]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: zoned: optimize hint byte for zoned allocator
authorNaohiro Aota <naohiro.aota@wdc.com>
Mon, 18 Dec 2023 16:02:29 +0000 (01:02 +0900)
committerDavid Sterba <dsterba@suse.com>
Fri, 12 Jan 2024 00:59:43 +0000 (01:59 +0100)
Writing sequentially to a huge file on btrfs on a SMR HDD revealed a
decline of the performance (220 MiB/s to 30 MiB/s after 500 minutes).

The performance goes down because of increased latency of the extent
allocation, which is induced by a traversing of a lot of full block groups.

So, this patch optimizes the ffe_ctl->hint_byte by choosing a block group
with sufficient size from the active block group list, which does not
contain full block groups.

After applying the patch, the performance is maintained well.

Fixes: 2eda57089ea3 ("btrfs: zoned: implement sequential extent allocation")
CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-tree.c

index d260b970bec7754e952e21a4ff8ad811ae35985a..6d680031211a1c6e97c937fe9add708a7bf8bb66 100644 (file)
@@ -4311,6 +4311,24 @@ static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
                if (fs_info->data_reloc_bg)
                        ffe_ctl->hint_byte = fs_info->data_reloc_bg;
                spin_unlock(&fs_info->relocation_bg_lock);
+       } else if (ffe_ctl->flags & BTRFS_BLOCK_GROUP_DATA) {
+               struct btrfs_block_group *block_group;
+
+               spin_lock(&fs_info->zone_active_bgs_lock);
+               list_for_each_entry(block_group, &fs_info->zone_active_bgs, active_bg_list) {
+                       /*
+                        * No lock is OK here because avail is monotinically
+                        * decreasing, and this is just a hint.
+                        */
+                       u64 avail = block_group->zone_capacity - block_group->alloc_offset;
+
+                       if (block_group_bits(block_group, ffe_ctl->flags) &&
+                           avail >= ffe_ctl->num_bytes) {
+                               ffe_ctl->hint_byte = block_group->start;
+                               break;
+                       }
+               }
+               spin_unlock(&fs_info->zone_active_bgs_lock);
        }
 
        return 0;