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 v2 11/15] samples: ftrace: Maintain Tasks RCU trampoline nesting in direct-call trampolines
Date: Fri, 11 Sep 2026 14:08:49 +0000 [thread overview]
Message-ID: <20260911-b4-rcu-tasks-preempt-qs-v2-11-eaaa61ed2da4@toxicpanda.com> (raw)
In-Reply-To: <20260911-b4-rcu-tasks-preempt-qs-v2-0-eaaa61ed2da4@toxicpanda.com>
Follow the register_ftrace_direct() contract in the sample modules: on
x86-64 and arm64, have each hand-written trampoline increment
current->rcu_tramp_nesting before calling its C handler and decrement it
before returning, via a small shared samples/ftrace/ftrace-direct.h.
%r11 and x12/w13 are used as scratch; both are caller-saved, non-argument
registers and therefore dead on entry to and exit from an fentry
trampoline.
The header pulls in the generated asm-offsets.h only on those two
architectures, since it is not generally safe to include from C (PPC32's
TASK_SIZE and arm64's TRAMP_VALIAS clash with the C definitions; the
latter is worked around locally with push_macro/pop_macro). Other
architectures get empty macros and are unchanged.
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
samples/ftrace/ftrace-direct-modify.c | 9 ++++
samples/ftrace/ftrace-direct-multi-modify.c | 9 ++++
samples/ftrace/ftrace-direct-multi.c | 5 +++
samples/ftrace/ftrace-direct-too.c | 5 +++
samples/ftrace/ftrace-direct.c | 5 +++
samples/ftrace/ftrace-direct.h | 64 +++++++++++++++++++++++++++++
6 files changed, 97 insertions(+)
diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-direct-modify.c
index 164d9dd6fd92..eb8230fa4242 100644
--- a/samples/ftrace/ftrace-direct-modify.c
+++ b/samples/ftrace/ftrace-direct-modify.c
@@ -2,6 +2,7 @@
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/ftrace.h>
+#include "ftrace-direct.h"
#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)
#include <asm/asm-offsets.h>
#endif
@@ -73,7 +74,9 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" call my_direct_func1\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp1, .-my_tramp1\n"
@@ -85,7 +88,9 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" call my_direct_func2\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp2, .-my_tramp2\n"
@@ -141,11 +146,13 @@ asm (
" .globl my_tramp1\n"
" my_tramp1:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #16\n"
" stp x9, x30, [sp]\n"
" bl my_direct_func1\n"
" ldp x30, x9, [sp]\n"
" add sp, sp, #16\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp1, .-my_tramp1\n"
@@ -153,11 +160,13 @@ asm (
" .globl my_tramp2\n"
" my_tramp2:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #16\n"
" stp x9, x30, [sp]\n"
" bl my_direct_func2\n"
" ldp x30, x9, [sp]\n"
" add sp, sp, #16\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp2, .-my_tramp2\n"
" .popsection\n"
diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/ftrace-direct-multi-modify.c
index b03766c6217b..c8f1062e5d1a 100644
--- a/samples/ftrace/ftrace-direct-multi-modify.c
+++ b/samples/ftrace/ftrace-direct-multi-modify.c
@@ -2,6 +2,7 @@
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/ftrace.h>
+#include "ftrace-direct.h"
#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)
#include <asm/asm-offsets.h>
#endif
@@ -77,10 +78,12 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" pushq %rdi\n"
" movq 8(%rbp), %rdi\n"
" call my_direct_func1\n"
" popq %rdi\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp1, .-my_tramp1\n"
@@ -92,10 +95,12 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" pushq %rdi\n"
" movq 8(%rbp), %rdi\n"
" call my_direct_func2\n"
" popq %rdi\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp2, .-my_tramp2\n"
@@ -154,6 +159,7 @@ asm (
" .globl my_tramp1\n"
" my_tramp1:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #32\n"
" stp x9, x30, [sp]\n"
" str x0, [sp, #16]\n"
@@ -162,6 +168,7 @@ asm (
" ldp x30, x9, [sp]\n"
" ldr x0, [sp, #16]\n"
" add sp, sp, #32\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp1, .-my_tramp1\n"
@@ -169,6 +176,7 @@ asm (
" .globl my_tramp2\n"
" my_tramp2:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #32\n"
" stp x9, x30, [sp]\n"
" str x0, [sp, #16]\n"
@@ -177,6 +185,7 @@ asm (
" ldp x30, x9, [sp]\n"
" ldr x0, [sp, #16]\n"
" add sp, sp, #32\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp2, .-my_tramp2\n"
" .popsection\n"
diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-direct-multi.c
index 3fe6ddaf0b69..bc6a88dd4ffc 100644
--- a/samples/ftrace/ftrace-direct-multi.c
+++ b/samples/ftrace/ftrace-direct-multi.c
@@ -3,6 +3,7 @@
#include <linux/mm.h> /* for handle_mm_fault() */
#include <linux/ftrace.h>
+#include "ftrace-direct.h"
#include <linux/sched/stat.h>
#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)
#include <asm/asm-offsets.h>
@@ -56,10 +57,12 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" pushq %rdi\n"
" movq 8(%rbp), %rdi\n"
" call my_direct_func\n"
" popq %rdi\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp, .-my_tramp\n"
@@ -101,6 +104,7 @@ asm (
" .globl my_tramp\n"
" my_tramp:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #32\n"
" stp x9, x30, [sp]\n"
" str x0, [sp, #16]\n"
@@ -109,6 +113,7 @@ asm (
" ldp x30, x9, [sp]\n"
" ldr x0, [sp, #16]\n"
" add sp, sp, #32\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp, .-my_tramp\n"
" .popsection\n"
diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-direct-too.c
index bf2411aa6fd7..247e418644a2 100644
--- a/samples/ftrace/ftrace-direct-too.c
+++ b/samples/ftrace/ftrace-direct-too.c
@@ -3,6 +3,7 @@
#include <linux/mm.h> /* for handle_mm_fault() */
#include <linux/ftrace.h>
+#include "ftrace-direct.h"
#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)
#include <asm/asm-offsets.h>
#endif
@@ -61,6 +62,7 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" pushq %rdi\n"
" pushq %rsi\n"
" pushq %rdx\n"
@@ -70,6 +72,7 @@ asm (
" popq %rdx\n"
" popq %rsi\n"
" popq %rdi\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp, .-my_tramp\n"
@@ -110,6 +113,7 @@ asm (
" .globl my_tramp\n"
" my_tramp:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #48\n"
" stp x9, x30, [sp]\n"
" stp x0, x1, [sp, #16]\n"
@@ -119,6 +123,7 @@ asm (
" ldp x0, x1, [sp, #16]\n"
" ldp x2, x3, [sp, #32]\n"
" add sp, sp, #48\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp, .-my_tramp\n"
" .popsection\n"
diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c
index 5368c8c39cbb..9e1964baf28b 100644
--- a/samples/ftrace/ftrace-direct.c
+++ b/samples/ftrace/ftrace-direct.c
@@ -3,6 +3,7 @@
#include <linux/sched.h> /* for wake_up_process() */
#include <linux/ftrace.h>
+#include "ftrace-direct.h"
#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)
#include <asm/asm-offsets.h>
#endif
@@ -54,9 +55,11 @@ asm (
" pushq %rbp\n"
" movq %rsp, %rbp\n"
CALL_DEPTH_ACCOUNT
+ RCU_TASKS_TRAMP_ENTER
" pushq %rdi\n"
" call my_direct_func\n"
" popq %rdi\n"
+ RCU_TASKS_TRAMP_EXIT
" leave\n"
ASM_RET
" .size my_tramp, .-my_tramp\n"
@@ -97,6 +100,7 @@ asm (
" .globl my_tramp\n"
" my_tramp:"
" hint 34\n" // bti c
+ RCU_TASKS_TRAMP_ENTER
" sub sp, sp, #32\n"
" stp x9, x30, [sp]\n"
" str x0, [sp, #16]\n"
@@ -104,6 +108,7 @@ asm (
" ldp x30, x9, [sp]\n"
" ldr x0, [sp, #16]\n"
" add sp, sp, #32\n"
+ RCU_TASKS_TRAMP_EXIT
" ret x9\n"
" .size my_tramp, .-my_tramp\n"
" .popsection\n"
diff --git a/samples/ftrace/ftrace-direct.h b/samples/ftrace/ftrace-direct.h
new file mode 100644
index 000000000000..d0313f33f47f
--- /dev/null
+++ b/samples/ftrace/ftrace-direct.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _SAMPLES_FTRACE_DIRECT_H
+#define _SAMPLES_FTRACE_DIRECT_H
+
+#include <linux/stringify.h>
+
+/*
+ * A direct-call trampoline is entered with no lock, refcount or RCU marker
+ * held; only Tasks RCU keeps it (and, for a module, its text) alive while a
+ * task is inside it or preempted in something it called. On architectures
+ * that select ARCH_HAS_RCU_TASKS_PREEMPT_QS a preemption is a Tasks RCU
+ * quiescent state unless current->rcu_tramp_nesting is non-zero, so the
+ * trampoline must raise it before calling out and drop it afterwards, exactly
+ * like the ftrace and BPF trampolines do. See rcu_tasks_trampoline_enter()
+ * and register_ftrace_direct(). The instructions before the increment and
+ * after the decrement are covered by ftrace_direct_mark_module().
+ *
+ * These expand to instruction strings for use inside the samples' asm()
+ * trampolines. The scratch register is caller-saved and not an argument
+ * register, so it is dead on entry to and exit from an fentry trampoline.
+ *
+ * The generated asm-offsets.h is only pulled in on the architectures that need
+ * it here: it is not generally safe to include from C (e.g. PPC32's TASK_SIZE
+ * and arm64's TRAMP_VALIAS clash with the C definitions), which is why the
+ * samples themselves guard their own include of it.
+ */
+#if defined(CONFIG_TASKS_RCU) && defined(CONFIG_X86_64)
+
+#include <asm/asm-offsets.h>
+
+#define RCU_TASKS_TRAMP_ENTER \
+ " movq %gs:current_task(%rip), %r11\n" \
+ " incl " __stringify(TASK_rcu_tramp_nesting) "(%r11)\n"
+#define RCU_TASKS_TRAMP_EXIT \
+ " movq %gs:current_task(%rip), %r11\n" \
+ " decl " __stringify(TASK_rcu_tramp_nesting) "(%r11)\n"
+
+#elif defined(CONFIG_TASKS_RCU) && defined(CONFIG_ARM64)
+
+/* arm64's asm-offsets.h redefines TRAMP_VALIAS from <asm/fixmap.h>. */
+#pragma push_macro("TRAMP_VALIAS")
+#undef TRAMP_VALIAS
+#include <asm/asm-offsets.h>
+#pragma pop_macro("TRAMP_VALIAS")
+
+#define RCU_TASKS_TRAMP_ENTER \
+ " mrs x12, sp_el0\n" \
+ " ldr w13, [x12, #" __stringify(TSK_RCU_TRAMP_NESTING) "]\n" \
+ " add w13, w13, #1\n" \
+ " str w13, [x12, #" __stringify(TSK_RCU_TRAMP_NESTING) "]\n"
+#define RCU_TASKS_TRAMP_EXIT \
+ " mrs x12, sp_el0\n" \
+ " ldr w13, [x12, #" __stringify(TSK_RCU_TRAMP_NESTING) "]\n" \
+ " sub w13, w13, #1\n" \
+ " str w13, [x12, #" __stringify(TSK_RCU_TRAMP_NESTING) "]\n"
+
+#else
+
+#define RCU_TASKS_TRAMP_ENTER
+#define RCU_TASKS_TRAMP_EXIT
+
+#endif
+
+#endif /* _SAMPLES_FTRACE_DIRECT_H */
--
2.55.0
next prev parent reply other threads:[~2026-09-11 14:10 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 14:08 [PATCH RFC v2 00/15] rcu-tasks: let preemption outside trampolines be a quiescent state Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 01/15] rcu-tasks: Add per-task trampoline nesting count Josef Bacik
2026-09-11 17:23 ` Paul E. McKenney
2026-09-11 14:08 ` [PATCH RFC v2 02/15] entry: Pass pt_regs to irqentry_exit_cond_resched() Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 03/15] rcu-tasks: Hold trampoline nesting across irq-exit preemption in trampoline text Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 04/15] kprobes: Let Tasks RCU recognise tasks preempted in an optprobe jump window Josef Bacik
2026-09-11 14:26 ` sashiko-bot
2026-09-11 17:27 ` Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 05/15] ftrace: Mark modules hosting direct-call trampolines for Tasks RCU Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 06/15] x86/ftrace: Maintain Tasks RCU trampoline nesting in ftrace_caller Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 07/15] x86/kprobes: Maintain Tasks RCU trampoline nesting in the optprobe template Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 08/15] bpf, x86: Maintain Tasks RCU trampoline nesting in the BPF trampoline Josef Bacik
2026-09-12 3:27 ` Alexei Starovoitov
2026-09-12 5:10 ` Paul E. McKenney
2026-09-12 17:18 ` Alexei Starovoitov
2026-09-12 18:03 ` Paul E. McKenney
2026-09-12 19:40 ` Alexei Starovoitov
2026-09-12 22:28 ` Paul E. McKenney
2026-09-12 23:59 ` Alexei Starovoitov
2026-09-13 3:07 ` Paul E. McKenney
2026-09-12 21:14 ` David Laight
2026-09-12 22:31 ` Paul E. McKenney
2026-09-13 11:28 ` David Laight
2026-09-13 18:20 ` Paul E. McKenney
2026-09-11 14:08 ` [PATCH RFC v2 09/15] arm64: ftrace: Maintain Tasks RCU trampoline nesting in ftrace_caller Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 10/15] bpf, arm64: Maintain Tasks RCU trampoline nesting in the BPF trampoline Josef Bacik
2026-09-11 14:08 ` Josef Bacik [this message]
2026-09-11 14:08 ` [PATCH RFC v2 12/15] rcutorture: Bracket Tasks RCU readers with trampoline nesting Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 13/15] rcu-tasks: Treat preemption outside trampolines as a quiescent state Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 14/15] rcu-tasks: Retire switched-out tasks with no trampoline nesting at scan time Josef Bacik
2026-09-11 14:08 ` [PATCH RFC v2 15/15] rcu-tasks: Kick running holdouts through the scheduler Josef Bacik
2026-09-11 18:46 ` Paul E. McKenney
2026-09-13 7:13 ` [PATCH RFC v2 00/15] rcu-tasks: let preemption outside trampolines be a quiescent state Yafang Shao
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=20260911-b4-rcu-tasks-preempt-qs-v2-11-eaaa61ed2da4@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