Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf stat: Fix handling of unsupported cgroup events when using BPF counters

When --for-each-cgroup option is used, it fails when any of events is
not supported and exits immediately. This is not how 'perf stat'
handles unsupported events.

Let's ignore the failure and proceed with others so that the output is
similar to when BPF counters are not used:

Before:

$ sudo ./perf stat -a --bpf-counters -e L1-icache-loads,L1-dcache-loads --for-each-cgroup system.slice,user.slice sleep 1
Failed to open first cgroup events
$

After it shows output similat to when --bpf-counters isn't specified:

$ sudo ./perf stat -a --bpf-counters -e L1-icache-loads,L1-dcache-loads --for-each-cgroup system.slice,user.slice sleep 1

Performance counter stats for 'system wide':

<not supported> L1-icache-loads system.slice
29,892,418 L1-dcache-loads system.slice
<not supported> L1-icache-loads user.slice
52,497,220 L1-dcache-loads user.slice
$

Fixes: 944138f048f7d759 ("perf stat: Enable BPF counter with --for-each-cgroup")
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
Link: https://lore.kernel.org/r/20230104064402.1551516-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
2d656b0f fb710dde

+3 -11
+3 -11
tools/perf/util/bpf_counter_cgroup.c
··· 116 116 117 117 /* open single copy of the events w/o cgroup */ 118 118 err = evsel__open_per_cpu(evsel, evsel->core.cpus, -1); 119 - if (err) { 120 - pr_err("Failed to open first cgroup events\n"); 121 - goto out; 122 - } 119 + if (err == 0) 120 + evsel->supported = true; 123 121 124 122 map_fd = bpf_map__fd(skel->maps.events); 125 123 perf_cpu_map__for_each_cpu(cpu, j, evsel->core.cpus) { 126 124 int fd = FD(evsel, j); 127 125 __u32 idx = evsel->core.idx * total_cpus + cpu.cpu; 128 126 129 - err = bpf_map_update_elem(map_fd, &idx, &fd, 130 - BPF_ANY); 131 - if (err < 0) { 132 - pr_err("Failed to update perf_event fd\n"); 133 - goto out; 134 - } 127 + bpf_map_update_elem(map_fd, &idx, &fd, BPF_ANY); 135 128 } 136 129 137 130 evsel->cgrp = leader_cgrp; 138 131 } 139 - evsel->supported = true; 140 132 141 133 if (evsel->cgrp == cgrp) 142 134 continue;