[PATCH v3] tracing: fgraph: fix the quadratic shadow stack walk
From: Vineet Gupta
Date: Thu Oct 01 2026 - 06:38:34 EST
alloc_retstack_tasklist() assigns a shadow stack to every thread when
fgraph is enabled. It did so FTRACE_RETSTACK_ALLOC_SIZE (32) tasks at a
time, and since for_each_process_thread() has no cursor, every sweep
restarted from init_task and re-walked the tasks already served, making
the ftrace_graph_active 0 -> 1 transition quadratic in the thread count.
On a 60-core Sapphire Rapids machine with 400000 idle threads it took
227 s, inside a single bpf() syscall for the kprobe_multi case.
Allocating inline with GFP_NOWAIT removes the batching: a single sweep
serves every task, 227 s -> 0.092 s.
v1: https://lore.kernel.org/all/20260922225526.1554758-1-vineet.gupta@xxxxxxxxx/
v2: https://lore.kernel.org/all/20260929005411.4105448-1-vineet.gupta@xxxxxxxxx/
Changes since v2:
- update the stale alloc_retstack_tasklist() comment, which still
described the old batch-of-32 behaviour (bot+bpf-ci)
Sashiko flagged the mix of goto-based cleanup and scoped_guard() in
this function. Peter and Andrii both considered it fine as is, so it
is unchanged:
https://lore.kernel.org/all/20260929080346.GR4120091@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
Changes since v1:
- replace both v1 patches with Peter's inline GFP_NOWAIT approach,
which removes the quadratic behaviour rather than dividing it by a
constant. With a single sweep there is no retry loop left, so the
v1 cond_resched() patch has nothing to attach to and is dropped.
- comment why returning from inside scoped_guard() skips the free
loop safely
Vineet Gupta (1):
tracing: fgraph: allocate shadow stacks inline with GFP_NOWAIT
kernel/trace/fgraph.c | 44 ++++++++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 15 deletions(-)
--
2.53.0-Meta