@@ -1871,7 +1871,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
}
next:
- if (ret)
+ if (ret && !READ_ONCE(space_info->periodic_reclaim))
btrfs_mark_bg_to_reclaim(bg);
btrfs_put_block_group(bg);
@@ -3580,6 +3580,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
space_info->bytes_used -= num_bytes;
space_info->disk_used -= num_bytes * factor;
+ space_info->periodic_reclaim_ready = true;
reclaim = should_reclaim_block_group(cache, num_bytes);
spin_unlock(&cache->lock);
@@ -1968,6 +1968,12 @@ static int do_reclaim_sweep(struct btrfs_fs_info *fs_info,
bool urgent;
spin_lock(&space_info->lock);
+ if (space_info->periodic_reclaim_ready) {
+ space_info->periodic_reclaim_ready = false;
+ } else {
+ spin_unlock(&space_info->lock);
+ return 0;
+ }
urgent = is_reclaim_urgent(space_info);
thresh_pct = btrfs_calc_reclaim_threshold(space_info);
spin_unlock(&space_info->lock);
@@ -175,6 +175,12 @@ struct btrfs_space_info {
* threshold in the cleaner thread.
*/
bool periodic_reclaim;
+
+ /*
+ * Periodic reclaim should be a no-op if a space_info hasn't
+ * freed any space since the last time we tried.
+ */
+ bool periodic_reclaim_ready;
};
struct reserve_ticket {
Periodic reclaim runs the risk of getting stuck in a state where it keeps reclaiming the same block group over and over. This can happen if 1. reclaiming that block_group fails 2. reclaiming that block_group fails to move any extents into existing block_groups and just allocates a fresh chunk and moves everything. Currently, 1. is a very tight loop inside the reclaim worker. That is critical for edge triggered reclaim or else we risk forgetting about a reclaimable group. On the other hand, with level triggered reclaim we can break out of that loop and get it later. With that fixed, 2. applies to both failures and "successes" with no progress. If we have done a periodic reclaim on a space_info and nothing has changed in that space_info, there is not much point to trying again, so don't, until some space gets free. Signed-off-by: Boris Burkov <boris@bur.io> --- fs/btrfs/block-group.c | 3 ++- fs/btrfs/space-info.c | 6 ++++++ fs/btrfs/space-info.h | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-)