Skip to content

Commit 81e9da6

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 b86fd2e61a2c6eb80b19ae407c7441c5a79cb0aa)
1 parent 372b463 commit 81e9da6

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
@@ -1125,6 +1125,21 @@ add_sched_in_event(struct work_atoms *atoms, u64 timestamp)
11251125
atoms->nb_atoms++;
11261126
}
11271127

1128+
static void free_work_atoms(struct work_atoms *atoms)
1129+
{
1130+
struct work_atom *atom, *tmp;
1131+
1132+
if (atoms == NULL)
1133+
return;
1134+
1135+
list_for_each_entry_safe(atom, tmp, &atoms->work_list, list) {
1136+
list_del(&atom->list);
1137+
free(atom);
1138+
}
1139+
thread__zput(atoms->thread);
1140+
free(atoms);
1141+
}
1142+
11281143
static int latency_switch_event(struct perf_sched *sched,
11291144
struct evsel *evsel,
11301145
struct perf_sample *sample,
@@ -3192,13 +3207,13 @@ static void __merge_work_atoms(struct rb_root_cached *root, struct work_atoms *d
31923207
this->total_runtime += data->total_runtime;
31933208
this->nb_atoms += data->nb_atoms;
31943209
this->total_lat += data->total_lat;
3195-
list_splice(&data->work_list, &this->work_list);
3210+
list_splice_init(&data->work_list, &this->work_list);
31963211
if (this->max_lat < data->max_lat) {
31973212
this->max_lat = data->max_lat;
31983213
this->max_lat_start = data->max_lat_start;
31993214
this->max_lat_end = data->max_lat_end;
32003215
}
3201-
zfree(&data);
3216+
free_work_atoms(data);
32023217
return;
32033218
}
32043219
}
@@ -3277,7 +3292,6 @@ static int perf_sched__lat(struct perf_sched *sched)
32773292
work_list = rb_entry(next, struct work_atoms, node);
32783293
output_lat_thread(sched, work_list);
32793294
next = rb_next(next);
3280-
thread__zput(work_list->thread);
32813295
}
32823296

32833297
printf(" -----------------------------------------------------------------------------------------------------------------\n");
@@ -3291,6 +3305,13 @@ static int perf_sched__lat(struct perf_sched *sched)
32913305

32923306
rc = 0;
32933307

3308+
while ((next = rb_first_cached(&sched->sorted_atom_root))) {
3309+
struct work_atoms *data;
3310+
3311+
data = rb_entry(next, struct work_atoms, node);
3312+
rb_erase_cached(next, &sched->sorted_atom_root);
3313+
free_work_atoms(data);
3314+
}
32943315
out_free_cpus_switch_event:
32953316
free_cpus_switch_event(sched);
32963317
return rc;

0 commit comments

Comments
 (0)