Skip to content

Commit b849156

Browse files
namhyungopsiff
authored andcommitted
perf sched: Fix memory leaks in 'perf sched latency'
[ Upstream commit e68b1c0098b959cb88afce5c93dd6a9324e6da78 ] The work_atoms should be freed after use. Add free_work_atoms() to make sure to release all. It should use list_splice_init() when merging atoms to prevent accessing invalid pointers. Fixes: b1ffe8f ("perf sched: Finish latency => atom rename and misc cleanups") Reviewed-by: Ian Rogers <[email protected]> Tested-by: Ian Rogers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Namhyung Kim <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit ffc3c00a0e835394112207c822d2f0721bb88a4a)
1 parent 2a37448 commit b849156

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

tools/perf/builtin-sched.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,21 @@ add_sched_in_event(struct work_atoms *atoms, u64 timestamp)
11161116
atoms->nb_atoms++;
11171117
}
11181118

1119+
static void free_work_atoms(struct work_atoms *atoms)
1120+
{
1121+
struct work_atom *atom, *tmp;
1122+
1123+
if (atoms == NULL)
1124+
return;
1125+
1126+
list_for_each_entry_safe(atom, tmp, &atoms->work_list, list) {
1127+
list_del(&atom->list);
1128+
free(atom);
1129+
}
1130+
thread__zput(atoms->thread);
1131+
free(atoms);
1132+
}
1133+
11191134
static int latency_switch_event(struct perf_sched *sched,
11201135
struct evsel *evsel,
11211136
struct perf_sample *sample,
@@ -3390,13 +3405,13 @@ static void __merge_work_atoms(struct rb_root_cached *root, struct work_atoms *d
33903405
this->total_runtime += data->total_runtime;
33913406
this->nb_atoms += data->nb_atoms;
33923407
this->total_lat += data->total_lat;
3393-
list_splice(&data->work_list, &this->work_list);
3408+
list_splice_init(&data->work_list, &this->work_list);
33943409
if (this->max_lat < data->max_lat) {
33953410
this->max_lat = data->max_lat;
33963411
this->max_lat_start = data->max_lat_start;
33973412
this->max_lat_end = data->max_lat_end;
33983413
}
3399-
zfree(&data);
3414+
free_work_atoms(data);
34003415
return;
34013416
}
34023417
}
@@ -3475,7 +3490,6 @@ static int perf_sched__lat(struct perf_sched *sched)
34753490
work_list = rb_entry(next, struct work_atoms, node);
34763491
output_lat_thread(sched, work_list);
34773492
next = rb_next(next);
3478-
thread__zput(work_list->thread);
34793493
}
34803494

34813495
printf(" -----------------------------------------------------------------------------------------------------------------\n");
@@ -3489,6 +3503,13 @@ static int perf_sched__lat(struct perf_sched *sched)
34893503

34903504
rc = 0;
34913505

3506+
while ((next = rb_first_cached(&sched->sorted_atom_root))) {
3507+
struct work_atoms *data;
3508+
3509+
data = rb_entry(next, struct work_atoms, node);
3510+
rb_erase_cached(next, &sched->sorted_atom_root);
3511+
free_work_atoms(data);
3512+
}
34923513
out_free_cpus_switch_event:
34933514
free_cpus_switch_event(sched);
34943515
return rc;

0 commit comments

Comments
 (0)