Skip to content

Commit cc252bb

Browse files
committed
fgraph: Still initialize idle shadow stacks when starting
A bug was discovered where the idle shadow stacks were not initialized for offline CPUs when starting function graph tracer, and when they came online they were not traced due to the missing shadow stack. To fix this, the idle task shadow stack initialization was moved to using the CPU hotplug callbacks. But it removed the initialization when the function graph was enabled. The problem here is that the hotplug callbacks are called when the CPUs come online, but the idle shadow stack initialization only happens if function graph is currently active. This caused the online CPUs to not get their shadow stack initialized. The idle shadow stack initialization still needs to be done when the function graph is registered, as they will not be allocated if function graph is not registered. Cc: [email protected] Cc: Masami Hiramatsu <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Link: https://lore.kernel.org/[email protected] Fixes: 2c02f73 ("fgraph: Use CPU hotplug mechanism to initialize idle shadow stacks") Reported-by: Linus Walleij <[email protected]> Tested-by: Linus Walleij <[email protected]> Closes: https://lore.kernel.org/all/CACRpkdaTBrHwRbbrphVy-=SeDz6MSsXhTKypOtLrTQ+DgGAOcQ@mail.gmail.com/ Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 78d4f34 commit cc252bb

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

kernel/trace/fgraph.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1215,14 +1215,20 @@ void fgraph_update_pid_func(void)
12151215
static int start_graph_tracing(void)
12161216
{
12171217
unsigned long **ret_stack_list;
1218-
int ret;
1218+
int ret, cpu;
12191219

12201220
ret_stack_list = kcalloc(FTRACE_RETSTACK_ALLOC_SIZE,
12211221
sizeof(*ret_stack_list), GFP_KERNEL);
12221222

12231223
if (!ret_stack_list)
12241224
return -ENOMEM;
12251225

1226+
/* The cpu_boot init_task->ret_stack will never be freed */
1227+
for_each_online_cpu(cpu) {
1228+
if (!idle_task(cpu)->ret_stack)
1229+
ftrace_graph_init_idle_task(idle_task(cpu), cpu);
1230+
}
1231+
12261232
do {
12271233
ret = alloc_retstack_tasklist(ret_stack_list);
12281234
} while (ret == -EAGAIN);

0 commit comments

Comments
 (0)