From: Ian Rogers <irogers@google.com>
To: Adrian Hunter <adrian.hunter@intel.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Benjamin Gray <bgray@linux.ibm.com>,
Caleb Biggers <caleb.biggers@intel.com>,
Edward Baker <edward.baker@intel.com>,
Ian Rogers <irogers@google.com>, Ingo Molnar <mingo@redhat.com>,
James Clark <james.clark@linaro.org>,
Jing Zhang <renyu.zj@linux.alibaba.com>,
Jiri Olsa <jolsa@kernel.org>,
John Garry <john.g.garry@oracle.com>, Leo Yan <leo.yan@arm.com>,
Namhyung Kim <namhyung@kernel.org>,
Perry Taylor <perry.taylor@intel.com>,
Peter Zijlstra <peterz@infradead.org>,
Sandipan Das <sandipan.das@amd.com>,
Thomas Falcon <thomas.falcon@intel.com>,
Weilin Wang <weilin.wang@intel.com>, Xu Yang <xu.yang_2@nxp.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: [PATCH v11 02/35] perf jevents: Add load event json to verify and allow fallbacks
Date: Tue, 27 Jan 2026 10:44:33 -0800 [thread overview]
Message-ID: <20260127184506.3059493-3-irogers@google.com> (raw)
In-Reply-To: <20260127184506.3059493-1-irogers@google.com>
Add a LoadEvents function that loads all event json files in a
directory. In the Event constructor ensure all events are defined in
the event json except for legacy events like "cycles". If the initial
event isn't found then legacy_event1 is used, and if that isn't found
legacy_event2 is used. This allows a single Event to have multiple
event names as models will often rename the same event over time. If
the event doesn't exist an exception is raised.
So that references to metrics can be added, add the MetricRef
class. This doesn't validate as an event name and so provides an
escape hatch for metrics to refer to each other.
Tested-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/pmu-events/Build | 12 ++--
tools/perf/pmu-events/amd_metrics.py | 7 ++-
tools/perf/pmu-events/arm64_metrics.py | 7 ++-
tools/perf/pmu-events/intel_metrics.py | 7 ++-
tools/perf/pmu-events/metric.py | 83 +++++++++++++++++++++++++-
5 files changed, 101 insertions(+), 15 deletions(-)
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index 3f2b26e5c6d5..4878d922a732 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -53,11 +53,11 @@ ZEN_METRICGROUPS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metricgroups.json)
$(ZEN_METRICS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS)
$(call rule_mkdir)
- $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) arch > $@
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@
$(ZEN_METRICGROUPS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS)
$(call rule_mkdir)
- $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) arch > $@
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@
# Generate ARM Json
ARMS = $(shell ls -d pmu-events/arch/arm64/arm/*|grep -v cmn)
@@ -66,11 +66,11 @@ ARM_METRICGROUPS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metricgroups.json)
$(ARM_METRICS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS)
$(call rule_mkdir)
- $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) arch > $@
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@
$(ARM_METRICGROUPS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS)
$(call rule_mkdir)
- $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) arch > $@
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@
# Generate Intel Json
INTELS = $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv)
@@ -79,11 +79,11 @@ INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json
$(INTEL_METRICS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS)
$(call rule_mkdir)
- $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) arch > $@
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@
$(INTEL_METRICGROUPS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS)
$(call rule_mkdir)
- $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) arch > $@
+ $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@
GEN_JSON = $(patsubst %,$(OUTPUT)%,$(JSON)) \
$(LEGACY_CACHE_JSON) \
diff --git a/tools/perf/pmu-events/amd_metrics.py b/tools/perf/pmu-events/amd_metrics.py
index 5f44687d8d20..bc91d9c120fa 100755
--- a/tools/perf/pmu-events/amd_metrics.py
+++ b/tools/perf/pmu-events/amd_metrics.py
@@ -2,8 +2,8 @@
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
import argparse
import os
-from metric import (
- JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, MetricGroup)
+from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents,
+ MetricGroup)
# Global command line arguments.
_args = None
@@ -30,6 +30,9 @@ def main() -> None:
)
_args = parser.parse_args()
+ directory = f"{_args.events_path}/x86/{_args.model}/"
+ LoadEvents(directory)
+
all_metrics = MetricGroup("", [])
if _args.metricgroups:
diff --git a/tools/perf/pmu-events/arm64_metrics.py b/tools/perf/pmu-events/arm64_metrics.py
index 204b3b08c680..ac717ca3513a 100755
--- a/tools/perf/pmu-events/arm64_metrics.py
+++ b/tools/perf/pmu-events/arm64_metrics.py
@@ -2,8 +2,8 @@
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
import argparse
import os
-from metric import (
- JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, MetricGroup)
+from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents,
+ MetricGroup)
# Global command line arguments.
_args = None
@@ -31,6 +31,9 @@ def main() -> None:
)
_args = parser.parse_args()
+ directory = f"{_args.events_path}/arm64/{_args.vendor}/{_args.model}/"
+ LoadEvents(directory)
+
all_metrics = MetricGroup("", [])
if _args.metricgroups:
diff --git a/tools/perf/pmu-events/intel_metrics.py b/tools/perf/pmu-events/intel_metrics.py
index 65ada006d05a..b287ef115193 100755
--- a/tools/perf/pmu-events/intel_metrics.py
+++ b/tools/perf/pmu-events/intel_metrics.py
@@ -2,8 +2,8 @@
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
import argparse
import os
-from metric import (
- JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, MetricGroup)
+from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents,
+ MetricGroup)
# Global command line arguments.
_args = None
@@ -30,6 +30,9 @@ def main() -> None:
)
_args = parser.parse_args()
+ directory = f"{_args.events_path}/x86/{_args.model}/"
+ LoadEvents(directory)
+
all_metrics = MetricGroup("", [])
if _args.metricgroups:
diff --git a/tools/perf/pmu-events/metric.py b/tools/perf/pmu-events/metric.py
index dd8fd06940e6..e33e163b2815 100644
--- a/tools/perf/pmu-events/metric.py
+++ b/tools/perf/pmu-events/metric.py
@@ -3,10 +3,56 @@
import ast
import decimal
import json
+import os
import re
from enum import Enum
from typing import Dict, List, Optional, Set, Tuple, Union
+all_events = set()
+
+def LoadEvents(directory: str) -> None:
+ """Populate a global set of all known events for the purpose of validating Event names"""
+ global all_events
+ all_events = {
+ "context\\-switches",
+ "cpu\\-cycles",
+ "cycles",
+ "duration_time",
+ "instructions",
+ "l2_itlb_misses",
+ }
+ for file in os.listdir(os.fsencode(directory)):
+ filename = os.fsdecode(file)
+ if filename.endswith(".json"):
+ try:
+ for x in json.load(open(f"{directory}/{filename}")):
+ if "EventName" in x:
+ all_events.add(x["EventName"])
+ elif "ArchStdEvent" in x:
+ all_events.add(x["ArchStdEvent"])
+ except json.decoder.JSONDecodeError:
+ # The generated directory may be the same as the input, which
+ # causes partial json files. Ignore errors.
+ pass
+
+
+def CheckEvent(name: str) -> bool:
+ """Check the event name exists in the set of all loaded events"""
+ global all_events
+ if len(all_events) == 0:
+ # No events loaded so assume any event is good.
+ return True
+
+ if ':' in name:
+ # Remove trailing modifier.
+ name = name[:name.find(':')]
+ elif '/' in name:
+ # Name could begin with a PMU or an event, for now assume it is good.
+ return True
+
+ return name in all_events
+
+
class MetricConstraint(Enum):
GROUPED_EVENTS = 0
NO_GROUP_EVENTS = 1
@@ -317,9 +363,18 @@ def _FixEscapes(s: str) -> str:
class Event(Expression):
"""An event in an expression."""
- def __init__(self, name: str, legacy_name: str = ''):
- self.name = _FixEscapes(name)
- self.legacy_name = _FixEscapes(legacy_name)
+ def __init__(self, *args: str):
+ error = ""
+ for name in args:
+ if CheckEvent(name):
+ self.name = _FixEscapes(name)
+ return
+ if error:
+ error += " or " + name
+ else:
+ error = name
+ global all_events
+ raise Exception(f"No event {error} in:\n{all_events}")
def ToPerfJson(self):
result = re.sub('/', '@', self.name)
@@ -338,6 +393,28 @@ class Event(Expression):
return self
+class MetricRef(Expression):
+ """A metric reference in an expression."""
+
+ def __init__(self, name: str):
+ self.name = _FixEscapes(name)
+
+ def ToPerfJson(self):
+ return self.name
+
+ def ToPython(self):
+ return f'MetricRef(r"{self.name}")'
+
+ def Simplify(self) -> Expression:
+ return self
+
+ def Equals(self, other: Expression) -> bool:
+ return isinstance(other, MetricRef) and self.name == other.name
+
+ def Substitute(self, name: str, expression: Expression) -> Expression:
+ return self
+
+
class Constant(Expression):
"""A constant within the expression tree."""
--
2.52.0.457.g6b5491de43-goog
next prev parent reply other threads:[~2026-01-27 18:45 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-27 18:44 [PATCH v11 00/35] AMD and Intel metric generation with Python Ian Rogers
2026-01-27 18:44 ` [PATCH v11 01/35] perf jevents: Build support for generating metrics from python Ian Rogers
2026-01-27 18:44 ` Ian Rogers [this message]
2026-01-27 18:44 ` [PATCH v11 03/35] perf jevents: Add RAPL event metric for AMD zen models Ian Rogers
2026-01-27 18:44 ` [PATCH v11 04/35] perf jevents: Add idle " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 05/35] perf jevents: Add upc metric for uops per cycle for AMD Ian Rogers
2026-01-27 18:44 ` [PATCH v11 06/35] perf jevents: Add br metric group for branch statistics on AMD Ian Rogers
2026-01-27 18:44 ` [PATCH v11 07/35] perf jevents: Add itlb metric group for AMD Ian Rogers
2026-01-27 18:44 ` [PATCH v11 08/35] perf jevents: Add dtlb " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 09/35] perf jevents: Add uncore l3 " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 10/35] perf jevents: Add load store breakdown metrics ldst " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 11/35] perf jevents: Add context switch metrics " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 12/35] perf jevents: Add RAPL metrics for all Intel models Ian Rogers
2026-01-27 18:44 ` [PATCH v11 13/35] perf jevents: Add idle metric for " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 14/35] perf jevents: Add CheckPmu to see if a PMU is in loaded json events Ian Rogers
2026-01-27 18:44 ` [PATCH v11 15/35] perf jevents: Add smi metric group for Intel models Ian Rogers
2026-01-27 18:44 ` [PATCH v11 16/35] perf jevents: Mark metrics with experimental events as experimental Ian Rogers
2026-01-27 18:44 ` [PATCH v11 17/35] perf jevents: Add tsx metric group for Intel models Ian Rogers
2026-01-27 18:44 ` [PATCH v11 18/35] perf jevents: Add br metric group for branch statistics on Intel Ian Rogers
2026-01-27 18:44 ` [PATCH v11 19/35] perf jevents: Add software prefetch (swpf) metric group for Intel Ian Rogers
2026-01-27 18:44 ` [PATCH v11 20/35] perf jevents: Add ports metric group giving utilization on Intel Ian Rogers
2026-01-27 18:44 ` [PATCH v11 21/35] perf jevents: Add L2 metrics for Intel Ian Rogers
2026-01-27 18:44 ` [PATCH v11 22/35] perf jevents: Add load store breakdown metrics ldst " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 23/35] perf jevents: Add ILP metrics " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 24/35] perf jevents: Add context switch " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 25/35] perf jevents: Add FPU " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 26/35] perf jevents: Add Miss Level Parallelism (MLP) metric " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 27/35] perf jevents: Add mem_bw " Ian Rogers
2026-01-27 18:44 ` [PATCH v11 28/35] perf jevents: Add local/remote "mem" breakdown metrics " Ian Rogers
2026-01-27 18:45 ` [PATCH v11 29/35] perf jevents: Add dir " Ian Rogers
2026-01-27 18:45 ` [PATCH v11 30/35] perf jevents: Add C-State metrics from the PCU PMU " Ian Rogers
2026-01-27 18:45 ` [PATCH v11 31/35] perf jevents: Add local/remote miss latency metrics " Ian Rogers
2026-01-27 18:45 ` [PATCH v11 32/35] perf jevents: Add upi_bw metric " Ian Rogers
2026-01-27 18:45 ` [PATCH v11 33/35] perf jevents: Add mesh bandwidth saturation " Ian Rogers
2026-01-27 18:45 ` [PATCH v11 34/35] perf jevents: Add cycles breakdown metric for arm64/AMD/Intel Ian Rogers
2026-01-27 18:45 ` [PATCH v11 35/35] perf jevents: Validate that all names given an Event Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260127184506.3059493-3-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=bgray@linux.ibm.com \
--cc=caleb.biggers@intel.com \
--cc=edward.baker@intel.com \
--cc=james.clark@linaro.org \
--cc=john.g.garry@oracle.com \
--cc=jolsa@kernel.org \
--cc=leo.yan@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=perry.taylor@intel.com \
--cc=peterz@infradead.org \
--cc=renyu.zj@linux.alibaba.com \
--cc=sandipan.das@amd.com \
--cc=thomas.falcon@intel.com \
--cc=weilin.wang@intel.com \
--cc=xu.yang_2@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®