Skip to content

Commit 0878355

Browse files
Nikita Yushchenkorostedt
authored andcommitted
tracing/osnoise: Properly unhook events if start_per_cpu_kthreads() fails
If start_per_cpu_kthreads() called from osnoise_workload_start() returns error, event hooks are left in broken state: unhook_irq_events() called but unhook_thread_events() and unhook_softirq_events() not called, and trace_osnoise_callback_enabled flag not cleared. On the next tracer enable, hooks get not installed due to trace_osnoise_callback_enabled flag. And on the further tracer disable an attempt to remove non-installed hooks happened, hitting a WARN_ON_ONCE() in tracepoint_remove_func(). Fix the error path by adding the missing part of cleanup. While at this, introduce osnoise_unhook_events() to avoid code duplication between this error path and normal tracer disable. Link: https://lkml.kernel.org/r/[email protected] Cc: [email protected] Fixes: bce29ac ("trace: Add osnoise tracer") Acked-by: Daniel Bristot de Oliveira <[email protected]> Signed-off-by: Nikita Yushchenko <[email protected]> Signed-off-by: Steven Rostedt <[email protected]>
1 parent 6e1b4bd commit 0878355

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

kernel/trace/trace_osnoise.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,6 +2122,13 @@ static int osnoise_hook_events(void)
21222122
return -EINVAL;
21232123
}
21242124

2125+
static void osnoise_unhook_events(void)
2126+
{
2127+
unhook_thread_events();
2128+
unhook_softirq_events();
2129+
unhook_irq_events();
2130+
}
2131+
21252132
/*
21262133
* osnoise_workload_start - start the workload and hook to events
21272134
*/
@@ -2154,7 +2161,14 @@ static int osnoise_workload_start(void)
21542161

21552162
retval = start_per_cpu_kthreads();
21562163
if (retval) {
2157-
unhook_irq_events();
2164+
trace_osnoise_callback_enabled = false;
2165+
/*
2166+
* Make sure that ftrace_nmi_enter/exit() see
2167+
* trace_osnoise_callback_enabled as false before continuing.
2168+
*/
2169+
barrier();
2170+
2171+
osnoise_unhook_events();
21582172
return retval;
21592173
}
21602174

@@ -2185,9 +2199,7 @@ static void osnoise_workload_stop(void)
21852199

21862200
stop_per_cpu_kthreads();
21872201

2188-
unhook_irq_events();
2189-
unhook_softirq_events();
2190-
unhook_thread_events();
2202+
osnoise_unhook_events();
21912203
}
21922204

21932205
static void osnoise_tracer_start(struct trace_array *tr)

0 commit comments

Comments
 (0)