summaryrefslogtreecommitdiff
path: root/include/uapi/linux
diff options
context:
space:
mode:
authorBreno Leitao <leitao@debian.org>2026-08-24 04:54:45 -0700
committerDavid Sterba <dsterba@suse.com>2026-10-05 14:55:38 +0200
commitacc5a94be748ad5a8a2c7316a6b69f29cd54dc21 (patch)
tree0fe1d5e0978a622d5994072e03bf4573221e7f1e /include/uapi/linux
parentfac54040fdfd9562ca64b0863fc479fefc07953c (diff)
downloadlinux-next-acc5a94be748ad5a8a2c7316a6b69f29cd54dc21.tar.gz
linux-next-acc5a94be748ad5a8a2c7316a6b69f29cd54dc21.zip
btrfs: skip extent tree lock in the shrinker for inodes without extent maps
find_first_inode_to_shrink() takes inode->extent_tree.lock in write mode on every inode it walks, only to find out whether that inode has any extent maps. Most inodes have none, so the lock is taken and dropped again without any work being done. Check whether the tree is empty before taking the lock. tree->root is only modified with the tree lock held for write, so the unlocked read is a harmless race: a false empty just defers the inode to a later scan, which already happens whenever the write_trylock() below fails, and a false non-empty falls through to the existing check under the lock. Across the Meta production fleet the extent map shrinker is ~0.35% of non-idle kernel CPU. Attributing callees to their caller, find_first_inode_to_shrink() is ~65% of that, and the write_trylock() it does is ~30% of the whole shrinker. Micro benchmark: a 6 GiB btrfs on a loop device, 100000 empty files kept open, plus 200 1 MiB files created last so they get the highest inode numbers and every scan has to walk all the empty ones first. Each round drops the page cache, re-reads the data files to recreate the extent maps, then triggers the shrinker with "echo 2 > /proc/sys/vm/drop_caches". 15 rounds per run on ARM64 (Neoverse V2), 8 CPUs, no lock debugging. Cost of find_first_inode_to_shrink() from the ftrace function profiler, in ns per inode walked, median of runs: base patched delta idle 46.4 40.1 -13.6% 4 concurrent readers 47.8 38.4 -19.7% A separate build with CONFIG_LOCK_STAT, same test, for the extent map tree rwlock. The shrinker is not the only user of that lock, every extent map insert and lookup takes it too, which is why the acquisition count drops by two thirds rather than to nothing: base patched delta write acquisitions 628016 228000 -63.7% hold time total (us) 47512 22717 -52.2% acq cacheline bounces 1574 1288 -18.2% Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'include/uapi/linux')
0 files changed, 0 insertions, 0 deletions