| #
0ddc8871 |
| 20-Oct-2026 |
Linus Torvalds <torvalds@linux-foundation.org> |
Merge tag 'vfs-7.4-rc1.kernfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull kernfs updates from Christian Brauner: "This contains kernfs scalability work from Shakeel driven by wha
Merge tag 'vfs-7.4-rc1.kernfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull kernfs updates from Christian Brauner: "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"
* tag 'vfs-7.4-rc1.kernfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: kernfs: free the old name outside kernfs_rwsem kernfs: allocate the new name outside kernfs_rwsem kernfs: activate a new node without dropping kernfs_rwsem selftests: cover readdir resuming at a removed entry kernfs: don't hold kernfs_rwsem across dir_emit() kernfs: resume readdir on the full entry key kernfs: don't repeat or skip an entry when readdir resumes kernfs: don't hold kernfs_rwsem across notification delivery kernfs: allocate the open node outside the open file mutex kernfs: fix up the unlocked attribute reads on the creation paths kernfs: don't lose IN_DELETE_SELF when decoding a file handle kernfs: take kernfs_rename_lock for same-parent renames too selftests: cover kernfs file handles and same-parent rename selftests: cover kernfs dentry revalidation kernfs: Remove kernfs_rwsem from dentry revalidation kernfs: Avoid namespace dereference in d_revalidate() kernfs: Prepare directory revisions for lockless reads kernfs: Use VFS lookup context in d_revalidate()
show more ...
|
| #
7f24d0f6 |
| 10-Sep-2026 |
Christian Brauner <brauner@kernel.org> |
Merge patch series "kernfs: three standalone fixes"
Shakeel Butt <shakeel.butt@linux.dev> says:
Three independent kernfs fixes, plus selftest coverage for the paths they touch. The fixes do not de
Merge patch series "kernfs: three standalone fixes"
Shakeel Butt <shakeel.butt@linux.dev> says:
Three independent kernfs fixes, plus selftest coverage for the paths they touch. The fixes do not depend on each other.
Patch 1 adds tests for decoding a file handle and for a rename that keeps the same parent. Patches 2-4:
- kernfs_rename_ns() takes kernfs_rename_lock only when the parent changes, so two same-parent renames inside one kernfs_path_from_node() walk can build a path that never existed. sysfs_warn_dup() is the only caller that can see it.
- __kernfs_fh_to_dentry() creates inodes with no lock, so a decode racing rmdir() can hash an inode after the removal's ilookup() pass. The inode keeps i_nlink 1, so no IN_DELETE_SELF is sent.
- kernfs_create_link() reads the target's uid and gid unlocked, so a chown in between gives the link an owner the target never had.
Patch 1 applies on top of the patch [1] ("selftests: cover kernfs dentry revalidation") with vfs-7.4.kernfs branch in vfs tree as base.
[1] http://lore.kernel.org/20260902014050.499002-1-shakeel.butt@linux.dev
* patches from https://patch.msgid.link/20260905191613.3143937-1-shakeel.butt@linux.dev: kernfs: fix up the unlocked attribute reads on the creation paths kernfs: don't lose IN_DELETE_SELF when decoding a file handle kernfs: take kernfs_rename_lock for same-parent renames too selftests: cover kernfs file handles and same-parent rename
Link: https://patch.msgid.link/20260905191613.3143937-1-shakeel.butt@linux.dev Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
show more ...
|
| #
60da22a3 |
| 05-Sep-2026 |
Shakeel Butt <shakeel.butt@linux.dev> |
selftests: cover kernfs file handles and same-parent rename
The kernfs tests only reach kernfs through lookup and readdir. Two paths are not covered: file handles, which find a node without a looku
selftests: cover kernfs file handles and same-parent rename
The kernfs tests only reach kernfs through lookup and readdir. Two paths are not covered: file handles, which find a node without a lookup through its parent, and rename of a node that keeps its parent.
Add three tests:
- decode a file handle, live and after the node is gone; - decode while the node is being removed; - look up a name while an interface is renamed, which renames its /sys/class/net entry with the parent unchanged.
Two small fixes while here. ns_tag_isolates_class_net now counts only symlinks, because bonding adds a bonding_masters attribute that is not a device. A failing mkdtemp() now skips instead of aborting.
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev> Link: https://patch.msgid.link/20260905191613.3143937-2-shakeel.butt@linux.dev Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
show more ...
|
| #
c38b381d |
| 02-Sep-2026 |
Shakeel Butt <shakeel.butt@linux.dev> |
selftests: cover kernfs dentry revalidation
kernfs_test only checked two xattr calls. It did not touch the part of kernfs that userspace hits most: the dentry cache.
The kernel adds and removes ker
selftests: cover kernfs dentry revalidation
kernfs_test only checked two xattr calls. It did not touch the part of kernfs that userspace hits most: the dentry cache.
The kernel adds and removes kernfs nodes on its own, with no VFS call behind it, and removal cannot always unhash the dentries that are already cached. So ->d_revalidate() is what keeps the cache honest, let's add tests for it.
Add tests that make the kernel change kernfs directly, instead of going through create and unlink:
- writing cgroup.subtree_control makes the kernel add and remove files in every child cgroup. That checks two things: a cached negative dentry is dropped once the file appears, and a cached positive one is dropped once the file goes away. - renaming a network interface renames the sysfs node under a dentry that is already cached. - sysfs mounted in a new network namespace must list that namespace's interfaces and not the parent's, which covers the KERNFS_NS tagging code. - many lookups running against concurrent mkdir and rmdir. A lookup may only succeed or fail with an errno that means "it is gone". - open across removal, readdir returning each entry once, and a telldir()/seekdir() round trip, which uses the name hash cookie in kernfs_dir_pos().
Test the other direction too: walking dentries that are already cached must not drop them. That is not just a slowdown. d_invalidate() calls detach_mounts(), so a dentry dropped by mistake also unmounts whatever is mounted under that directory.
Both filesystems are needed. cgroup2 has no ->rename and is not namespace tagged. sysfs cannot be mounted with a set of children we control. The config fragment stops a kernel built with kselftest-merge from passing while it runs almost nothing.
To confirm the tests really catch a broken backstop, kernfs_dir_changed() was stubbed to return false. 8 of the 11 tests then failed.
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev> Link: https://patch.msgid.link/20260902014050.499002-1-shakeel.butt@linux.dev Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
show more ...
|