btrfs: annotate block group access with data_race() when sorting for reclaim
authorFilipe Manana <fdmanana@suse.com>
Mon, 8 Sep 2025 11:51:11 +0000 (12:51 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 15 Sep 2025 03:25:43 +0000 (05:25 +0200)
When sorting the block group list for reclaim we are using a block group's
used bytes counter without taking the block group's spinlock, so we can
race with a concurrent task updating it (at btrfs_update_block_group()),
which makes tools like KCSAN unhappy and report a race.

Since the sorting is not strictly needed from a functional perspective
and such races should rarely cause any ordering changes (only load/store
tearing could cause them), not to mention that after the sorting the
ordering may no longer be accurate due to concurrent allocations and
deallocations of extents in a block group, annotate the accesses to the
used counter with data_race() to silence KCSAN and similar tools.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c

index 9bf282d2453c02ddfe5eed5526dc79f3775d1c0c..499a9edf0ca315b93335a0e4cf0f999382c8df8e 100644 (file)
@@ -1795,7 +1795,14 @@ static int reclaim_bgs_cmp(void *unused, const struct list_head *a,
        bg1 = list_entry(a, struct btrfs_block_group, bg_list);
        bg2 = list_entry(b, struct btrfs_block_group, bg_list);
 
-       return bg1->used > bg2->used;
+       /*
+        * Some other task may be updating the ->used field concurrently, but it
+        * is not serious if we get a stale value or load/store tearing issues,
+        * as sorting the list of block groups to reclaim is not critical and an
+        * occasional imperfect order is ok. So silence KCSAN and avoid the
+        * overhead of locking or any other synchronization.
+        */
+       return data_race(bg1->used > bg2->used);
 }
 
 static inline bool btrfs_should_reclaim(const struct btrfs_fs_info *fs_info)