From: Christian Brauner <brauner@kernel.org>
To: Zenghui Yu <yuzenghui@huawei.com>
Cc: linux-fsdevel@vger.kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-kernel@vger.kernel.org,
Alexander Viro <viro@zeniv.linux.org.uk>,
Jan Kara <jack@suse.cz>, Jann Horn <jannh@google.com>
Subject: Re: [PATCH RFC v4 23/25] fs: start all kthreads in nullfs
Date: Thu, 17 Sep 2026 14:07:22 +0200 [thread overview]
Message-ID: <20260917-atemtechnik-bleichen-befassen-9a57db01baf0@brauner> (raw)
In-Reply-To: <15174353-3f4a-a1ca-5bd1-ea2a4c77828e@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 379 bytes --]
> The following lockdep splat can be triggered on mainline, which is built
> with arm64's defconfig plus
>
> CONFIG_SHRINKER_DEBUG
> CONFIG_PROVE_LOCKING
> CONFIG_FTRACE
>
> . Reverting this patch (as pointed out by AI) makes this warn disappear.
This is benign and caused by holding LOCK_MOUNT_EXACT() for longer than
necessary. I'm adding the appended fix to vfs.fixes.
[-- Attachment #2: 0001-fs-don-t-create-the-private-nullfs-mount-under-names.patch --]
[-- Type: text/x-diff, Size: 3743 bytes --]
From a6bd269dceeb76f92d5e8d378fed2482dd208085 Mon Sep 17 00:00:00 2001
From: Christian Brauner <brauner@kernel.org>
Date: Thu, 17 Sep 2026 13:20:25 +0200
Subject: [PATCH] fs: don't create the private nullfs mount under namespace_sem
init_mount_tree() mounts the mutable rootfs on top of nullfs via
LOCK_MOUNT_EXACT(). That declares a pinned mountpoint with a cleanup
attribute in the scope of the whole function so the nullfs root inode
lock and namespace_sem are only dropped when init_mount_tree() returns.
This became a problem when the private nullfs instance for kthreads was
added. kern_mount() allocates a new superblock and alloc_super() takes
the new s_umount with SINGLE_DEPTH_NESTING and then shrinker_mutex via
shrinker_alloc(). Doing that with namespace_sem held teaches lockdep the
dependency
namespace_sem -> s_umount/1 -> shrinker_mutex
With CONFIG_SHRINKER_DEBUG shrinker_debugfs_rename() takes the debugfs
directory inode lock under shrinker_mutex every time a block device is
mounted and lock_mount_exact() takes namespace_sem under the inode lock
of the mountpoint for every mount. So mounting anything on debugfs,
e.g. the tracefs automount on /sys/kernel/debug/tracing, closes the
cycle:
WARNING: possible circular locking dependency detected
7.3.0-rc3+ #17 Not tainted
------------------------------------------------------
rasdaemon/4449 is trying to acquire lock:
(namespace_sem){++++}-{4:4}, at: lock_mount_exact+0x4c/0x308
but task is already holding lock:
(&sb->s_type->i_mutex_key#17){++++}-{4:4}, at: lock_mount_exact+0x3c/0x308
which lock already depends on the new lock.
...
Chain exists of:
namespace_sem --> shrinker_mutex --> &sb->s_type->i_mutex_key#17
This can't actually deadlock. init_mount_tree() runs single-threaded
during early boot before any other task exists and nothing allocates a
superblock under namespace_sem after that. But lockdep can't know that
and disables itself for the rest of the boot.
Move mounting the rootfs on top of nullfs into a helper so the locks
are dropped when it returns.
Fixes: 32750c77e811 ("fs: start all kthreads in nullfs")
Reported-by: Zenghui Yu <yuzenghui@huawei.com>
Closes: https://lore.kernel.org/15174353-3f4a-a1ca-5bd1-ea2a4c77828e@huawei.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
fs/namespace.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index ae5dc64f8b45..5e41021eaa63 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -6184,6 +6184,21 @@ struct mnt_namespace init_mnt_ns = {
.poll = __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll),
};
+static void __init mount_rootfs_on_nullfs(struct vfsmount *mnt,
+ struct vfsmount *nullfs_mnt)
+{
+ struct path root = {
+ .mnt = nullfs_mnt,
+ .dentry = nullfs_mnt->mnt_root,
+ };
+
+ LOCK_MOUNT_EXACT(mp, &root);
+ if (unlikely(IS_ERR(mp.parent)))
+ panic("VFS: Failed to mount rootfs on nullfs");
+ scoped_guard(mount_writer)
+ attach_mnt(real_mount(mnt), mp.parent, mp.mp);
+}
+
static void __init init_mount_tree(void)
{
struct vfsmount *mnt, *nullfs_mnt;
@@ -6215,15 +6230,7 @@ static void __init init_mount_tree(void)
mnt_root = real_mount(nullfs_mnt);
init_mnt_ns.root = mnt_root;
- /* Mount mutable rootfs on top of nullfs. */
- root.mnt = nullfs_mnt;
- root.dentry = nullfs_mnt->mnt_root;
-
- LOCK_MOUNT_EXACT(mp, &root);
- if (unlikely(IS_ERR(mp.parent)))
- panic("VFS: Failed to mount rootfs on nullfs");
- scoped_guard(mount_writer)
- attach_mnt(real_mount(mnt), mp.parent, mp.mp);
+ mount_rootfs_on_nullfs(mnt, nullfs_mnt);
pr_info("VFS: Finished mounting rootfs on nullfs\n");
--
2.53.0
next prev parent reply other threads:[~2026-09-17 12:07 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-01 13:56 [PATCH RFC v4 00/25] fs,kthread: " Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 01/25] fs: add switch_fs_struct() Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 02/25] fs: notice when init abandons fs sharing Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 03/25] fs: add scoped_with_init_fs() Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 04/25] fs: add real_fs to track task's actual fs_struct Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 05/25] fs: make userspace_init_fs a dynamically-initialized pointer Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 06/25] rnbd: use scoped_with_init_fs() for block device open Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 07/25] crypto: ccp: use scoped_with_init_fs() for SEV file access Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 08/25] scsi: target: use scoped_with_init_fs() for ALUA metadata Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 09/25] scsi: target: use scoped_with_init_fs() for APTPL metadata Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 10/25] btrfs: use scoped_with_init_fs() for update_dev_time() Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 11/25] coredump: use scoped_with_init_fs() for coredump path resolution Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 12/25] fs: use scoped_with_init_fs() for kernel_read_file_from_path_initns() Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 13/25] ksmbd: use scoped_with_init_fs() for share path resolution Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 14/25] ksmbd: use scoped_with_init_fs() for filesystem info path lookup Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 15/25] ksmbd: use scoped_with_init_fs() for VFS path operations Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 16/25] pnfs/blocklayout: use scoped_with_init_fs() for SCSI device lookup Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 17/25] initramfs: use scoped_with_init_fs() for rootfs unpacking Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 18/25] af_unix: use scoped_with_init_fs() for coredump socket lookup Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 19/25] fs: stop sharing fs_struct between init_task and pid 1 Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 20/25] fs: add umh argument to struct kernel_clone_args Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 21/25] devtmpfs: create private mount namespace Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 22/25] nullfs: make nullfs multi-instance Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 23/25] fs: start all kthreads in nullfs Christian Brauner
2026-09-15 12:39 ` Zenghui Yu
2026-09-17 12:07 ` Christian Brauner [this message]
2026-09-18 1:59 ` Zenghui Yu
2026-06-01 13:56 ` [PATCH RFC v4 24/25] fs: stop rewriting kthread fs structs Christian Brauner
2026-06-01 13:56 ` [PATCH RFC v4 25/25] fs: stop rewriting paths for PF_EXITING | PF_DUMPCORE Christian Brauner
2026-07-05 12:34 ` [PATCH RFC v4 00/25] fs,kthread: start all kthreads in nullfs Askar Safin
2026-07-05 12:57 ` Askar Safin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260917-atemtechnik-bleichen-befassen-9a57db01baf0@brauner \
--to=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®