Skip to content

Commit 8977121

Browse files
morbidrsakdave
authored andcommitted
btrfs: zoned: get rid of relocation_bg_lock
Lockstat analysis of benchmark workloads shows a very high contention on relocation_bg_lock. But the lock only protects a single field in 'struct btrfs_fs_info', namely 'u64 data_reloc_bg'. Use READ_ONCE()/WRITE_ONCE() to access 'btrfs_fs_info::data_reloc_bg'. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 3c6e359 commit 8977121

File tree

4 files changed

+17
-34
lines changed

4 files changed

+17
-34
lines changed

fs/btrfs/disk-io.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2793,7 +2793,6 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
27932793
spin_lock_init(&fs_info->unused_bgs_lock);
27942794
spin_lock_init(&fs_info->treelog_bg_lock);
27952795
spin_lock_init(&fs_info->zone_active_bgs_lock);
2796-
spin_lock_init(&fs_info->relocation_bg_lock);
27972796
rwlock_init(&fs_info->tree_mod_log_lock);
27982797
rwlock_init(&fs_info->global_root_lock);
27992798
mutex_init(&fs_info->unused_bg_unpin_mutex);

fs/btrfs/extent-tree.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3842,7 +3842,6 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
38423842
u64 avail;
38433843
u64 bytenr = block_group->start;
38443844
u64 log_bytenr;
3845-
u64 data_reloc_bytenr;
38463845
int ret = 0;
38473846
bool skip = false;
38483847

@@ -3865,14 +3864,9 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
38653864
* Do not allow non-relocation blocks in the dedicated relocation block
38663865
* group, and vice versa.
38673866
*/
3868-
spin_lock(&fs_info->relocation_bg_lock);
3869-
data_reloc_bytenr = fs_info->data_reloc_bg;
3870-
if (data_reloc_bytenr &&
3871-
((ffe_ctl->for_data_reloc && bytenr != data_reloc_bytenr) ||
3872-
(!ffe_ctl->for_data_reloc && bytenr == data_reloc_bytenr)))
3873-
skip = true;
3874-
spin_unlock(&fs_info->relocation_bg_lock);
3875-
if (skip)
3867+
if (READ_ONCE(fs_info->data_reloc_bg) &&
3868+
((ffe_ctl->for_data_reloc && bytenr != READ_ONCE(fs_info->data_reloc_bg)) ||
3869+
(!ffe_ctl->for_data_reloc && bytenr == READ_ONCE(fs_info->data_reloc_bg))))
38763870
return 1;
38773871

38783872
/* Check RO and no space case before trying to activate it */
@@ -3899,7 +3893,6 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
38993893
spin_lock(&space_info->lock);
39003894
spin_lock(&block_group->lock);
39013895
spin_lock(&fs_info->treelog_bg_lock);
3902-
spin_lock(&fs_info->relocation_bg_lock);
39033896

39043897
if (ret)
39053898
goto out;
@@ -3908,8 +3901,8 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39083901
block_group->start == fs_info->treelog_bg ||
39093902
fs_info->treelog_bg == 0);
39103903
ASSERT(!ffe_ctl->for_data_reloc ||
3911-
block_group->start == fs_info->data_reloc_bg ||
3912-
fs_info->data_reloc_bg == 0);
3904+
block_group->start == READ_ONCE(fs_info->data_reloc_bg) ||
3905+
READ_ONCE(fs_info->data_reloc_bg) == 0);
39133906

39143907
if (block_group->ro ||
39153908
(!ffe_ctl->for_data_reloc &&
@@ -3932,7 +3925,7 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39323925
* Do not allow currently used block group to be the data relocation
39333926
* dedicated block group.
39343927
*/
3935-
if (ffe_ctl->for_data_reloc && !fs_info->data_reloc_bg &&
3928+
if (ffe_ctl->for_data_reloc && READ_ONCE(fs_info->data_reloc_bg) == 0 &&
39363929
(block_group->used || block_group->reserved)) {
39373930
ret = 1;
39383931
goto out;
@@ -3957,8 +3950,8 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39573950
fs_info->treelog_bg = block_group->start;
39583951

39593952
if (ffe_ctl->for_data_reloc) {
3960-
if (!fs_info->data_reloc_bg)
3961-
fs_info->data_reloc_bg = block_group->start;
3953+
if (READ_ONCE(fs_info->data_reloc_bg) == 0)
3954+
WRITE_ONCE(fs_info->data_reloc_bg, block_group->start);
39623955
/*
39633956
* Do not allow allocations from this block group, unless it is
39643957
* for data relocation. Compared to increasing the ->ro, setting
@@ -3994,8 +3987,7 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39943987
if (ret && ffe_ctl->for_treelog)
39953988
fs_info->treelog_bg = 0;
39963989
if (ret && ffe_ctl->for_data_reloc)
3997-
fs_info->data_reloc_bg = 0;
3998-
spin_unlock(&fs_info->relocation_bg_lock);
3990+
WRITE_ONCE(fs_info->data_reloc_bg, 0);
39993991
spin_unlock(&fs_info->treelog_bg_lock);
40003992
spin_unlock(&block_group->lock);
40013993
spin_unlock(&space_info->lock);
@@ -4303,11 +4295,9 @@ static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
43034295
if (fs_info->treelog_bg)
43044296
ffe_ctl->hint_byte = fs_info->treelog_bg;
43054297
spin_unlock(&fs_info->treelog_bg_lock);
4306-
} else if (ffe_ctl->for_data_reloc) {
4307-
spin_lock(&fs_info->relocation_bg_lock);
4308-
if (fs_info->data_reloc_bg)
4309-
ffe_ctl->hint_byte = fs_info->data_reloc_bg;
4310-
spin_unlock(&fs_info->relocation_bg_lock);
4298+
} else if (ffe_ctl->for_data_reloc &&
4299+
READ_ONCE(fs_info->data_reloc_bg)) {
4300+
ffe_ctl->hint_byte = READ_ONCE(fs_info->data_reloc_bg);
43114301
} else if (ffe_ctl->flags & BTRFS_BLOCK_GROUP_DATA) {
43124302
struct btrfs_block_group *block_group;
43134303

fs/btrfs/fs.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -848,11 +848,7 @@ struct btrfs_fs_info {
848848
spinlock_t treelog_bg_lock;
849849
u64 treelog_bg;
850850

851-
/*
852-
* Start of the dedicated data relocation block group, protected by
853-
* relocation_bg_lock.
854-
*/
855-
spinlock_t relocation_bg_lock;
851+
/* Start of the dedicated data relocation block group */
856852
u64 data_reloc_bg;
857853
struct mutex zoned_data_reloc_io_lock;
858854

fs/btrfs/zoned.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,10 +2495,8 @@ void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg)
24952495
{
24962496
struct btrfs_fs_info *fs_info = bg->fs_info;
24972497

2498-
spin_lock(&fs_info->relocation_bg_lock);
2499-
if (fs_info->data_reloc_bg == bg->start)
2500-
fs_info->data_reloc_bg = 0;
2501-
spin_unlock(&fs_info->relocation_bg_lock);
2498+
if (READ_ONCE(fs_info->data_reloc_bg) == bg->start)
2499+
WRITE_ONCE(fs_info->data_reloc_bg, 0);
25022500
}
25032501

25042502
void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info)
@@ -2517,7 +2515,7 @@ void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info)
25172515
if (!btrfs_is_zoned(fs_info))
25182516
return;
25192517

2520-
if (fs_info->data_reloc_bg)
2518+
if (READ_ONCE(fs_info->data_reloc_bg))
25212519
return;
25222520

25232521
if (sb_rdonly(fs_info->sb))
@@ -2538,7 +2536,7 @@ void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info)
25382536
continue;
25392537
}
25402538

2541-
fs_info->data_reloc_bg = bg->start;
2539+
WRITE_ONCE(fs_info->data_reloc_bg, bg->start);
25422540
set_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &bg->runtime_flags);
25432541
btrfs_zone_activate(bg);
25442542

0 commit comments

Comments
 (0)