[PATCH 3/4] perf stat: Use evsel->core.cpus to iterate cpus in BPF cgroup counters

From: Namhyung Kim
Date: Fri Sep 16 2022 - 14:41:56 EST


If it mixes core and uncore events, each evsel would have different cpu map.
But it assumed they are same with evlist's all_cpus and accessed by the same
index. This resulted in a crash like below.

$ perf stat -a --bpf-counters --for-each_cgroup ^. -e cycles,imc/cas_count_read/ sleep 1
Segmentation fault

While it's not recommended to use uncore events for cgroup aggregation, it
should not crash.

Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
tools/perf/util/bpf_counter_cgroup.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
index 97c69a249c6e..3c2df7522f6f 100644
--- a/tools/perf/util/bpf_counter_cgroup.c
+++ b/tools/perf/util/bpf_counter_cgroup.c
@@ -115,14 +115,14 @@ static int bperf_load_program(struct evlist *evlist)
evsel->cgrp = NULL;

/* open single copy of the events w/o cgroup */
- err = evsel__open_per_cpu(evsel, evlist->core.all_cpus, -1);
+ err = evsel__open_per_cpu(evsel, evsel->core.cpus, -1);
if (err) {
pr_err("Failed to open first cgroup events\n");
goto out;
}

map_fd = bpf_map__fd(skel->maps.events);
- perf_cpu_map__for_each_cpu(cpu, j, evlist->core.all_cpus) {
+ perf_cpu_map__for_each_cpu(cpu, j, evsel->core.cpus) {
int fd = FD(evsel, j);
__u32 idx = evsel->core.idx * total_cpus + cpu.cpu;

@@ -269,7 +269,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
goto out;
}

- perf_cpu_map__for_each_cpu(cpu, i, evlist->core.all_cpus) {
+ perf_cpu_map__for_each_cpu(cpu, i, evsel->core.cpus) {
counts = perf_counts(evsel->counts, i, 0);
counts->val = values[cpu.cpu].counter;
counts->ena = values[cpu.cpu].enabled;
--
2.37.3.968.ga6b4b080e4-goog