summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/lib/perf/evlist.c25
-rw-r--r--tools/lib/perf/include/internal/evsel.h6
2 files changed, 23 insertions, 8 deletions
diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c
index 81e8b5fcd8ba..b8b066d0dc5e 100644
--- a/tools/lib/perf/evlist.c
+++ b/tools/lib/perf/evlist.c
@@ -36,18 +36,33 @@ void perf_evlist__init(struct perf_evlist *evlist)
static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
struct perf_evsel *evsel)
{
- /*
- * We already have cpus for evsel (via PMU sysfs) so
- * keep it, if there's no target cpu list defined.
- */
if (evsel->system_wide) {
+ /* System wide: set the cpu map of the evsel to all online CPUs. */
perf_cpu_map__put(evsel->cpus);
evsel->cpus = perf_cpu_map__new(NULL);
+ } else if (evlist->has_user_cpus && evsel->is_pmu_core) {
+ /*
+ * User requested CPUs on a core PMU, ensure the requested CPUs
+ * are valid by intersecting with those of the PMU.
+ */
+ perf_cpu_map__put(evsel->cpus);
+ evsel->cpus = perf_cpu_map__intersect(evlist->user_requested_cpus, evsel->own_cpus);
} else if (!evsel->own_cpus || evlist->has_user_cpus ||
- (!evsel->requires_cpu && perf_cpu_map__empty(evlist->user_requested_cpus))) {
+ (!evsel->requires_cpu && perf_cpu_map__has_any_cpu(evlist->user_requested_cpus))) {
+ /*
+ * The PMU didn't specify a default cpu map, this isn't a core
+ * event and the user requested CPUs or the evlist user
+ * requested CPUs have the "any CPU" (aka dummy) CPU value. In
+ * which case use the user requested CPUs rather than the PMU
+ * ones.
+ */
perf_cpu_map__put(evsel->cpus);
evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus);
} else if (evsel->cpus != evsel->own_cpus) {
+ /*
+ * No user requested cpu map but the PMU cpu map doesn't match
+ * the evsel's. Reset it back to the PMU cpu map.
+ */
perf_cpu_map__put(evsel->cpus);
evsel->cpus = perf_cpu_map__get(evsel->own_cpus);
}
diff --git a/tools/lib/perf/include/internal/evsel.h b/tools/lib/perf/include/internal/evsel.h
index 4d6f2a032f45..5cd220a61962 100644
--- a/tools/lib/perf/include/internal/evsel.h
+++ b/tools/lib/perf/include/internal/evsel.h
@@ -62,9 +62,9 @@ struct perf_evsel {
int nr_members;
/*
* system_wide is for events that need to be on every CPU, irrespective
- * of user requested CPUs or threads. Map propagation will set cpus to
- * this event's own_cpus, whereby they will contribute to evlist
- * all_cpus.
+ * of user requested CPUs or threads. Tha main example of this is the
+ * dummy event. Map propagation will set cpus for this event to all CPUs
+ * as software PMU events like dummy, have a CPU map that is empty.
*/
bool system_wide;
/*