mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
perf evlist: Don't restrict uncore events to PMU CPUs
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 read from the PMU's cpumask sysfs attribute,
which lists the default CPU to open the event on per socket/die, not the
set of CPUs it can only be opened on. The user-requested CPU may override
these defaults, 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.
Add evsel->is_pmu_uncore, set once from pmu->is_uncore at parse time,
to skip the intersection for uncore PMUs. Core PMUs, and other
non-core PMUs such as software events, breakpoints, or tracepoints,
continue to be restricted to their PMU CPU map.
Fixes: 811082e4b6 ("perf parse-events: Support user CPUs mixed with threads/processes")
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Nia Su <nia.su@sifive.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
0d91c10f88
commit
aa9265d507
|
|
@ -79,8 +79,9 @@ 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) &&
|
||||
/* Ensure cpus only references valid PMU CPUs, except for uncore PMUs. */
|
||||
if (!evsel->is_pmu_uncore &&
|
||||
!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);
|
||||
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ struct perf_evsel {
|
|||
bool requires_cpu;
|
||||
/** Is the PMU for the event a core one? Effects the handling of own_cpus. */
|
||||
bool is_pmu_core;
|
||||
/** Is the PMU for the event an uncore one? */
|
||||
bool is_pmu_uncore;
|
||||
/** Does the evsel on read on the first CPU index such as tool time events? */
|
||||
bool reads_only_on_cpu_idx0;
|
||||
int idx;
|
||||
|
|
|
|||
|
|
@ -555,6 +555,7 @@ struct evsel *evsel__clone(struct evsel *orig)
|
|||
evsel->core.system_wide = orig->core.system_wide;
|
||||
evsel->core.requires_cpu = orig->core.requires_cpu;
|
||||
evsel->core.is_pmu_core = orig->core.is_pmu_core;
|
||||
evsel->core.is_pmu_uncore = orig->core.is_pmu_uncore;
|
||||
|
||||
if (orig->name) {
|
||||
evsel->name = strdup(orig->name);
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ __add_event(struct list_head *list, int *idx,
|
|||
evsel->core.pmu_cpus = pmu_cpus;
|
||||
evsel->core.requires_cpu = pmu ? pmu->is_uncore : false;
|
||||
evsel->core.is_pmu_core = is_pmu_core;
|
||||
evsel->core.is_pmu_uncore = pmu ? pmu->is_uncore : false;
|
||||
evsel->core.reads_only_on_cpu_idx0 = perf_pmu__reads_only_on_cpu_idx0(attr);
|
||||
evsel->pmu = pmu;
|
||||
evsel->alternate_hw_config = alternate_hw_config;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user