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 10/15] bpf, arm64: Maintain Tasks RCU trampoline nesting in the BPF trampoline
Date: Fri, 11 Sep 2026 14:08:48 +0000 [thread overview]
Message-ID: <20260911-b4-rcu-tasks-preempt-qs-v2-10-eaaa61ed2da4@toxicpanda.com> (raw)
In-Reply-To: <20260911-b4-rcu-tasks-preempt-qs-v2-0-eaaa61ed2da4@toxicpanda.com>
Same scheme as x86: emit "mrs x10, sp_el0; ldr/add|sub/str w11" to bump
current->rcu_tramp_nesting after the callee-saved registers are stored
and to drop it before they are restored, and release it around the call
to the original function, which im->pcref protects and which must not
pin a Tasks RCU grace period. x10/x11 are scratch at every emission
point; the fmod_ret cbnz target lies after the decrement/increment pair
around the original call, and the ip_after_call nop follows the
re-increment, so the count is balanced on every path. BUILD_BUG_ON
guards the LDR/STR immediate range for the task_struct offset.
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
arch/arm64/net/bpf_jit_comp.c | 46 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index c18e005a41db..5c9a7bde5cc9 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -2591,6 +2591,34 @@ static void emit_arena_arg_conv(struct jit_ctx *ctx, u8 dst, u8 src, bool nullab
emit(A64_SUB(0, dst, src, base_lo), ctx);
}
+/*
+ * Tasks RCU trampoline nesting, see rcu_tasks_trampoline_enter().
+ *
+ * mrs x10, sp_el0
+ * ldr w11, [x10, #offsetof(struct task_struct, rcu_tramp_nesting)]
+ * add/sub w11, w11, #1
+ * str w11, [x10, #...]
+ *
+ * x10/x11 are scratch in the trampoline at every point this is emitted.
+ */
+static void emit_rcu_tasks_tramp_nesting(struct jit_ctx *ctx, bool enter)
+{
+#ifdef CONFIG_TASKS_RCU
+ const int off = offsetof(struct task_struct, rcu_tramp_nesting);
+ const u8 tsk = A64_R(10), cnt = A64_R(11);
+
+ BUILD_BUG_ON(off & 3 || off >= SZ_16K); /* LDR/STR (imm12, scaled) */
+
+ emit(A64_MRS_SP_EL0(tsk), ctx);
+ emit(A64_LDR32I(cnt, tsk, off), ctx);
+ if (enter)
+ emit(A64_ADD_I(0, cnt, cnt, 1), ctx);
+ else
+ emit(A64_SUB_I(0, cnt, cnt, 1), ctx);
+ emit(A64_STR32I(cnt, tsk, off), ctx);
+#endif
+}
+
static void save_args(struct jit_ctx *ctx, int bargs_off, int oargs_off,
const struct btf_func_model *m, const struct arg_aux *a,
bool for_call_origin, bool is_struct_ops, u64 arena_base)
@@ -2854,6 +2882,13 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
emit(A64_STR64I(A64_R(19), A64_SP, regs_off), ctx);
emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx);
+ /*
+ * From here until the matching decrement in the epilogue, a preemption
+ * of this task is not a Tasks RCU quiescent state. The instructions
+ * above this point are covered by the irq-exit IP check.
+ */
+ emit_rcu_tasks_tramp_nesting(ctx, true);
+
if (flags & BPF_TRAMP_F_CALL_ORIG) {
/* for the first pass, assume the worst case */
if (!ctx->image)
@@ -2898,12 +2933,20 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
if (flags & BPF_TRAMP_F_CALL_ORIG) {
/* the original func takes kernel addresses, never converted ones */
save_args(ctx, bargs_off, oargs_off, m, a, true, is_struct_ops, 0);
+ /*
+ * The original function may run for a long time without
+ * sleeping; do not let it pin a Tasks RCU grace period. The
+ * trampoline frame above it is held by im->pcref
+ * (__bpf_tramp_enter()), not by Tasks RCU, across the call.
+ */
+ emit_rcu_tasks_tramp_nesting(ctx, false);
/* call original func */
emit(A64_LDR64I(A64_R(10), A64_SP, retaddr_off), ctx);
emit(A64_ADR(A64_LR, AARCH64_INSN_SIZE * 2), ctx);
emit(A64_RET(A64_R(10)), ctx);
/* store return value */
emit(A64_STR64I(A64_R(0), A64_SP, retval_off), ctx);
+ emit_rcu_tasks_tramp_nesting(ctx, true);
/* reserve a nop for bpf_tramp_image_put */
im->ip_after_call = ctx->ro_image + ctx->idx;
emit(A64_NOP, ctx);
@@ -2945,6 +2988,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
if (flags & BPF_TRAMP_F_RESTORE_REGS)
restore_args(ctx, bargs_off, a->regs_for_args);
+ /* Remaining instructions are covered by the irq-exit IP check. */
+ emit_rcu_tasks_tramp_nesting(ctx, false);
+
/* restore callee saved register x19 and x20 */
emit(A64_LDR64I(A64_R(19), A64_SP, regs_off), ctx);
emit(A64_LDR64I(A64_R(20), A64_SP, regs_off + 8), ctx);
--
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 ` Josef Bacik [this message]
2026-09-11 14:08 ` [PATCH RFC v2 11/15] samples: ftrace: Maintain Tasks RCU trampoline nesting in direct-call trampolines Josef Bacik
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-10-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