[PATCH v2] tracing: Free tracer resources on instance creation failure
flat view
From: Baek Kyu, Kim <hidden>
Date: 2026-10-29 17:31:31
Also in:
lkml
Subsystem:
the rest, tracing · Maintainers:
Linus Torvalds, Steven Rostedt, Masami Hiramatsu
Creating a tracefs instance can allocate private tracer nodes, copied flags and option arrays before trace_array_create_dir() returns. If a later allocation fails, trace_array_create_systems() frees the trace_array without releasing those private allocations. The failed instance is never registered, so normal removal cannot reclaim them. Free the tracer nodes and option arrays when trace_array_create_dir() fails, then continue through the existing trace_array cleanup. Share the option array cleanup with normal instance removal. Earlier failures still use out_free_tr because the tracer list is not yet initialized there. Fixes: 428add559b69 ("tracing: Have tracer option be instance specific") Signed-off-by: Baek Kyu, Kim <redacted> --- Changes in v2: - Add the Fixes tag requested by Masami Hiramatsu. - Share option array cleanup between failed creation and normal removal. kernel/trace/trace.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 97a058623f94..faa90323809c 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c@@ -1456,6 +1456,13 @@ static void free_tracers(struct trace_array *tr) } } +static void free_tracer_options(struct trace_array *tr) +{ + for (int i = 0; i < tr->nr_topts; i++) + kfree(tr->topts[i].topts); + kfree(tr->topts); +} + /** * register_tracer - register a tracer with the ftrace system. * @type: the plugin for the tracer
@@ -8751,7 +8758,7 @@ trace_array_create_systems(const char *name, const char *systems, if (trace_instance_dir) { ret = trace_array_create_dir(tr); if (ret) - goto out_free_tr; + goto out_free_tracers; } else __trace_early_add_events(tr);
@@ -8761,6 +8768,9 @@ trace_array_create_systems(const char *name, const char *systems, return tr; + out_free_tracers: + free_tracers(tr); + free_tracer_options(tr); out_free_tr: ftrace_free_ftrace_ops(tr); free_trace_buffers(tr);
@@ -8914,10 +8924,7 @@ static int __remove_instance(struct trace_array *tr) if (tr->flags & TRACE_ARRAY_FL_VMALLOC) vfree((void *)tr->range_addr_start); - for (i = 0; i < tr->nr_topts; i++) { - kfree(tr->topts[i].topts); - } - kfree(tr->topts); + free_tracer_options(tr); free_cpumask_var(tr->pipe_cpumask); free_cpumask_var(tr->tracing_cpumask);