From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
To: "Paul E . McKenney" <paulmck@kernel.org>,
Frederic Weisbecker <frederic@kernel.org>,
Neeraj Upadhyay <neeraj.upadhyay@kernel.org>,
Joel Fernandes <joelagnelf@nvidia.com>,
Josh Triplett <josh@joshtriplett.org>,
Boqun Feng <boqun@kernel.org>,
Uladzislau Rezki <urezki@gmail.com>, Thomas Graf <tgraf@suug.ch>,
Herbert Xu <herbert@gondor.apana.org.au>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Lai Jiangshan <jiangshanlai@gmail.com>,
Zqiang <qiang.zhang@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
rcu@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-crypto@vger.kernel.org, bpf@vger.kernel.org,
linux-trace-kernel@vger.kernel.org
Subject: [RFC PATCH 0/3] fprobe, rcu/tasks, rhashtable: Switch fprobe and BPF kprobe-multi to Tasks-Rude RCU
Date: Mon, 28 Sep 2026 23:29:13 +0900 [thread overview]
Message-ID: <179060575297.372125.10581329083761385407.stgit@devnote2> (raw)
Hi,
Here is an RFC patch series which removes standard RCU read lock
(guard(rcu) and rcu_read_lock()) from fprobe callback paths
by switching fprobe and BPF multi-kprobe to Tasks-Rude RCU.
Motivation & Problem
====================
Currently, fprobe entry and exit callbacks (fprobe_fgraph_entry,
fprobe_return, and fprobe_ftrace_entry) execute in the tracing hot
path where preemption is disabled.
However, fprobe was forced to wrap hash lookups with guard(rcu)() and
rcu_read_lock() because:
- rhashtable defers bucket table deallocation using standard RCU
- unregister_fprobe() and BPF waited for a standard RCU grace period
Taking standard RCU read locks in the tracing fast path introduces
several drawbacks:
1. Unnecessary Runtime Overhead:
Every probe hit manipulates current->rcu_read_lock_nesting with
memory barriers, and rcu_read_unlock() adds conditional branches
to check for special quiescent processing.
On debug kernels with CONFIG_PROVE_RCU=y or CONFIG_LOCKDEP=y,
this additionally acquires and releases lockdep maps on every hit,
introducing severe lockdep hashing overhead and tracer recursion risks.
2. Fragile Dependency on rcu_is_watching():
Standard RCU treats idle CPUs (and user-space on nohz_full CPUs) as
Extended Quiescent States (EQS). If a function is traced while
rcu_is_watching() is false, standard RCU is blind to the read-side
critical section. In such contexts, synchronize_rcu() does not wait
for the reader (risking Use-After-Free), and lockdep emits an
"RCU-illegal: rcu_read_lock() used while not watching!" warning.
To avoid this, ftrace callbacks normally require FTRACE_OPS_FL_RCU,
adding extra trampoline check overhead.
3. Asymmetric Synchronization with fprobe_return():
fprobe_return() executes under preempt_disable_notrace() without
holding rcu_read_lock(). Prior to this series, unregister_fprobe()
only waited on synchronize_rcu(), which does NOT wait for pure
preempt-disabled sections, leaving a potential Use-After-Free window
during probe unregistration.
I've tried to fix the last UAF with simply introducing guard(rcu)()[1]
but Sashiko found the 2nd problem [2]. So I decided to implement this
series.
[1] https://lore.kernel.org/all/179055575009.241711.6358052647499787191.stgit@devnote2/
[2] https://lore.kernel.org/all/20260928005114.9C9FC1F000FF@smtp.kernel.org/
Solution: Tasks-Rude RCU
========================
Because fprobe callbacks already run strictly within preempt-disabled
contexts, we can transition fprobe and its deferred table reclamation
to Tasks-Rude RCU:
- Tasks-Rude RCU detects grace periods via schedule_on_each_cpu(),
forcing a schedule on every online CPU. This guarantees that all
preempt-disabled sections that began prior to the grace period have
completed before memory is reclaimed.
- Unlike standard RCU, Tasks-Rude RCU does not rely on dyntick-idle /
EQS tracking. It does NOT require rcu_is_watching() to be true and
does not trigger lockdep warnings in pre-RCU/idle execution paths.
- Within fprobe, guard(rcu)() is replaced with guard(rcu_sched_notrace)(),
reducing the lookup lock to pure, non-tracing preempt counter
increments without lockdep or RCU state manipulation.
Feedback and suggestions from RCU, BPF, and tracing maintainers are welcome!
Thank you,
---
base-commit: 5bfa9f1a9dcb6ecb607adbc1c0226605c972935b
Masami Hiramatsu (Google) (3):
rcu/tasks: Export call_rcu_tasks_rude()
rhashtable: Add use_tasks_rude parameter to defer bucket table free
fprobe: Switch fprobe and BPF kprobe-multi to Tasks-Rude RCU
include/linux/rcupdate.h | 6 +++
include/linux/rhashtable-types.h | 2 +
kernel/bpf/syscall.c | 2 +
kernel/rcu/tasks.h | 8 ++---
kernel/trace/fprobe.c | 66 +++++++++++++++++++++-----------------
lib/rhashtable.c | 5 ++-
6 files changed, 54 insertions(+), 35 deletions(-)
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
next reply other threads:[~2026-09-28 14:29 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 14:29 Masami Hiramatsu (Google) [this message]
2026-09-28 14:29 ` [RFC PATCH 1/3] rcu/tasks: Export call_rcu_tasks_rude() Masami Hiramatsu (Google)
2026-09-28 14:39 ` sashiko-bot
2026-09-28 15:17 ` bot+bpf-ci
2026-09-28 14:29 ` [RFC PATCH 2/3] rhashtable: Add use_tasks_rude parameter to defer bucket table free Masami Hiramatsu (Google)
2026-09-28 14:43 ` sashiko-bot
2026-09-28 14:29 ` [RFC PATCH 3/3] fprobe: Switch fprobe and BPF kprobe-multi to Tasks-Rude RCU Masami Hiramatsu (Google)
2026-09-28 14:46 ` sashiko-bot
2026-09-28 16:25 ` [RFC PATCH 0/3] fprobe, rcu/tasks, rhashtable: " Paul E. McKenney
2026-09-28 23:28 ` Masami Hiramatsu
2026-09-29 0:04 ` Paul E. McKenney
2026-09-29 0:33 ` Andrii Nakryiko
2026-09-29 0:41 ` Paul E. McKenney
2026-09-30 0:35 ` Masami Hiramatsu
2026-09-30 0:47 ` Paul E. McKenney
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=179060575297.372125.10581329083761385407.stgit@devnote2 \
--to=mhiramat@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=boqun@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=frederic@kernel.org \
--cc=herbert@gondor.apana.org.au \
--cc=ihor.solodrai@linux.dev \
--cc=jiangshanlai@gmail.com \
--cc=joelagnelf@nvidia.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=josh@joshtriplett.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=mathieu.desnoyers@efficios.com \
--cc=memxor@gmail.com \
--cc=neeraj.upadhyay@kernel.org \
--cc=paulmck@kernel.org \
--cc=qiang.zhang@linux.dev \
--cc=rcu@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=song@kernel.org \
--cc=tgraf@suug.ch \
--cc=urezki@gmail.com \
--cc=yonghong.song@linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.