From: Josef Bacik <josef@toxicpanda.com>
To: "Paul E. McKenney" <paulmck@kernel.org>,
Frederic Weisbecker <frederic@kernel.org>,
Neeraj Upadhyay <neeraj.upadhyay@kernel.org>,
Joel Fernandes <joelagnelf@nvidia.com>,
Boqun Feng <boqun@kernel.org>, Thomas Gleixner <tglx@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Jiri Olsa <jolsa@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
x86@kernel.org, Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Puranjay Mohan <puranjay@kernel.org>,
Xu Kuohai <xukuohai@huaweicloud.com>
Cc: Andy Lutomirski <luto@kernel.org>,
Josh Triplett <josh@joshtriplett.org>,
Uladzislau Rezki <urezki@gmail.com>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Lai Jiangshan <jiangshanlai@gmail.com>,
Zqiang <qiang.zhang@linux.dev>, Juergen Gross <jgross@suse.com>,
Luis Chamberlain <mcgrof@kernel.org>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
linux-kernel@vger.kernel.org, rcu@vger.kernel.org,
linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
xen-devel@lists.xenproject.org,
Josef Bacik <josef@toxicpanda.com>
Subject: [PATCH RFC 04/13] kprobes: Let Tasks RCU recognise tasks preempted in an optprobe jump window
Date: Thu, 10 Sep 2026 18:50:27 +0000 [thread overview]
Message-ID: <20260910-b4-rcu-tasks-preempt-qs-v1-4-d4469f4cc101@toxicpanda.com> (raw)
In-Reply-To: <20260910-b4-rcu-tasks-preempt-qs-v1-0-d4469f4cc101@toxicpanda.com>
kprobe_optimizer() is the one synchronize_rcu_tasks() user that is not
about trampoline text: it waits for tasks that were preempted on an
instruction boundary inside the bytes it is about to overwrite with the
optimized jump, so that none of them resumes into the middle of the new
instruction. Such a task sits in ordinary kernel or module text with
rcu_tramp_nesting == 0, and can only have got there via an irq-exit
preemption.
Add kprobe_in_optimized_region(), a lockless and conservative form of
get_optimized_kprobe() that reports whether any registered kprobe lies
within MAX_OPTIMIZED_LENGTH before the given address regardless of its
optimization state, and have rcu_tasks_ip_in_trampoline() consult it so
that a task interrupted there keeps holding off the Tasks RCU grace
period once preemption becomes a quiescent state.
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
include/linux/kprobes.h | 8 +++++++-
include/linux/rcupdate.h | 4 +++-
kernel/kprobes.c | 24 ++++++++++++++++++++++++
kernel/rcu/tasks.h | 6 ++++++
4 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index e6de7ae55bda..74cc48c04417 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -530,11 +530,17 @@ static inline bool is_kprobe_insn_slot(unsigned long addr)
}
#endif /* !CONFIG_KPROBES */
-#ifndef CONFIG_OPTPROBES
+#ifdef CONFIG_OPTPROBES
+bool kprobe_in_optimized_region(unsigned long addr);
+#else /* !CONFIG_OPTPROBES */
static inline bool is_kprobe_optinsn_slot(unsigned long addr)
{
return false;
}
+static inline bool kprobe_in_optimized_region(unsigned long addr)
+{
+ return false;
+}
#endif /* !CONFIG_OPTPROBES */
#ifdef CONFIG_KRETPROBES
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 0a408e36ea15..e9afbbb1b061 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -200,7 +200,9 @@ bool arch_rcu_tasks_ip_in_trampoline(unsigned long ip);
* cannot be preempted synchronously, only from an interrupt, so the irq-exit
* preemption path covers it by checking regs->ip with
* rcu_tasks_ip_in_trampoline() and holding the count elevated across
- * preempt_schedule_irq() when it matches.
+ * preempt_schedule_irq() when it matches. The same check covers the one
+ * non-trampoline user, kprobe jump optimization, which waits for tasks
+ * preempted inside the instruction bytes it is about to overwrite.
*
* Only current writes the count and only current (or an interrupt on the same
* CPU) reads it, so plain accesses suffice.
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 6337da5cab9e..76f146edb0e5 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -511,6 +511,30 @@ static struct kprobe *get_optimized_kprobe(kprobe_opcode_t *addr)
return NULL;
}
+/**
+ * kprobe_in_optimized_region - Could @addr be inside bytes a jump-optimized
+ * kprobe replaces?
+ * @addr: kernel text address, typically an interrupted instruction pointer
+ *
+ * kprobe_optimizer() relies on synchronize_rcu_tasks() to wait for tasks that
+ * were preempted on an instruction boundary inside the region about to be
+ * overwritten by the optimized jump; such a task must not report a Tasks RCU
+ * quiescent state when it is preempted (see rcu_tasks_ip_in_trampoline()).
+ * This is the lockless, conservative form of get_optimized_kprobe(): it does
+ * not care whether the kprobe found is, or ever will be, optimized. May be
+ * called from any context with preemption disabled.
+ */
+bool kprobe_in_optimized_region(unsigned long addr)
+{
+ int i;
+
+ for (i = 1; i < MAX_OPTIMIZED_LENGTH / sizeof(kprobe_opcode_t); i++)
+ if (get_kprobe((kprobe_opcode_t *)addr - i))
+ return true;
+ return false;
+}
+NOKPROBE_SYMBOL(kprobe_in_optimized_region);
+
/* Optimization staging list, protected by 'kprobe_mutex' */
static LIST_HEAD(optimizing_list);
static LIST_HEAD(unoptimizing_list);
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
index a801ec4a951b..a55dc2a20fb7 100644
--- a/kernel/rcu/tasks.h
+++ b/kernel/rcu/tasks.h
@@ -1114,6 +1114,9 @@ bool __weak arch_rcu_tasks_ip_in_trampoline(unsigned long ip)
* deliberately does not consult is_ftrace_trampoline() and friends: text
* being torn down may already be unregistered there while a task still
* stands on it;
+ * - inside the bytes following a registered kprobe that jump optimization
+ * may overwrite, which kprobe_optimizer() protects with
+ * synchronize_rcu_tasks();
* - in core text the architecture flags via arch_rcu_tasks_ip_in_trampoline().
*
* A false positive only defers the quiescent state to the task's next
@@ -1121,6 +1124,9 @@ bool __weak arch_rcu_tasks_ip_in_trampoline(unsigned long ip)
*/
bool rcu_tasks_ip_in_trampoline(unsigned long ip)
{
+ if (kprobe_in_optimized_region(ip))
+ return true;
+
if (core_kernel_text(ip))
return arch_rcu_tasks_ip_in_trampoline(ip);
return !is_module_text_address(ip);
--
2.55.0
next prev parent reply other threads:[~2026-09-10 18:51 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 18:50 [PATCH RFC 00/13] rcu-tasks: let preemption outside trampolines be a quiescent state Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 01/13] rcu-tasks: Add per-task trampoline nesting count Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 02/13] entry: Pass pt_regs to irqentry_exit_cond_resched() Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 03/13] rcu-tasks: Hold trampoline nesting across irq-exit preemption in trampoline text Josef Bacik
2026-09-10 18:50 ` Josef Bacik [this message]
2026-09-10 19:16 ` [PATCH RFC 04/13] kprobes: Let Tasks RCU recognise tasks preempted in an optprobe jump window sashiko-bot
2026-09-10 22:46 ` Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 05/13] ftrace: Mark modules hosting direct-call trampolines for Tasks RCU Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 06/13] x86/ftrace: Maintain Tasks RCU trampoline nesting in ftrace_caller Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 07/13] x86/kprobes: Maintain Tasks RCU trampoline nesting in the optprobe template Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 08/13] bpf, x86: Maintain Tasks RCU trampoline nesting in the BPF trampoline Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 09/13] arm64: ftrace: Maintain Tasks RCU trampoline nesting in ftrace_caller Josef Bacik
2026-09-10 19:04 ` sashiko-bot
2026-09-10 22:46 ` Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 10/13] bpf, arm64: Maintain Tasks RCU trampoline nesting in the BPF trampoline Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 11/13] samples: ftrace: Maintain Tasks RCU trampoline nesting in direct-call trampolines Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 12/13] rcutorture: Bracket Tasks RCU readers with trampoline nesting Josef Bacik
2026-09-10 18:50 ` [PATCH RFC 13/13] rcu-tasks: Treat preemption outside trampolines as a quiescent state Josef Bacik
2026-09-10 19:44 ` [PATCH RFC 00/13] rcu-tasks: let preemption outside trampolines be " Steven Rostedt
2026-09-10 22:59 ` 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=20260910-b4-rcu-tasks-preempt-qs-v1-4-d4469f4cc101@toxicpanda.com \
--to=josef@toxicpanda.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=boqun@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=catalin.marinas@arm.com \
--cc=daniel@iogearbox.net \
--cc=frederic@kernel.org \
--cc=ihor.solodrai@linux.dev \
--cc=jgross@suse.com \
--cc=jiangshanlai@gmail.com \
--cc=joelagnelf@nvidia.com \
--cc=jolsa@kernel.org \
--cc=josh@joshtriplett.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mark.rutland@arm.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=mcgrof@kernel.org \
--cc=mhiramat@kernel.org \
--cc=neeraj.upadhyay@kernel.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=puranjay@kernel.org \
--cc=qiang.zhang@linux.dev \
--cc=rcu@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=tglx@kernel.org \
--cc=urezki@gmail.com \
--cc=will@kernel.org \
--cc=x86@kernel.org \
--cc=xen-devel@lists.xenproject.org \
--cc=xukuohai@huaweicloud.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