perf kmem: Fix memory leaks on error path and when skipping

Fix memory leaks on the error paths and skipped sample handling paths
in the perf kmem tool.

Ensure that all allocated GFP flags and thread references are properly freed and
released via thread__put() when skipping samples or encountering parsing failures,
preventing long-term memory usage leaks during large trace analyses.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andrew Jones <ajones@ventanamicro.com>
Cc: Anup Patel <anup@brainfault.org>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Blake Jones <blakejones@google.com>
Cc: Chen Ni <nichen@iscas.ac.cn>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Derek Foreman <derek.foreman@collabora.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Hrishikesh Suresh <hrishikesh123s@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Krzysztof Łopatowski <krzysztof.m.lopatowski@gmail.com>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quan Zhou <zhouquan@iscas.ac.cn>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Tianyou Li <tianyou.li@intel.com>
Cc: Yujie Liu <yujie.liu@intel.com>
Cc: tanze <tanze@kylinos.cn>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2026-05-20 12:05:31 -07:00 committed by Arnaldo Carvalho de Melo
parent 00b36b394c
commit b3ab668761

View File

@ -783,17 +783,21 @@ static int parse_gfp_flags(struct perf_sample *sample, unsigned int gfp_flags)
new = realloc(gfps, (nr_gfps + 1) * sizeof(*gfps));
if (new == NULL)
return -ENOMEM;
goto err_out;
gfps = new;
new += nr_gfps++;
new += nr_gfps;
new->flags = gfp_flags;
new->human_readable = strdup(str + 10);
if (!new->human_readable)
goto err_out;
new->compact_str = compact_gfp_flags(str + 10);
if (!new->human_readable || !new->compact_str)
return -ENOMEM;
if (!new->compact_str) {
free(new->human_readable);
goto err_out;
}
nr_gfps++;
qsort(gfps, nr_gfps, sizeof(*gfps), gfpcmp);
}
@ -802,6 +806,9 @@ static int parse_gfp_flags(struct perf_sample *sample, unsigned int gfp_flags)
trace_seq_destroy(&seq);
return 0;
err_out:
trace_seq_destroy(&seq);
return -ENOMEM;
}
static int evsel__process_page_alloc_event(struct perf_sample *sample)
@ -971,6 +978,7 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
}
if (perf_kmem__skip_sample(sample)) {
thread__put(thread);
return 0;
}