From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Kan Liang <kan.liang@linux.intel.com>,
James Clark <james.clark@linaro.org>,
Xu Yang <xu.yang_2@nxp.com>,
Thomas Falcon <thomas.falcon@intel.com>,
Andi Kleen <ak@linux.intel.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
bpf@vger.kernel.org, Atish Patra <atishp@rivosinc.com>,
Beeman Strong <beeman@rivosinc.com>, Leo Yan <leo.yan@arm.com>,
Vince Weaver <vincent.weaver@maine.edu>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Subject: [PATCH v4 10/21] perf jevents: Add legacy json terms and default_core event table helper
Date: Sun, 14 Sep 2025 11:11:10 -0700 [thread overview]
Message-ID: <20250914181121.1952748-11-irogers@google.com> (raw)
In-Reply-To: <20250914181121.1952748-1-irogers@google.com>
Add json LegacyConfigCode and LegacyCacheCode values that translate to
legacy-hardware-config and legacy-cache-config event terms
respectively.
Add perf_pmu__default_core_events_table as a means to find a
default_core event table that will later contain legacy events.
In situations like hypervisors it is more likely that tables will be
NULL. Rather than testing in the calling PMU code, early exit in the
pmu-event.c routines.
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Thomas Richter <tmricht@linux.ibm.com>
---
tools/perf/pmu-events/empty-pmu-events.c | 26 +++++++++++++++++++
tools/perf/pmu-events/jevents.py | 32 ++++++++++++++++++++++++
tools/perf/pmu-events/pmu-events.h | 1 +
3 files changed, 59 insertions(+)
diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 041c598b16d8..2393b3a7a4c9 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -461,6 +461,8 @@ int pmu_events_table__for_each_event(const struct pmu_events_table *table,
pmu_event_iter_fn fn,
void *data)
{
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -482,6 +484,8 @@ int pmu_events_table__find_event(const struct pmu_events_table *table,
pmu_event_iter_fn fn,
void *data)
{
+ if (!table)
+ return PMU_EVENTS__NOT_FOUND;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -502,6 +506,8 @@ size_t pmu_events_table__num_events(const struct pmu_events_table *table,
{
size_t count = 0;
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -580,6 +586,8 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
pmu_metric_iter_fn fn,
void *data)
{
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
int ret = pmu_metrics_table__for_each_metric_pmu(table, &table->pmus[i],
fn, data);
@@ -596,6 +604,8 @@ int pmu_metrics_table__find_metric(const struct pmu_metrics_table *table,
pmu_metric_iter_fn fn,
void *data)
{
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -707,6 +717,22 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
return NULL;
}
+const struct pmu_events_table *perf_pmu__default_core_events_table(void)
+{
+ int i = 0;
+
+ for (;;) {
+ const struct pmu_events_map *map = &pmu_events_map[i++];
+
+ if (!map->arch)
+ break;
+
+ if (!strcmp(map->cpuid, "common"))
+ return &map->event_table;
+ }
+ return NULL;
+}
+
const struct pmu_metrics_table *pmu_metrics_table__find(void)
{
struct perf_cpu cpu = {-1};
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 168c044dd7cc..1f3917cbff87 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -325,6 +325,8 @@ class JsonEvent:
eventcode |= int(jd['ExtSel']) << 8
configcode = int(jd['ConfigCode'], 0) if 'ConfigCode' in jd else None
eventidcode = int(jd['EventidCode'], 0) if 'EventidCode' in jd else None
+ legacy_hw_config = int(jd['LegacyConfigCode'], 0) if 'LegacyConfigCode' in jd else None
+ legacy_cache_config = int(jd['LegacyCacheCode'], 0) if 'LegacyCacheCode' in jd else None
self.name = jd['EventName'].lower() if 'EventName' in jd else None
self.topic = ''
self.compat = jd.get('Compat')
@@ -370,6 +372,10 @@ class JsonEvent:
event = f'config={llx(configcode)}'
elif eventidcode is not None:
event = f'eventid={llx(eventidcode)}'
+ elif legacy_hw_config is not None:
+ event = f'legacy-hardware-config={llx(legacy_hw_config)}'
+ elif legacy_cache_config is not None:
+ event = f'legacy-cache-config={llx(legacy_cache_config)}'
else:
event = f'event={llx(eventcode)}'
event_fields = [
@@ -951,6 +957,8 @@ int pmu_events_table__for_each_event(const struct pmu_events_table *table,
pmu_event_iter_fn fn,
void *data)
{
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -972,6 +980,8 @@ int pmu_events_table__find_event(const struct pmu_events_table *table,
pmu_event_iter_fn fn,
void *data)
{
+ if (!table)
+ return PMU_EVENTS__NOT_FOUND;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -992,6 +1002,8 @@ size_t pmu_events_table__num_events(const struct pmu_events_table *table,
{
size_t count = 0;
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -1070,6 +1082,8 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
pmu_metric_iter_fn fn,
void *data)
{
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
int ret = pmu_metrics_table__for_each_metric_pmu(table, &table->pmus[i],
fn, data);
@@ -1086,6 +1100,8 @@ int pmu_metrics_table__find_metric(const struct pmu_metrics_table *table,
pmu_metric_iter_fn fn,
void *data)
{
+ if (!table)
+ return 0;
for (size_t i = 0; i < table->num_pmus; i++) {
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
@@ -1197,6 +1213,22 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
return NULL;
}
+const struct pmu_events_table *perf_pmu__default_core_events_table(void)
+{
+ int i = 0;
+
+ for (;;) {
+ const struct pmu_events_map *map = &pmu_events_map[i++];
+
+ if (!map->arch)
+ break;
+
+ if (!strcmp(map->cpuid, "common"))
+ return &map->event_table;
+ }
+ return NULL;
+}
+
const struct pmu_metrics_table *pmu_metrics_table__find(void)
{
struct perf_cpu cpu = {-1};
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
index ea022ea55087..e0535380c0b2 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -125,6 +125,7 @@ int pmu_metrics_table__find_metric(const struct pmu_metrics_table *table,
void *data);
const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu);
+const struct pmu_events_table *perf_pmu__default_core_events_table(void);
const struct pmu_metrics_table *pmu_metrics_table__find(void);
const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid);
const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid);
--
2.51.0.384.g4c02a37b29-goog
next prev parent reply other threads:[~2025-09-14 18:11 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-14 18:11 [PATCH v4 00/21] Legacy hardware/cache events as json Ian Rogers
2025-09-14 18:11 ` [PATCH v4 01/21] perf parse-events: Fix legacy cache events if event is duplicated in a PMU Ian Rogers
2025-09-14 18:11 ` [PATCH v4 02/21] perf perf_api_probe: Avoid scanning all PMUs, try software PMU first Ian Rogers
2025-09-14 18:11 ` [PATCH v4 03/21] perf record: Skip don't fail for events that don't open Ian Rogers
2025-09-14 18:11 ` [PATCH v4 04/21] perf jevents: Support copying the source json files to OUTPUT Ian Rogers
2025-09-14 18:11 ` [PATCH v4 05/21] perf pmu: Don't eagerly parse event terms Ian Rogers
2025-09-14 18:11 ` [PATCH v4 06/21] perf parse-events: Remove unused FILE input argument to scanner Ian Rogers
2025-09-14 18:11 ` [PATCH v4 07/21] perf pmu: Use fd rather than FILE from new_alias Ian Rogers
2025-09-14 18:11 ` [PATCH v4 08/21] perf pmu: Factor term parsing into a perf_event_attr into a helper Ian Rogers
2025-09-14 18:11 ` [PATCH v4 09/21] perf parse-events: Add terms for legacy hardware and cache config values Ian Rogers
2025-09-14 18:11 ` Ian Rogers [this message]
2025-09-14 18:11 ` [PATCH v4 11/21] perf pmu: Add and use legacy_terms in alias information Ian Rogers
2025-09-14 18:11 ` [PATCH v4 12/21] perf jevents: Add legacy-hardware and legacy-cache json Ian Rogers
2025-09-14 18:11 ` [PATCH v4 13/21] perf print-events: Remove print_hwcache_events Ian Rogers
2025-09-14 18:11 ` [PATCH v4 14/21] perf print-events: Remove print_symbol_events Ian Rogers
2025-09-14 18:11 ` [PATCH v4 15/21] perf parse-events: Remove hard coded legacy hardware and cache parsing Ian Rogers
2025-09-14 18:11 ` [PATCH v4 16/21] perf record: Use evlist__new_default when no events specified Ian Rogers
2025-09-14 18:11 ` [PATCH v4 17/21] perf top: " Ian Rogers
2025-09-14 18:11 ` [PATCH v4 18/21] perf evlist: Avoid scanning all PMUs for evlist__new_default Ian Rogers
2025-09-14 18:11 ` [PATCH v4 19/21] perf evsel: Improvements to __evsel__match Ian Rogers
2025-09-14 18:11 ` [PATCH v4 20/21] perf parse-events: Add HW_CYCLES_STR as default cycles event string Ian Rogers
2025-09-16 13:18 ` Mark Rutland
2025-09-16 15:49 ` Ian Rogers
2025-09-16 17:56 ` Ian Rogers
2025-09-17 6:23 ` Namhyung Kim
2025-09-20 15:16 ` Ian Rogers
2025-09-14 18:11 ` [PATCH v4 21/21] perf test: Make stat grep more robust 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=20250914181121.1952748-11-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=atishp@rivosinc.com \
--cc=beeman@rivosinc.com \
--cc=bpf@vger.kernel.org \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=leo.yan@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=thomas.falcon@intel.com \
--cc=tmricht@linux.ibm.com \
--cc=vincent.weaver@maine.edu \
--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;
as well as URLs for NNTP newsgroup(s).