perf stat: Use evsel->core.cpus to iterate cpus in BPF cgroup counters
authorNamhyung Kim <namhyung@kernel.org>
Fri, 16 Sep 2022 18:41:31 +0000 (11:41 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 21 Sep 2022 13:30:55 +0000 (10:30 -0300)
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@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20220916184132.1161506-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/bpf_counter_cgroup.c

index 97c69a249c6e4216923eb01a9f5156ac7b477719..3c2df7522f6fcbdc63a918a6d322cd2c3afbcf56 100644 (file)
@@ -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;