• Filipe Manana's avatar
    btrfs: only run the extent map shrinker from kswapd tasks · ae1e766f
    Filipe Manana authored
    Currently the extent map shrinker can be run by any task when attempting
    to allocate memory and there's enough memory pressure to trigger it.
    
    To avoid too much latency we stop iterating over extent maps and removing
    them once the task needs to reschedule. This logic was introduced in commit
    b3ebb9b7 ("btrfs: stop extent map shrinker if reschedule is needed").
    
    While that solved high latency problems for some use cases, it's still
    not enough because with a too high number of tasks entering the extent map
    shrinker code, either due to memory allocations or because they are a
    kswapd task, we end up having a very high level of contention on some
    spin locks, namely:
    
    1) The fs_info->fs_roots_radix_lock spin lock, which we need to find
       roots to iterate over their inodes;
    
    2) The spin lock of the xarray used to track open inodes for a root
       (struct btrfs_root::inodes) - on 6.10 kernels and below, it used to
       be a red black tree and the spin lock was root->inode_lock;
    
    3) The fs_info->delayed_iput_lock spin lock since the shrinker adds
       delayed iputs (calls btrfs_add_delayed_iput()).
    
    Instead of allowing the extent map shrinker to be run by any task, make
    it run only by kswapd tasks. This still solves the problem of running
    into OOM situations due to an unbounded extent map creation, which is
    simple to trigger by direct IO writes, as described in the changelog
    of commit 956a17d9 ("btrfs: add a shrinker for extent maps"), and
    by a similar case when doing buffered IO on files with a very large
    number of holes (keeping the file open and creating many holes, whose
    extent maps are only released when the file is closed).
    Reported-by: default avatarkzd <kzd@56709.net>
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=219121Reported-by: default avatarOctavia Togami <octavia.togami@gmail.com>
    Link: https://lore.kernel.org/linux-btrfs/CAHPNGSSt-a4ZZWrtJdVyYnJFscFjP9S7rMcvEMaNSpR556DdLA@mail.gmail.com/
    Fixes: 956a17d9 ("btrfs: add a shrinker for extent maps")
    CC: stable@vger.kernel.org # 6.10+
    Tested-by: default avatarkzd <kzd@56709.net>
    Tested-by: default avatarOctavia Togami <octavia.togami@gmail.com>
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    ae1e766f
extent_map.c 37.4 KB