summaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2026-05-19 08:27:15 -0700
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-05-25 16:46:17 -0300
commit65bd18199ad5358f7c879dc69b4de3671b33e62e (patch)
treebca80385c99402c65295a5e7f2a014fcfbeac5f3 /tools/perf
parent7378b6656aa46fda56f2743d5a7c1f619c2f6f9b (diff)
perf stat: Propagate supported flag to follower cgroup BPF events
When using BPF counters with cgroups, follower events (for cgroups other than the first one) are not opened. Because they are not opened, their `supported` flag was left as `false`. During metric calculation, `prepare_metric` checks if the event is supported. If it is not supported (like the follower events), it explicitly sets the value to `NAN`, which eventually causes the metric to be reported as `nan %`. Fix this by propagating the `supported` flag from the "leader" events (the ones opened for the first cgroup) to the "follower" events. Also add a validation check to `bperf_load_program` to ensure `nr_cgroups` is not zero and the number of events is a multiple of `nr_cgroups`, preventing a potential division-by-zero (SIGFPE) exception when `num_events` evaluates to 0 (e.g., with a trailing comma in cgroups list). Reported-by: Svilen Kanev <skanev@google.com> Assisted-by: Antigravity:gemini-3-flash Signed-off-by: Ian Rogers <irogers@google.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/bpf_counter_cgroup.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
index 519fee3dc3d0..e1ce5aa3b957 100644
--- a/tools/perf/util/bpf_counter_cgroup.c
+++ b/tools/perf/util/bpf_counter_cgroup.c
@@ -104,6 +104,11 @@ static int bperf_load_program(struct evlist *evlist)
set_max_rlimit();
+ if (nr_cgroups == 0 || evlist->core.nr_entries % nr_cgroups != 0) {
+ pr_err("Invalid cgroup or event count\n");
+ return -EINVAL;
+ }
+
test_max_events_program_load();
skel = bperf_cgroup_bpf__open();
@@ -187,6 +192,21 @@ static int bperf_load_program(struct evlist *evlist)
}
/*
+ * Propagate supported flag from leaders to followers. Follower events
+ * are not opened, so their supported flag remains false.
+ */
+ {
+ struct evsel *leader;
+ int num_events = evlist->core.nr_entries / nr_cgroups;
+
+ evlist__for_each_entry(evlist, evsel) {
+ leader = evlist__find_evsel(evlist, evsel->core.idx % num_events);
+ if (leader)
+ evsel->supported = leader->supported;
+ }
+ }
+
+ /*
* bperf uses BPF_PROG_TEST_RUN to get accurate reading. Check
* whether the kernel support it
*/