Linux filesystem development
 help / color / mirror / Atom feed
* [PATCH 0/3] binfmt_misc: use RCU for the handler lookup
@ 2026-07-08 16:51 Christian Brauner
  2026-07-08 16:51 ` [PATCH 1/3] binfmt_misc: convert entry list to an hlist Christian Brauner
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Christian Brauner @ 2026-07-08 16:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Alexander Viro, Christian Brauner, Jan Kara, linux-mm,
	Farid Zakaria, jannh

Once binfmt_misc is loaded load_misc_binary() runs for every execve()
on the system since binfmt_misc registers at the head of the formats
list. Every exec therefore performs read_lock() and read_unlock() on
the entries_lock of the relevant binfmt_misc instance, i.e., two
atomic read-modify-writes on a shared cacheline, in the common case
just to conclude that the binary matches no handler. User namespaces
without their own binfmt_misc mount fall back to an ancestor's
instance so on container-heavy systems every exec on the machine
typically ends up hammering the cacheline of init_binfmt_misc. On
PREEMPT_RT the rwlock additionally turns the handler lookup into a
sleeping lock on the exec fast path.

The lock protects very little. Entries are immutable after publication
except for the Enabled bit which is already toggled locklessly via
set_bit()/clear_bit() and entry lifetime is already handled by the
users refcount. The read lock's only remaining job is to make "the
entry is still linked" and "take a reference" atomic with respect to
the unlink sites.

So make the lookup an RCU walk that acquires a reference via
refcount_inc_not_zero() and free entries via kfree_rcu(). The removal
paths need to detect whether an entry has already been unlinked and
rely on list_del_init() reinitialization for that today, but
reinitializing the forward pointer of a removed entry would make a
concurrent lockless walker standing on it loop indefinitely. hlists
support exactly this pattern: hlist_del_init_rcu() keeps the forward
pointer of a removed entry intact for concurrent walkers and only
zeroes ->pprev with hlist_unhashed() serving as the linked test. Hence
the first patch converts the entry list to an hlist so the RCU
conversion in the second is a pure locking change.

Writers remain serialized by the inode lock of the root dentry with
one exception: bm_evict_inode() unlinks entries during umount without
holding it. A spinlock stays around the unlink sites to make that
exclusion explicit instead of relying on superblock lifetime rules to
provide it implicitly.

Handler removal semantics are unchanged. An exec that acquired a
reference just before its handler was unregistered already completes
with the removed handler today. The read lock never protected against
that, it only made the window smaller.

With this an exec that matches no binfmt_misc entry no longer writes
to any shared cacheline at all. The last patch annotates the
long-standing lockless ->enabled accesses for KCSAN while at it.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
Christian Brauner (3):
      binfmt_misc: convert entry list to an hlist
      binfmt_misc: use RCU for the handler lookup
      binfmt_misc: annotate racy accesses to ->enabled

 fs/binfmt_misc.c        | 86 ++++++++++++++++++++++++++++---------------------
 include/linux/binfmts.h |  4 +--
 kernel/user.c           |  4 +--
 3 files changed, 53 insertions(+), 41 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260708-work-binfmt_misc-locking-15347df12ec8


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-09 10:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08 16:51 [PATCH 0/3] binfmt_misc: use RCU for the handler lookup Christian Brauner
2026-07-08 16:51 ` [PATCH 1/3] binfmt_misc: convert entry list to an hlist Christian Brauner
2026-07-09 10:46   ` Jori Koolstra
2026-07-08 16:51 ` [PATCH 2/3] binfmt_misc: use RCU for the handler lookup Christian Brauner
2026-07-08 16:51 ` [PATCH 3/3] binfmt_misc: annotate racy accesses to ->enabled Christian Brauner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox