[PATCH] perf evlist: don't restrict uncore events to PMU CPUs
From: Nia Su
Date: Fri Sep 04 2026 - 10:21:37 EST
The PMU CPU map has different semantics for core and uncore PMUs.
For core PMUs, pmu_cpus contains the CPUs on which the event can be
opened. Intersect the user-requested CPU map with the PMU CPU map to
reject CPUs unsupported by the PMU.
For uncore PMUs, pmu_cpus is just the default CPU to open the event on,
not the set of CPUs it can only be opened on. The user-requested CPU may
override the default and be used directly, and the driver can redirect
the event to the appropriate control CPU.
Currently, __perf_evlist__propagate_maps() intersects the user-requested
CPU map with pmu_cpus for all PMUs. If the user-requested CPU is not in
pmu_cpus, the intersection becomes empty and the evsel is removed before
perf_event_open() is called.
Skip the intersection when evsel->requires_cpu is true, which is set for
uncore PMUs. is_pmu_core is also false for other non-core PMUs, so
gating on it would have loosened this check for them too. Core PMUs
continue to be restricted to their PMU CPU map.
requires_cpu can also be set for BPF counters regardless of PMU type,
but only when has_user_cpus is false, so this guard has no effect there
today.
Fixes: 811082e4b668 ("perf parse-events: Support user CPUs mixed with threads/processes")
Assisted-by: Claude Sonnet 5
Signed-off-by: Nia Su <nia.su@xxxxxxxxxx>
---
tools/lib/perf/evlist.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c
index 1f210dadd666ff818a23712ab95acaa659ccf8dc..a1064175f12ba655a9f7fe42e7c7e4c49ae60423 100644
--- a/tools/lib/perf/evlist.c
+++ b/tools/lib/perf/evlist.c
@@ -80,7 +80,8 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
}
/* Ensure cpus only references valid PMU CPUs. */
- if (!perf_cpu_map__has_any_cpu(evsel->cpus) &&
+ if (!evsel->requires_cpu &&
+ !perf_cpu_map__has_any_cpu(evsel->cpus) &&
!perf_cpu_map__is_subset(evsel->pmu_cpus, evsel->cpus)) {
struct perf_cpu_map *tmp = perf_cpu_map__intersect(evsel->pmu_cpus, evsel->cpus);
---
base-commit: 73e3f0710014fe6d4ed98cfc02292f6121db7558
change-id: 20260904-perf-evlist-uncore-cpu-b4-418af0f17c80
--