From: "Jose Fernandez (Anthropic)" <jose.fernandez@linux.dev>
To: Mark Rutland <mark.rutland@arm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <nick.desaulniers+lkml@gmail.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, llvm@lists.linux.dev,
bpf@vger.kernel.org, Florent Revest <revest@chromium.org>,
Puranjay Mohan <puranjay@kernel.org>,
Xu Kuohai <xukuohai@huawei.com>
Subject: Re: [PATCH 0/2] arm64: ftrace: support DIRECT_CALLS without CALL_OPS
Date: Wed, 29 Jul 2026 14:02:52 +0000 [thread overview]
Message-ID: <amn7cBQ-cqs2XlKV@linux.dev> (raw)
In-Reply-To: <amjnf5gz0xP5PTSB@J2N7QTR9R3>
Hi Mark,
Thanks for the review, answers inline.
On Tue, Jul 28, 2026 at 06:31:43PM +0100, Mark Rutland wrote:
> So the big questions are:
>
> (1) How often is a direct call being made?
The workloads that want this are always-on. In our case a BPF LSM
security monitor covers file, exec and socket hooks, so it sits on
syscall-rate paths on busy machines, and fentry-based observability
behaves the same way. That is why we measured per-call dispatch cost
below.
> (2) Where does BPF allocate its direct call trampolines?
>
> From a skim of arch/arm64/mm/init.c, EXECMEM_BPF covers
> VMALLOC_START..VMALLOC_END, the vast majority of which is out-of-range
> for a BL from the core kernel or a module. So if EXECMEM_BPF is used,
> that's likely to be problematic. Hopefully I'm missing something such
> that BPF trampolines are almost always allocated in-range of a BL?
You're not missing anything. BPF trampolines come from bpf_prog_pack,
which allocates via EXECMEM_BPF, and we confirmed the consequence at
runtime. Across every boot and attach in the measurements below, the
trampoline landed in the same execmem slot while the kernel text moved
with KASLR, 50-90 TB out of BL range. Only a handful of boots, but
EXECMEM_BPF spans all of vmalloc and has no reason to land near
kernel text, so I would expect out-of-range to be the common case
here rather than the exception.
> When we originally implemented CALL_OPS and DIRECT_CALLS for arm64, the
> understanding was that we'd have many ops with direct calls. We believed
> that the ftrace_ops_list_func() penalty was so substantial that it
> wasn't worthwhile supporting direct calls in a configuration where
> bouncing through that would be common.
>
> If we need to support this configuration, then I strongly suspect we
> need to make other changes too in order for it to be worthwhile.
Agreed. One idea I would like your opinion on is an in-range
allocation preference for BPF trampolines, since execmem seems to
have the shape for it on arm64 already. EXECMEM_DEFAULT prefers the
module_direct_base window ("prefer to allocate within direct branch
range of the kernel") and falls back when that neighborhood is full,
while EXECMEM_BPF spans all of vmalloc with no preference. Giving
trampolines the same preference would need no new dispatch machinery,
and the measurements below suggest it recovers 93% of the gap to the
CALL_OPS baseline. Does that direction sound right to you, or is
there something in the CALL_OPS design that argues against it? If it
holds up I am happy to write it as a follow-up to this series.
> Following from the comment regarding EXECMEM_BPF above, it looks like
> both s390 and loongarch don't define EXECMEM_BPF, and only define
> EXECMEM_DEFAULT with a subsstantially limited range, which I suspect
> keeps their direct calls within range.
That matches our reading. Their limited EXECMEM_DEFAULT ranges keep
direct calls in range by construction, same idea as the above.
> Can you comment on how you've tested in-range vs out-of-range
> attachements here?
Reachability is decided per attach at patch time.
ftrace_find_callable_addr() picks the direct BL when the target is in
range and ftrace_caller when it is not. In our runs we read the live
trampoline and patch-site addresses from /proc/kallsyms and computed
the BL-range verdict for every attach, and every attach came out
out-of-range. So all of the original series validation was
out-of-range too, per the allocation behavior above.
To get numbers for the in-range side we forced it on a test rig
instead of writing the real change. A small bench-only patch (six
lines) makes arch_alloc_bpf_trampoline() allocate from
execmem_alloc(EXECMEM_MODULE_TEXT, ...) instead of bpf_prog_pack, and
the guest boots with nokaslr so the module window is always within
reach. From there the existing reach check does the rest and patches
the direct BL by itself. So the rig only tells us what in-range is
worth, the allocator preference above is what I would actually
implement.
> Have you made any performance measurements, or was this just functional
> enablement?
The original posting was functional enablement, so after your review
we measured the per-call cost. The rig is a KVM guest with 8 vcpus on
an arm64 Graviton metal host, 6.18.36 with this series, fentry on
__arm64_sys_getpid, 20M calls per run, per-call overhead taken as
traced minus untraced. Six passes across three fresh boots per
configuration, ranges below are min to max over those six passes.
CALL_OPS baseline (CFI off): 17.8-18.3 ns
series path, out-of-range, no other ops: 34.5-35.6 ns (~2.0x)
same, plus N unrelated ftrace_ops
(function tracer on vfs_read):
N=1 41 ns
N=4 53 ns
N=8 68 ns
N=16 98 ns
in-range trampoline (rig above): 18.7-19.4 ns (~1.2 ns more)
The extra-ops rows are the ftrace_ops_list_func() cost you were
worried about, a straight 3.9 ns per registered op, and paid
everywhere since the traced callsite never matches their filter. The
in-range trampoline closes 93% of the gap to baseline, though the
passes still sit a bit above, so not quite identical.
Thanks,
Jose
prev parent reply other threads:[~2026-07-29 14:03 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-09 5:19 [PATCH 0/2] arm64: ftrace: support DIRECT_CALLS without CALL_OPS Jose Fernandez (Anthropic)
2026-06-09 5:19 ` [PATCH 1/2] arm64: ftrace: prepare ftrace_modify_call() for use " Jose Fernandez (Anthropic)
2026-06-11 4:06 ` Xu Kuohai
2026-06-09 5:19 ` [PATCH 2/2] arm64: ftrace: allow DIRECT_CALLS " Jose Fernandez (Anthropic)
2026-06-11 4:06 ` Xu Kuohai
2026-06-09 9:50 ` [PATCH 0/2] arm64: ftrace: support " Puranjay Mohan
2026-06-10 4:42 ` Clayton Craft
2026-06-10 23:36 ` Nathan Chancellor
2026-07-10 14:07 ` Jose Fernandez (Anthropic)
2026-07-10 15:55 ` Steven Rostedt
2026-07-13 16:47 ` Mark Rutland
2026-07-22 21:39 ` Will Deacon
2026-07-28 17:31 ` Mark Rutland
2026-07-29 14:02 ` Jose Fernandez (Anthropic) [this message]
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=amn7cBQ-cqs2XlKV@linux.dev \
--to=jose.fernandez@linux.dev \
--cc=bpf@vger.kernel.org \
--cc=catalin.marinas@arm.com \
--cc=justinstitt@google.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mark.rutland@arm.com \
--cc=mhiramat@kernel.org \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=nick.desaulniers+lkml@gmail.com \
--cc=puranjay@kernel.org \
--cc=revest@chromium.org \
--cc=rostedt@goodmis.org \
--cc=will@kernel.org \
--cc=xukuohai@huawei.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;
as well as URLs for NNTP newsgroup(s).