
This is a backport of a collection of 12 upstream patches. The main one being the switch to use a rwsem instead. The next important one being the switch of the rwsem to be a per filesystem lock instead of global. See the individual patches for details. They did not require much work or wiggling to get them applied. They all come from Linus' tree and are easily located. As such I have not modified their individual headers with upstream commit ids. Verification: - two scripts, the concept behind them supplied by Vefa Bicakci. The first one causes a lot of concurrent contention in sysfs. The second script highlights how well systemd is also contending. Run Script1 followed by Script2 Without this change, Script2 has timeouts and fails. Script1: for i in `seq 20`; do (while :; do find /sys/fs/cgroup/ -type f -readable -print0 \ 2>/dev/null | xargs -0 -n 20 -r cat >&/dev/null ; done) & done for i in `seq 10`; do (while :; do systemd-run --scope -q sleep 0.5 >/dev/null; done) & done Script2: while true; do date -Is /usr/bin/time -f %e systemctl enable -q lighttpd.service || break /usr/bin/time -f %e systemctl disable -q lighttpd.service || break /usr/bin/time -f %e systemctl restart -q lighttpd.service || break sleep 0.5 || break done - also soak testing to ensure that these patches don't introduce issues Partial-Bug: 2016028 Signed-off-by: Jim Somerville <jim.somerville@windriver.com> Change-Id: I6ad64cd7c90f756c6eb904065febfeb516e73009
63 lines
2.3 KiB
Diff
63 lines
2.3 KiB
Diff
From 1ec09b985b429c06bd9d58af05c0d8e1bcf24edc Mon Sep 17 00:00:00 2001
|
|
From: Ian Kent <raven@themaw.net>
|
|
Date: Mon, 4 Oct 2021 09:03:53 +0800
|
|
Subject: [PATCH] kernfs: don't create a negative dentry if inactive node
|
|
exists
|
|
|
|
It's been reported that doing stress test for module insertion and
|
|
removal can result in an ENOENT from libkmod for a valid module.
|
|
|
|
In kernfs_iop_lookup() a negative dentry is created if there's no kernfs
|
|
node associated with the dentry or the node is inactive.
|
|
|
|
But inactive kernfs nodes are meant to be invisible to the VFS and
|
|
creating a negative dentry for these can have unexpected side effects
|
|
when the node transitions to an active state.
|
|
|
|
The point of creating negative dentries is to avoid the expensive
|
|
alloc/free cycle that occurs if there are frequent lookups for kernfs
|
|
attributes that don't exist. So kernfs nodes that are not yet active
|
|
should not result in a negative dentry being created so when they
|
|
transition to an active state VFS lookups can create an associated
|
|
dentry is a natural way.
|
|
|
|
It's also been reported that https://github.com/osandov/blktests.git
|
|
test block/001 hangs during the test. It was suggested that recent
|
|
changes to blktests might have caused it but applying this patch
|
|
resolved the problem without change to blktests.
|
|
|
|
Fixes: c7e7c04274b1 ("kernfs: use VFS negative dentry caching")
|
|
Tested-by: Yi Zhang <yi.zhang@redhat.com>
|
|
ACKed-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
Link: https://lore.kernel.org/r/163330943316.19450.15056895533949392922.stgit@mickey.themaw.net
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Signed-off-by: Jim Somerville <jim.somerville@windriver.com>
|
|
---
|
|
fs/kernfs/dir.c | 9 ++++++++-
|
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
|
|
index dd7ef74ee0ff..6c189848f5c2 100644
|
|
--- a/fs/kernfs/dir.c
|
|
+++ b/fs/kernfs/dir.c
|
|
@@ -1119,7 +1119,14 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
|
|
|
|
kn = kernfs_find_ns(parent, dentry->d_name.name, ns);
|
|
/* attach dentry and inode */
|
|
- if (kn && kernfs_active(kn)) {
|
|
+ if (kn) {
|
|
+ /* Inactive nodes are invisible to the VFS so don't
|
|
+ * create a negative.
|
|
+ */
|
|
+ if (!kernfs_active(kn)) {
|
|
+ up_read(&kernfs_rwsem);
|
|
+ return NULL;
|
|
+ }
|
|
inode = kernfs_get_inode(dir->i_sb, kn);
|
|
if (!inode)
|
|
inode = ERR_PTR(-ENOMEM);
|
|
--
|
|
2.25.1
|
|
|