diff mbox series

[2/5] btrfs: allow block group background reclaim for !zoned fs'es

Message ID ef7463193e228bbb348bf8a8d587aa8b95bebf22.1647878642.git.johannes.thumshirn@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: rework background block group relocation | expand

Commit Message

Johannes Thumshirn March 21, 2022, 4:14 p.m. UTC
From: Josef Bacik <josef@toxicpanda.com>

We have found this feature invaluable at Facebook due to how our
workload interacts with the allocator.  We have been using this in
production for months with only a single problem that has already been
fixed.  This will allow us to set a threshold for block groups to be
automatically relocated even if we don't have zoned devices.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/block-group.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

Comments

Josef Bacik March 22, 2022, 5:38 p.m. UTC | #1
On Mon, Mar 21, 2022 at 09:14:11AM -0700, Johannes Thumshirn wrote:
> From: Josef Bacik <josef@toxicpanda.com>
> 
> We have found this feature invaluable at Facebook due to how our
> workload interacts with the allocator.  We have been using this in
> production for months with only a single problem that has already been
> fixed.  This will allow us to set a threshold for block groups to be
> automatically relocated even if we don't have zoned devices.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/block-group.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
> index 59f18a10fd5f..628741ecb97b 100644
> --- a/fs/btrfs/block-group.c
> +++ b/fs/btrfs/block-group.c
> @@ -3208,6 +3208,31 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans)
>  	return ret;
>  }
>  
> +static inline bool should_reclaim_block_group(struct btrfs_block_group *block_group,
> +					      u64 bytes_freed)
> +{
> +	const struct btrfs_space_info *space_info = block_group->space_info;
> +	const int reclaim_thresh = READ_ONCE(space_info->bg_reclaim_threshold);
> +	const u64 new_val = block_group->used;
> +	const u64 old_val = new_val + bytes_freed;
> +	u64 thresh;
> +

Actually do we want to do a

if (btrfs_zoned())
	return false;

here and leave the auto reclaim zoned behavior the way it is?  Or do you want to
delete your stuff and rely on this as the way that we setup zoned block groups
for relocation?  If we use this then you could make the
fs_info->bg_reclaim_threshold also apply here.  Thanks,

Josef
Johannes Thumshirn March 22, 2022, 5:40 p.m. UTC | #2
On 22/03/2022 18:38, Josef Bacik wrote:
>> +static inline bool should_reclaim_block_group(struct btrfs_block_group *block_group,
>> +					      u64 bytes_freed)
>> +{
>> +	const struct btrfs_space_info *space_info = block_group->space_info;
>> +	const int reclaim_thresh = READ_ONCE(space_info->bg_reclaim_threshold);
>> +	const u64 new_val = block_group->used;
>> +	const u64 old_val = new_val + bytes_freed;
>> +	u64 thresh;
>> +
> 
> Actually do we want to do a
> 
> if (btrfs_zoned())
> 	return false;
> 
> here and leave the auto reclaim zoned behavior the way it is?  Or do you want to
> delete your stuff and rely on this as the way that we setup zoned block groups
> for relocation?  If we use this then you could make the
> fs_info->bg_reclaim_threshold also apply here.  Thanks,
> 
>

I actually like the per-space info knob for the individual block groups and then
the global one to kick in reclaim.
diff mbox series

Patch

diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 59f18a10fd5f..628741ecb97b 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -3208,6 +3208,31 @@  int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans)
 	return ret;
 }
 
+static inline bool should_reclaim_block_group(struct btrfs_block_group *block_group,
+					      u64 bytes_freed)
+{
+	const struct btrfs_space_info *space_info = block_group->space_info;
+	const int reclaim_thresh = READ_ONCE(space_info->bg_reclaim_threshold);
+	const u64 new_val = block_group->used;
+	const u64 old_val = new_val + bytes_freed;
+	u64 thresh;
+
+	if (reclaim_thresh == 0)
+		return false;
+
+	thresh = div_factor_fine(block_group->length, reclaim_thresh);
+
+	/*
+	 * If we were below the threshold before don't reclaim, we are likely a
+	 * brand new block group and we don't want to relocate new block groups.
+	 */
+	if (old_val < thresh)
+		return false;
+	if (new_val >= thresh)
+		return false;
+	return true;
+}
+
 int btrfs_update_block_group(struct btrfs_trans_handle *trans,
 			     u64 bytenr, u64 num_bytes, bool alloc)
 {
@@ -3230,6 +3255,8 @@  int btrfs_update_block_group(struct btrfs_trans_handle *trans,
 	spin_unlock(&info->delalloc_root_lock);
 
 	while (total) {
+		bool reclaim;
+
 		cache = btrfs_lookup_block_group(info, bytenr);
 		if (!cache) {
 			ret = -ENOENT;
@@ -3275,6 +3302,8 @@  int btrfs_update_block_group(struct btrfs_trans_handle *trans,
 					cache->space_info, num_bytes);
 			cache->space_info->bytes_used -= num_bytes;
 			cache->space_info->disk_used -= num_bytes * factor;
+
+			reclaim = should_reclaim_block_group(cache, num_bytes);
 			spin_unlock(&cache->lock);
 			spin_unlock(&cache->space_info->lock);
 
@@ -3301,6 +3330,8 @@  int btrfs_update_block_group(struct btrfs_trans_handle *trans,
 		if (!alloc && old_val == 0) {
 			if (!btrfs_test_opt(info, DISCARD_ASYNC))
 				btrfs_mark_bg_unused(cache);
+		} else if (!alloc && reclaim) {
+			btrfs_mark_bg_to_reclaim(cache);
 		}
 
 		btrfs_put_block_group(cache);