Skip to content

Commit 8ad9219

Browse files
Stephane Eranianacmel
authored andcommitted
perf stat: Fix memory corruption of xyarray when cpumask is used
This patch fixes a memory corruption problem with the xyarray when the evsel fds get closed at the end of the run_perf_stat() call. It could be triggered with: # perf stat -a -e power/energy-cores/ ls When cpumask are used by events (.e.g, RAPL or uncores) then the evsel fds are allocated based on the actual number of CPUs monitored. That number can be smaller than the total number of CPUs on the system. The problem arises at the end by perf stat closes the fds twice. When fds are closed, their entry in the xyarray are set to -1. The first close() on the evsel is made from __run_perf_stat() and it uses the actual number of CPUS for the event which is how the xyarray was allocated for. The second is from perf_evlist_close() but that one is on the total number of CPUs in the system, so it assume the xyarray was allocated to cover it. However it was not, and some writes corrupt memory. The fix is in perf_evlist_close() is to first try with the evsel->cpus if present, if not use the evlist->cpus. That fixes the problem. Signed-off-by: Stephane Eranian <eranian@google.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1389972846-6566-3-git-send-email-eranian@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent de256a4 commit 8ad9219

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

tools/perf/util/evlist.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,9 +1003,12 @@ void perf_evlist__close(struct perf_evlist *evlist)
10031003
struct perf_evsel *evsel;
10041004
int ncpus = cpu_map__nr(evlist->cpus);
10051005
int nthreads = thread_map__nr(evlist->threads);
1006+
int n;
10061007

1007-
evlist__for_each_reverse(evlist, evsel)
1008-
perf_evsel__close(evsel, ncpus, nthreads);
1008+
evlist__for_each_reverse(evlist, evsel) {
1009+
n = evsel->cpus ? evsel->cpus->nr : ncpus;
1010+
perf_evsel__close(evsel, n, nthreads);
1011+
}
10091012
}
10101013

10111014
int perf_evlist__open(struct perf_evlist *evlist)

0 commit comments

Comments
 (0)