perf sched: Fix memory leaks in 'perf sched map'

[ Upstream commit dc3a80c988 ]

It maintains per-cpu pointers for the current thread but it doesn't
release the refcounts.

Fixes: 5e89527869 ("perf sched: Move curr_thread initialization to perf_sched__map()")
Reviewed-by: Ian Rogers <irogers@google.com>
Tested-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250703014942.1369397-4-namhyung@kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Namhyung Kim 2025-07-02 18:49:37 -07:00 committed by Greg Kroah-Hartman
parent 4b3ab5f363
commit 31a549b3a2

View File

@ -1639,6 +1639,7 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
const char *color = PERF_COLOR_NORMAL;
char stimestamp[32];
const char *str;
int ret = -1;
BUG_ON(this_cpu.cpu >= MAX_CPUS || this_cpu.cpu < 0);
@ -1669,17 +1670,20 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
sched_in = map__findnew_thread(sched, machine, -1, next_pid);
sched_out = map__findnew_thread(sched, machine, -1, prev_pid);
if (sched_in == NULL || sched_out == NULL)
return -1;
goto out;
tr = thread__get_runtime(sched_in);
if (tr == NULL) {
thread__put(sched_in);
return -1;
}
if (tr == NULL)
goto out;
thread__put(sched->curr_thread[this_cpu.cpu]);
thread__put(sched->curr_out_thread[this_cpu.cpu]);
sched->curr_thread[this_cpu.cpu] = thread__get(sched_in);
sched->curr_out_thread[this_cpu.cpu] = thread__get(sched_out);
ret = 0;
str = thread__comm_str(sched_in);
new_shortname = 0;
if (!tr->shortname[0]) {
@ -1774,12 +1778,10 @@ sched_out:
color_fprintf(stdout, color, "\n");
out:
if (sched->map.task_name)
thread__put(sched_out);
thread__put(sched_out);
thread__put(sched_in);
return 0;
return ret;
}
static int process_sched_switch_event(const struct perf_tool *tool,
@ -3546,10 +3548,10 @@ static int perf_sched__map(struct perf_sched *sched)
sched->curr_out_thread = calloc(MAX_CPUS, sizeof(*(sched->curr_out_thread)));
if (!sched->curr_out_thread)
return rc;
goto out_free_curr_thread;
if (setup_cpus_switch_event(sched))
goto out_free_curr_thread;
goto out_free_curr_out_thread;
if (setup_map_cpus(sched))
goto out_free_cpus_switch_event;
@ -3580,7 +3582,14 @@ out_put_map_cpus:
out_free_cpus_switch_event:
free_cpus_switch_event(sched);
out_free_curr_out_thread:
for (int i = 0; i < MAX_CPUS; i++)
thread__put(sched->curr_out_thread[i]);
zfree(&sched->curr_out_thread);
out_free_curr_thread:
for (int i = 0; i < MAX_CPUS; i++)
thread__put(sched->curr_thread[i]);
zfree(&sched->curr_thread);
return rc;
}