Skip to content

Commit a8349f7

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

File tree

5 files changed

+14
-45
lines changed

5 files changed

+14
-45
lines changed

fs/btrfs/disk-io.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2791,7 +2791,6 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
27912791
spin_lock_init(&fs_info->defrag_inodes_lock);
27922792
spin_lock_init(&fs_info->super_lock);
27932793
spin_lock_init(&fs_info->unused_bgs_lock);
2794-
spin_lock_init(&fs_info->treelog_bg_lock);
27952794
spin_lock_init(&fs_info->zone_active_bgs_lock);
27962795
rwlock_init(&fs_info->tree_mod_log_lock);
27972796
rwlock_init(&fs_info->global_root_lock);

fs/btrfs/extent-tree.c

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3809,22 +3809,6 @@ static int do_allocation_clustered(struct btrfs_block_group *block_group,
38093809
return find_free_extent_unclustered(block_group, ffe_ctl);
38103810
}
38113811

3812-
/*
3813-
* Tree-log block group locking
3814-
* ============================
3815-
*
3816-
* fs_info::treelog_bg_lock protects the fs_info::treelog_bg which
3817-
* indicates the starting address of a block group, which is reserved only
3818-
* for tree-log metadata.
3819-
*
3820-
* Lock nesting
3821-
* ============
3822-
*
3823-
* space_info::lock
3824-
* block_group::lock
3825-
* fs_info::treelog_bg_lock
3826-
*/
3827-
38283812
/*
38293813
* Simple allocator for sequential-only block group. It only allows sequential
38303814
* allocation. No need to play with trees. This function also reserves the
@@ -3841,23 +3825,17 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
38413825
u64 num_bytes = ffe_ctl->num_bytes;
38423826
u64 avail;
38433827
u64 bytenr = block_group->start;
3844-
u64 log_bytenr;
38453828
int ret = 0;
3846-
bool skip = false;
38473829

38483830
ASSERT(btrfs_is_zoned(block_group->fs_info));
38493831

38503832
/*
38513833
* Do not allow non-tree-log blocks in the dedicated tree-log block
38523834
* group, and vice versa.
38533835
*/
3854-
spin_lock(&fs_info->treelog_bg_lock);
3855-
log_bytenr = fs_info->treelog_bg;
3856-
if (log_bytenr && ((ffe_ctl->for_treelog && bytenr != log_bytenr) ||
3857-
(!ffe_ctl->for_treelog && bytenr == log_bytenr)))
3858-
skip = true;
3859-
spin_unlock(&fs_info->treelog_bg_lock);
3860-
if (skip)
3836+
if (READ_ONCE(fs_info->treelog_bg) &&
3837+
((ffe_ctl->for_treelog && bytenr != READ_ONCE(fs_info->treelog_bg)) ||
3838+
(!ffe_ctl->for_treelog && bytenr == READ_ONCE(fs_info->treelog_bg))))
38613839
return 1;
38623840

38633841
/*
@@ -3892,14 +3870,13 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
38923870

38933871
spin_lock(&space_info->lock);
38943872
spin_lock(&block_group->lock);
3895-
spin_lock(&fs_info->treelog_bg_lock);
38963873

38973874
if (ret)
38983875
goto out;
38993876

39003877
ASSERT(!ffe_ctl->for_treelog ||
3901-
block_group->start == fs_info->treelog_bg ||
3902-
fs_info->treelog_bg == 0);
3878+
block_group->start == READ_ONCE(fs_info->treelog_bg) ||
3879+
READ_ONCE(fs_info->treelog_bg) == 0);
39033880
ASSERT(!ffe_ctl->for_data_reloc ||
39043881
block_group->start == READ_ONCE(fs_info->data_reloc_bg) ||
39053882
READ_ONCE(fs_info->data_reloc_bg) == 0);
@@ -3915,7 +3892,7 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39153892
* Do not allow currently using block group to be tree-log dedicated
39163893
* block group.
39173894
*/
3918-
if (ffe_ctl->for_treelog && !fs_info->treelog_bg &&
3895+
if (ffe_ctl->for_treelog && READ_ONCE(fs_info->treelog_bg) == 0 &&
39193896
(block_group->used || block_group->reserved)) {
39203897
ret = 1;
39213898
goto out;
@@ -3946,8 +3923,8 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39463923
goto out;
39473924
}
39483925

3949-
if (ffe_ctl->for_treelog && !fs_info->treelog_bg)
3950-
fs_info->treelog_bg = block_group->start;
3926+
if (ffe_ctl->for_treelog && READ_ONCE(fs_info->treelog_bg) == 0)
3927+
WRITE_ONCE(fs_info->treelog_bg, block_group->start);
39513928

39523929
if (ffe_ctl->for_data_reloc) {
39533930
if (READ_ONCE(fs_info->data_reloc_bg) == 0)
@@ -3985,10 +3962,9 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
39853962

39863963
out:
39873964
if (ret && ffe_ctl->for_treelog)
3988-
fs_info->treelog_bg = 0;
3965+
WRITE_ONCE(fs_info->treelog_bg, 0);
39893966
if (ret && ffe_ctl->for_data_reloc)
39903967
WRITE_ONCE(fs_info->data_reloc_bg, 0);
3991-
spin_unlock(&fs_info->treelog_bg_lock);
39923968
spin_unlock(&block_group->lock);
39933969
spin_unlock(&space_info->lock);
39943970
return ret;
@@ -4290,11 +4266,8 @@ static int prepare_allocation_clustered(struct btrfs_fs_info *fs_info,
42904266
static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
42914267
struct find_free_extent_ctl *ffe_ctl)
42924268
{
4293-
if (ffe_ctl->for_treelog) {
4294-
spin_lock(&fs_info->treelog_bg_lock);
4295-
if (fs_info->treelog_bg)
4296-
ffe_ctl->hint_byte = fs_info->treelog_bg;
4297-
spin_unlock(&fs_info->treelog_bg_lock);
4269+
if (ffe_ctl->for_treelog && READ_ONCE(fs_info->treelog_bg)) {
4270+
ffe_ctl->hint_byte = READ_ONCE(fs_info->treelog_bg);
42984271
} else if (ffe_ctl->for_data_reloc &&
42994272
READ_ONCE(fs_info->data_reloc_bg)) {
43004273
ffe_ctl->hint_byte = READ_ONCE(fs_info->data_reloc_bg);

fs/btrfs/fs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,6 @@ struct btrfs_fs_info {
845845
u64 max_zone_append_size;
846846

847847
struct mutex zoned_meta_io_lock;
848-
spinlock_t treelog_bg_lock;
849848
u64 treelog_bg;
850849

851850
/* Start of the dedicated data relocation block group */

fs/btrfs/zoned.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1947,7 +1947,7 @@ static bool check_bg_is_active(struct btrfs_eb_write_context *ctx,
19471947
if (test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags))
19481948
return true;
19491949

1950-
if (fs_info->treelog_bg == block_group->start) {
1950+
if (READ_ONCE(fs_info->treelog_bg) == block_group->start) {
19511951
if (!btrfs_zone_activate(block_group)) {
19521952
int ret_fin = btrfs_zone_finish_one_bg(fs_info);
19531953

fs/btrfs/zoned.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,8 @@ static inline void btrfs_clear_treelog_bg(struct btrfs_block_group *bg)
387387
if (!btrfs_is_zoned(fs_info))
388388
return;
389389

390-
spin_lock(&fs_info->treelog_bg_lock);
391-
if (fs_info->treelog_bg == bg->start)
392-
fs_info->treelog_bg = 0;
393-
spin_unlock(&fs_info->treelog_bg_lock);
390+
if (READ_ONCE(fs_info->treelog_bg) == bg->start)
391+
WRITE_ONCE(fs_info->treelog_bg, 0);
394392
}
395393

396394
static inline void btrfs_zoned_data_reloc_lock(struct btrfs_inode *inode)

0 commit comments

Comments
 (0)