From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Jan Kara <jack@suse.cz>, Al Viro <viro@zeniv.linux.org.uk>,
linux-kernel@vger.kernel.org,
"Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH 0/2] fs: don't let idle threads pin the initramfs
Date: Tue, 13 Oct 2026 00:11:05 +0200 [thread overview]
Message-ID: <20261013-work-fs-idle_fs-v1-0-2063d1bcb5aa@kernel.org> (raw)
Since v7.0 nullfs is the real rootfs and userspace can pivot_root() away
from the initramfs and unmount it. systemd does exactly that and the
initramfs is supposed to be freed afterwards. But it isn't (cf. [1]).
The unpacked initramfs stays around forever. It shows up as Unevictable
in /proc/meminfo with ramfs and as Shmem with tmpfs. In the reports
that's between 70MB and 150MB.
Two things keep it alive and neither is visible from userspace:
(1) On v7.0 to v7.2 devtmpfsd unshares a copy of the initial mount
namespace which since nullfs contains the initramfs mount. It
doesn't show up in /proc/<pid>/mountinfo because it's below the
thread's root. That's already fixed in mainline by commit
66d2faeccbff ("devtmpfs: create private mount namespace").
(2) On all kernels since v7.0 the idle threads of the secondary cpus
are forked from PID 1 and each of them gets a private copy of the
fs_struct of PID 1 with the initramfs as root and pwd. Idle threads
aren't on the task list so pivot_root() never moves them over to
the new root and they never exit. With a single possible cpu there
are no such idle threads which is why booting a VM with -smp 1
hides it.
This series fixes (2) by letting the idle threads share init_fs like
init_task already does. The first patch turns the umh boolean of
copy_fs() into flags. The second patch is the actual fix and carries a
reproducer.
systemd could go back to emptying the initramfs when switching root like
it did before nullfs and that's what [2] does. But that only frees the
contents. The mount and the superblock stay pinned. And I don't think
userspace should have to do that. With nullfs it's supposed to be able
to just unmount the initramfs and be done with it.
We could also teach chroot_fs_refs() about idle threads. But they are
kernel threads and have no business holding a reference to the root of
userspace to begin with.
Of the stable kernels only v7.2 is affected and the backport looks
different there. PID 1 still shares init_fs with all kthreads so passing
CLONE_FS in fork_idle() is enough. It also needs 66d2faeccbff which
applies cleanly.
I've tested this with the reproducer from the second patch and with a
systemd 262 initrd on 4 cpus. On vfs.fixes about 170MB stay Unevictable
after switching root and with this series they're freed. Same for the
backport on v7.2.
[1]: https://github.com/systemd/systemd/issues/43911
[2]: https://github.com/systemd/systemd/pull/44144
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
Christian Brauner (2):
fs: pass flags to copy_fs()
fs: let idle threads share init_fs
kernel/fork.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
---
base-commit: 19cd109ac4ab4b0dece4ebfbf3ab0532cc5cb505
change-id: 20261012-work-fs-idle_fs-bbfb9604d4f4
next reply other threads:[~2026-10-12 22:11 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 22:11 Christian Brauner [this message]
2026-10-12 22:11 ` [PATCH 1/2] fs: pass flags to copy_fs() Christian Brauner
2026-10-12 22:11 ` [PATCH 2/2] fs: let idle threads share init_fs Christian Brauner
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=20261013-work-fs-idle_fs-v1-0-2063d1bcb5aa@kernel.org \
--to=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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®