Commit 2a67955d authored by Ian Rogers's avatar Ian Rogers Committed by Namhyung Kim
Browse files

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: b91917c0 ("perf bpf_counter: Fix handling of cpumap fixing hybrid")
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
parent 6090e612
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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");
+6 −1
Original line number Diff line number Diff line
@@ -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);