Re: [PATCH] tracing: Free tracer resources on instance creation failure
From: Google
Date: Sun Oct 25 2026 - 21:53:49 EST
Hi,
On Mon, 26 Oct 2026 01:52:50 +0900, Baek Kyu, Kim <pocj8ur4in@xxxxxxxxx> wrote:
> 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() jumps to
> out_free_tr and 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. Earlier
> failures still use out_free_tr because the tracer list is not yet
> initialized there.
>
> Signed-off-by: Baek Kyu, Kim <pocj8ur4in@xxxxxxxxx>
Please add the appropriate Fixes tag before the Signed-off-by:
Fixes: 428add559b69 ("tracing: Have tracer option be instance specific")
Commit 428add559b69 introduced per-instance private tracer nodes (tr->tracers),
flags, and option arrays, and called __update_tracer() from
trace_array_create_dir(). When trace_array_create_dir() fails, these allocated
resources were leaked because out_free_tr did not release them.
> ---
> Tested under ARM64 QEMU/KVM through tracefs instance mkdir with
> failslab targeting tracer flags, a later tracer node and option-array
> growth. The baseline retained one or four private allocations after
> the failed mkdir; the patched kernel retained none. Normal instance
> option read/write and removal also passed.
>
> kernel/trace/trace.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
[...]
> @@ -8761,6 +8761,11 @@ trace_array_create_systems(const char *name, const char *systems,
> return tr;
>
> + out_free_tracers:
> + free_tracers(tr);
> + for (int i = 0; i < tr->nr_topts; i++)
> + kfree(tr->topts[i].topts);
> + kfree(tr->topts);
Two minor nits:
- Please declare `int i;` at the beginning of trace_array_create_systems()
rather than inlining it inside `for (int i = 0; ...)`, matching the
prevailing style in trace.c (e.g. in __remove_instance()).
- The cleanup loop freeing tr->topts[i].topts and tr->topts exactly mirrors
the logic in __remove_instance(). Consider refactoring this into a small
helper function, e.g. `free_tracer_options(struct trace_array *tr)`,
shared by both trace_array_create_systems() and __remove_instance().
Thanks,
--
Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>