[PATCH v4 14/21] perf test attr: Leave out the events of the other core PMUs

From: Arnaldo Carvalho de Melo

Date: Fri Oct 16 2026 - 17:24:06 EST


From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

On a hybrid machine the default stat metrics are opened on each core PMU,
and the events of the other one have their own encodings: on an i7-14700K
cpu_atom (type 10) opens UOPS_RETIRED.ALL, config 194, which the
expectations, written for cpu_core (type 4), don't name:

expected type=4, got 10
expected config=209|391, got 194

The test already masks the core PMU type out of 'config' for the legacy
events, but raw events keep their type and encoding, so leave out the
events of the core PMUs no expectation names, like the dummy tracking
event. Core PMUs are found as perf finds them: 'cpu' or 'cpum_cf', or a
PMU with a 'cpus' file in sysfs. Nothing is left out unless an
expectation names a core PMU, so single core PMU machines and the tests
with only legacy expectations are not affected.

Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/tests/shell/lib/attr.py | 39 ++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)

diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/lib/attr.py
index 47a09f00000ff762..d485a491c717c96c 100644
--- a/tools/perf/tests/shell/lib/attr.py
+++ b/tools/perf/tests/shell/lib/attr.py
@@ -563,6 +563,44 @@ class Test(object):
for event in self.result.values():
event.tracking_moved_to_dummy = moved

+ def drop_other_core_pmu_events(self, devices='/sys/bus/event_source/devices'):
+ """
+ Leave out the events of the other core PMUs, which have their own
+ encodings, when the expectations name one of the core PMUs.
+ """
+ asked = set()
+ for event in self.expect.values():
+ types = event.get('type', '').split('|')
+ if '*' in types:
+ return
+ asked.update(types)
+
+ try:
+ names = os.listdir(devices)
+ except OSError:
+ return
+
+ core = set()
+ for name in names:
+ path = os.path.join(devices, name)
+ has_cpus = os.path.exists(os.path.join(path, 'cpus'))
+ if name not in ('cpu', 'cpum_cf') and not has_cpus:
+ continue
+ try:
+ with open(os.path.join(path, 'type'), encoding='utf-8') as f:
+ core.add(f.read().strip())
+ except OSError:
+ pass
+
+ if not core & asked:
+ return
+
+ others = core - asked
+ for name, event in list(self.result.items()):
+ if event.get('type') in others:
+ log.debug(" dropping other core PMU event [%s]", name)
+ del self.result[name]
+
def compare(self, expect, result, strict_groups=True):
match = {}

@@ -645,6 +683,7 @@ class Test(object):
event.recorded = True

self.drop_dummy_tracking_events()
+ self.drop_other_core_pmu_events()

# resolve group_fd to event names
self.resolve_groups(self.expect)
--
2.55.0