mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
perf evlist: Propagate user CPU maps intersecting core PMU maps
The CPU map for a non-core PMU gives a default CPU value for perf_event_open. For core PMUs the CPU map lists all CPUs the evsel may be opened on. If there are >1 core PMU, the CPU maps will list the CPUs for that core PMU, but the user_requested_cpus may contain CPUs that are invalid for the PMU and cause perf_event_open to fail. To avoid this, when propagating the CPU map for core PMUs intersect it with the CPU map of the PMU (the evsel's "own_cpus"). Add comments to __perf_evlist__propagate_maps to explain its somewhat complex behavior. Fix the related comments for system_wide in struct perf_evsel. Reviewed-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ali Saidi <alisaidi@amazon.com> Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Huacai Chen <chenhuacai@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jing Zhang <renyu.zj@linux.alibaba.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kang Minchul <tegongkang@gmail.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mike Leach <mike.leach@linaro.org> Cc: Ming Wang <wangming01@loongson.cn> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Rob Herring <robh@kernel.org> Cc: Sandipan Das <sandipan.das@amd.com> Cc: Sean Christopherson <seanjc@google.com> Cc: Suzuki Poulouse <suzuki.poulose@arm.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Will Deacon <will@kernel.org> Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com> Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230527072210.2900565-9-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
a0c41caeba
commit
ef91871c96
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user