summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaohiro Aota <naohiro.aota@wdc.com>2023-12-18 19:02:29 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-02-01 03:19:10 +0300
commit46ac4e1f9a9ddfbc1dee75d3880966084b7723bd (patch)
tree5fd656daee9e4565f67683e1aa68755e1a2f7c7d
parentb1e30e2ff6eb1b200220036b22066f762ceceea2 (diff)
downloadlinux-46ac4e1f9a9ddfbc1dee75d3880966084b7723bd.tar.xz
btrfs: zoned: optimize hint byte for zoned allocator
[ Upstream commit 02444f2ac26eae6385a65fcd66915084d15dffba ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--fs/btrfs/extent-tree.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 69abb6eb81df..b89b558b1592 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4152,6 +4152,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;