perf bpf_counter: Fix opening of "any"(-1) CPU events

The bperf BPF counter code doesn't handle "any"(-1) CPU events, always
wanting to aggregate a count against a CPU, which avoids the need for
atomics so let's not change that. Force evsels used for BPF counters
to require a CPU when not in system-wide mode so that the "any"(-1)
value isn't used during map propagation and evsel's CPU map matches
that of the PMU.

Fixes: b91917c0c6 ("perf bpf_counter: Fix handling of cpumap fixing hybrid")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ian Rogers 2025-10-09 06:29:11 -07:00 committed by Namhyung Kim
parent 6090e612cf
commit 2a67955de1
2 changed files with 19 additions and 1 deletions

View File

@ -2542,6 +2542,7 @@ int cmd_stat(int argc, const char **argv)
unsigned int interval, timeout;
const char * const stat_subcommands[] = { "record", "report" };
char errbuf[BUFSIZ];
struct evsel *counter;
setlocale(LC_ALL, "");
@ -2799,6 +2800,18 @@ int cmd_stat(int argc, const char **argv)
evlist__warn_user_requested_cpus(evsel_list, target.cpu_list);
evlist__for_each_entry(evsel_list, counter) {
/*
* Setup BPF counters to require CPUs as any(-1) isn't
* supported. evlist__create_maps below will propagate this
* information to the evsels. Note, evsel__is_bperf isn't yet
* set up, and this change must happen early, so directly use
* the bpf_counter variable and target information.
*/
if ((counter->bpf_counter || target.use_bpf) && !target__has_cpu(&target))
counter->core.requires_cpu = true;
}
if (evlist__create_maps(evsel_list, &target) < 0) {
if (target__has_task(&target)) {
pr_err("Problems finding threads of monitor\n");

View File

@ -460,6 +460,7 @@ static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd,
struct bperf_leader_bpf *skel = bperf_leader_bpf__open();
int link_fd, diff_map_fd, err;
struct bpf_link *link = NULL;
struct perf_thread_map *threads;
if (!skel) {
pr_err("Failed to open leader skeleton\n");
@ -495,7 +496,11 @@ static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd,
* following evsel__open_per_cpu call
*/
evsel->leader_skel = skel;
evsel__open(evsel, evsel->core.cpus, evsel->core.threads);
assert(!perf_cpu_map__has_any_cpu_or_is_empty(evsel->core.cpus));
/* Always open system wide. */
threads = thread_map__new_by_tid(-1);
evsel__open(evsel, evsel->core.cpus, threads);
perf_thread_map__put(threads);
out:
bperf_leader_bpf__destroy(skel);