[External] Re: [PATCH 0/7] fs: preserve superblock inode walk positions across lock drops
Julian Sun
sunjunchao at bytedance.com
Wed Sep 9 13:08:23 UTC 2026
On Wed, Sep 9, 2026 at 8:49 PM Jan Kara <jack at suse.cz> wrote:
>
> On Wed 09-09-26 17:01:05, Julian Sun wrote:
> > [Motivation]
> >
> > We observed hung tasks in production during disk hotplug operations. A
> > kernel thread spends a long time in evict_inodes() while holding s_umount,
> > blocking other users of that lock and causing further stalls.
> >
> > The problem is that evict_inodes() restarts its walk from the head of
> > sb->s_inodes every time it reschedules. When a large number of referenced
> > inodes remain near the head, each restart scans those inodes again without
> > making progress through that part of the list. The repeated scans can
> > delay eviction long enough to trigger hung-task reports. This is the same
> > problem that [1] attempted to address.
>
> Thanks fro the patch! What's really unexpected is that there are many
> inodes with incremented refcount at the time when evict_inodes() is called.
> Did you have a look who's holding those references? Or is evict_inodes()
> called through the fs_bdev_mark_dead() call (as you mention "disk hotplug
> operations")? There the filesystem is in fact in use so what you describe
> makes some sense.
Yes, the filesystem was still in use, and the disk was unplugged
directly without being unmounted. As a result, `fs_bdev_mark_dead()`
holds the `s_umount` lock and performs a large number of redundant
traversals, which takes a significant amount of time.
>
> Honza
>
> > [Approach]
> >
> > This series introduces sb_for_each_inodes() for two purposes:
> >
> > 1. Consolidate open-coded s_inodes walks behind a common entry point.
> > 2. Retain each walk's position across drops of s_inode_list_lock.
> >
> > The iterator mechanism follows the approach used by cgroup task iteration,
> > such as css_task_iter_next(). Active iterators are registered on a separate
> > list, sb->s_inodes_iters. Before removing an inode from s_inodes, the
> > removal path advances any iterator whose next position points to that
> > inode. These updates are protected by s_inode_list_lock, so a walker can
> > drop the lock and later resume from its saved position.
> >
> > Existing walkers, such as drop_pagecache_sb() and add_dquot_ref(), already
> > contain their own position-preserving logic: they carry an inode reference
> > across iterations so that they can resume after dropping the list lock.
> > Moving that responsibility into sb_for_each_inodes() simplifies these
> > callers and lets their callbacks focus on the per-inode work.
> >
> > Patch 1 removes trailing whitespace from include/linux/fs.h.
> > Patch 2 introduces sb_for_each_inodes().
> > The remaining patches convert existing walks to the new interface.
> > remove_dquot_ref() and nr_blockdev_pages() are left unchanged: their
> > walks are simple and do not require the inode->i_lock locking imposed
> > by the callback interface. Converting them would add an unnecessary
> > lock/unlock overhead for every inode.
> >
> > [Testing]
> >
> > I tested this series with approximately 20 hours of xfstests case
> > execution, repeatedly running the auto group on ext4 and XFS, no new
> > issues were observed. And with this patch applied, the hung task that
> > previously occurred on every run no longer occurs.
> >
> > [1] https://lore.kernel.org/all/20241118114508.1405494-1-yebin@huaweicloud.com/
> >
> > Julian Sun (7):
> > fs: remove trailing whitespace from include/linux/fs.h
> > fs: introduce sb_for_each_inodes().
> > block: use sb_for_each_inodes() in sync_bdevs()
> > fs: use sb_for_each_inodes() API.
> > gfs2: use sb_for_each_inodes() for cooperative eviction
> > quota: use sb_for_each_inodes() in add_dquot_ref()
> > landlock: use sb_for_each_inodes() when detaching a superblock
> >
> > block/bdev.c | 85 +++++++++----------
> > fs/drop_caches.c | 44 +++++-----
> > fs/gfs2/ops_fstype.c | 38 ++++-----
> > fs/inode.c | 142 +++++++++++++++++++++++--------
> > fs/quota/dquot.c | 72 ++++++----------
> > fs/super.c | 1 +
> > include/linux/fs.h | 29 +++++--
> > include/linux/fs/super_types.h | 3 +-
> > security/landlock/fs.c | 150 +++++++++++++--------------------
> > 9 files changed, 295 insertions(+), 269 deletions(-)
> >
> > --
> > 2.39.5
> >
> --
> Jan Kara <jack at suse.com>
> SUSE Labs, CR
Thanks,
--
Julian Sun <sunjunchao at bytedance.com>
More information about the Linux-security-module-archive
mailing list