[GIT PULL 12/19 for v7.4] vfs kernfs
From: Christian Brauner
Date: Fri Oct 16 2026 - 06:29:15 EST
Hey Linus,
/* Summary */
This contains kernfs scalability work from Shakeel driven by what Meta
sees in their fleet. kernfs_rwsem is per kernfs root, so sysfs and
cgroupfs each have one for the whole machine, and every create, remove
and rename takes it for writing. rwsems don't let readers steal the lock
once a writer is queued, so one cgroup being created or a device being
renamed parks the entire incoming reader stream in uninterruptible
sleep. Daemons that poll cgroup files in a loop turn that into a convoy
and the two that hurt most, oomd and below, are the ones that are
supposed to relieve memory pressure and record what happened.
kernfs_dop_revalidate() took kernfs_rwsem for read once per path
component of every walk into a kernfs mount. Nothing it reads needs the
semaphore. kn->active is an atomic_t, kn->__parent and kn->name are rcu
pointers, kn->ns can be compared instead of dereferenced and the
directory revision is a plain counter. The callback runs under rcu now.
Readers walking cgroupfs and sysfs while another thread churns cgroups,
renames netdevs and plugs devices went from 48,593,360 read
acquisitions and 1,744,517 contentions to 1,280,280 and 429,846 on an
8-CPU VM and path walk throughput improved 35-53%. LOOKUP_RCU still
returns ECHILD because kernfs_iop_permission() forces every walk out of
rcu-walk anyway. That is left for later.
kernfs_fop_readdir() held the semaphore across dir_emit(). dir_emit()
copies to userspace and under memory pressure that fault goes to
reclaim with the lock every create, remove and rename needs held for
reading. Meta sees 120 second allocation stalls in filldir64() from
below and systemd-oomd stuck behind it. The lock is dropped around
dir_emit() now. Since the entry the listing stopped on can disappear in
that window and two entries can share a hash, readdir resumes on the
full (hash, ns, name) key and the fallback search lands after the
missing entry instead of repeating or skipping one. The repeat was a
pre-existing bug between two getdents(2) calls.
Three more lock holds are shortened. kernfs_notify_workfn() no longer
holds kernfs_rwsem across fsnotify() which allocates against the memcg
of the watching cgroup that is already under pressure. The open node is
allocated outside the hashed open file mutex, the most contended lock
in kernfs on their fleet with 2.19M waiters over 29 days and a 77ms
median hold. A new node is activated without dropping and retaking the
write lock, lock_stat says 1200 -> 830 write acquisitions for five
dummy netdevs, and kernfs_rename_ns() allocates the new name before and
frees the old one after the lock so a rename can't enter reclaim or
wait out a grace period with it held.
Three standalone fixes come with selftests. Same-parent renames take
kernfs_rename_lock too so kernfs_path_from_node() can't build a path
that never existed. Decoding a file handle takes the semaphore so a
decode racing rmdir() can't hash an inode after the removal's ilookup()
pass and lose IN_DELETE_SELF. And kernfs_create_link() reads the
target's uid and gid under kernfs_iattr_rwsem so a chown in between
can't give the link an owner the target never had. The kernfs selftests
grew from two xattr checks to coverage of dentry revalidation, rename,
namespace tagging, file handles and readdir under churn.
/* Testing */
No build failures or warnings were observed.
/* Conflicts */
Merge conflicts with mainline
=============================
No known conflicts.
Merge conflicts with other trees
================================
No known conflicts.
The following changes since commit cee9395acd8043be0644b25c34bfa86623f2b935:
Linux 7.3-rc1 (2026-08-30 13:34:40 -0700)
are available in the Git repository at:
git@xxxxxxxxxxxxxxxxxxx:pub/scm/linux/kernel/git/vfs/vfs tags/vfs-7.4-rc1.kernfs
for you to fetch changes up to 1c45110a23bd7fb4a1a7d5f5a1014c5b688844ae:
Merge patch series "kernfs: do less work under the kernfs_rwsem write lock" (2026-09-25 16:59:12 +0200)
----------------------------------------------------------------
vfs-7.4-rc1.kernfs
Please consider pulling these changes from the signed vfs-7.4-rc1.kernfs tag.
Thanks!
Christian
----------------------------------------------------------------
Christian Brauner (4):
Merge patch series "kernfs: remove kernfs_rwsem from dentry revalidation"
Merge patch series "kernfs: three standalone fixes"
Merge patch series "kernfs: don't hold kernfs_rwsem across dir_emit()"
Merge patch series "kernfs: do less work under the kernfs_rwsem write lock"
Shakeel Butt (18):
kernfs: Use VFS lookup context in d_revalidate()
kernfs: Prepare directory revisions for lockless reads
kernfs: Avoid namespace dereference in d_revalidate()
kernfs: Remove kernfs_rwsem from dentry revalidation
selftests: cover kernfs dentry revalidation
selftests: cover kernfs file handles and same-parent rename
kernfs: take kernfs_rename_lock for same-parent renames too
kernfs: don't lose IN_DELETE_SELF when decoding a file handle
kernfs: fix up the unlocked attribute reads on the creation paths
kernfs: allocate the open node outside the open file mutex
kernfs: don't hold kernfs_rwsem across notification delivery
kernfs: don't repeat or skip an entry when readdir resumes
kernfs: resume readdir on the full entry key
kernfs: don't hold kernfs_rwsem across dir_emit()
selftests: cover readdir resuming at a removed entry
kernfs: activate a new node without dropping kernfs_rwsem
kernfs: allocate the new name outside kernfs_rwsem
kernfs: free the old name outside kernfs_rwsem
MAINTAINERS | 1 +
fs/kernfs/dir.c | 225 ++--
fs/kernfs/file.c | 47 +-
fs/kernfs/kernfs-internal.h | 18 +-
fs/kernfs/mount.c | 32 +-
fs/kernfs/symlink.c | 17 +-
tools/testing/selftests/filesystems/config | 8 +
tools/testing/selftests/filesystems/kernfs_test.c | 1187 ++++++++++++++++++++-
8 files changed, 1414 insertions(+), 121 deletions(-)
create mode 100644 tools/testing/selftests/filesystems/config