summaryrefslogtreecommitdiff
path: root/tools/perf/pmu-events/jevents.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/pmu-events/jevents.py')
-rwxr-xr-xtools/perf/pmu-events/jevents.py109
1 files changed, 70 insertions, 39 deletions
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index e42efc16723e..7499a35bfadd 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -284,6 +284,7 @@ class JsonEvent:
'hisi_sccl,hha': 'hisi_sccl,hha',
'hisi_sccl,l3c': 'hisi_sccl,l3c',
'imx8_ddr': 'imx8_ddr',
+ 'imx9_ddr': 'imx9_ddr',
'L3PMC': 'amd_l3',
'DFPMC': 'amd_df',
'UMCPMC': 'amd_umc',
@@ -291,6 +292,7 @@ class JsonEvent:
'cpu_atom': 'cpu_atom',
'ali_drw': 'ali_drw',
'arm_cmn': 'arm_cmn',
+ 'tool': 'tool',
}
return table[unit] if unit in table else f'uncore_{unit.lower()}'
@@ -428,8 +430,11 @@ class JsonEvent:
def to_c_string(self, metric: bool) -> str:
"""Representation of the event as a C struct initializer."""
+ def fix_comment(s: str) -> str:
+ return s.replace('*/', r'\*\/')
+
s = self.build_c_string(metric)
- return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n'
+ return f'{{ { _bcs.offsets[s] } }}, /* {fix_comment(s)} */\n'
@lru_cache(maxsize=None)
@@ -459,12 +464,16 @@ def preprocess_arch_std_files(archpath: str) -> None:
"""Read in all architecture standard events."""
global _arch_std_events
for item in os.scandir(archpath):
- if item.is_file() and item.name.endswith('.json'):
+ if not item.is_file() or not item.name.endswith('.json'):
+ continue
+ try:
for event in read_json_events(item.path, topic=''):
if event.name:
_arch_std_events[event.name.lower()] = event
if event.metric_name:
_arch_std_events[event.metric_name.lower()] = event
+ except Exception as e:
+ raise RuntimeError(f'Failure processing \'{item.name}\' in \'{archpath}\'') from e
def add_events_table_entries(item: os.DirEntry, topic: str) -> None:
@@ -502,8 +511,11 @@ def print_pending_events() -> None:
first = True
last_pmu = None
+ last_name = None
pmus = set()
for event in sorted(_pending_events, key=event_cmp_key):
+ if last_pmu and last_pmu == event.pmu:
+ assert event.name != last_name, f"Duplicate event: {last_pmu}/{last_name}/ in {_pending_events_tblname}"
if event.pmu != last_pmu:
if not first:
_args.output_file.write('};\n')
@@ -515,6 +527,7 @@ def print_pending_events() -> None:
pmus.add((event.pmu, pmu_name))
_args.output_file.write(event.to_c_string(metric=False))
+ last_name = event.name
_pending_events = []
_args.output_file.write(f"""
@@ -630,14 +643,17 @@ def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
"""Process a JSON file during the main walk."""
- def is_leaf_dir(path: str) -> bool:
+ def is_leaf_dir_ignoring_sys(path: str) -> bool:
for item in os.scandir(path):
- if item.is_dir():
+ if item.is_dir() and item.name != 'sys':
return False
return True
- # model directory, reset topic
- if item.is_dir() and is_leaf_dir(item.path):
+ # Model directories are leaves (ignoring possible sys
+ # directories). The FTW will walk into the directory next. Flush
+ # pending events and metrics and update the table names for the new
+ # model directory.
+ if item.is_dir() and is_leaf_dir_ignoring_sys(item.path):
print_pending_events()
print_pending_metrics()
@@ -714,6 +730,17 @@ const struct pmu_events_map pmu_events_map[] = {
\t}
},
""")
+ elif arch == 'common':
+ _args.output_file.write("""{
+\t.arch = "common",
+\t.cpuid = "common",
+\t.event_table = {
+\t\t.pmus = pmu_events__common,
+\t\t.num_pmus = ARRAY_SIZE(pmu_events__common),
+\t},
+\t.metric_table = {},
+},
+""")
else:
with open(f'{_args.starting_dir}/{arch}/mapfile.csv') as csvfile:
table = csv.reader(csvfile)
@@ -905,7 +932,7 @@ static int pmu_events_table__find_event_pmu(const struct pmu_events_table *table
do_call:
return fn ? fn(&pe, table, data) : 0;
}
- return -1000;
+ return PMU_EVENTS__NOT_FOUND;
}
int pmu_events_table__for_each_event(const struct pmu_events_table *table,
@@ -918,11 +945,11 @@ int pmu_events_table__for_each_event(const struct pmu_events_table *table,
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
int ret;
- if (pmu && !pmu__name_match(pmu, pmu_name))
+ if (pmu && !perf_pmu__name_wildcard_match(pmu, pmu_name))
continue;
ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data);
- if (pmu || ret)
+ if (ret)
return ret;
}
return 0;
@@ -939,14 +966,14 @@ int pmu_events_table__find_event(const struct pmu_events_table *table,
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
int ret;
- if (!pmu__name_match(pmu, pmu_name))
+ if (!perf_pmu__name_wildcard_match(pmu, pmu_name))
continue;
ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data);
- if (ret != -1000)
+ if (ret != PMU_EVENTS__NOT_FOUND)
return ret;
}
- return -1000;
+ return PMU_EVENTS__NOT_FOUND;
}
size_t pmu_events_table__num_events(const struct pmu_events_table *table,
@@ -958,7 +985,7 @@ size_t pmu_events_table__num_events(const struct pmu_events_table *table,
const struct pmu_table_entry *table_pmu = &table->pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
- if (pmu__name_match(pmu, pmu_name))
+ if (perf_pmu__name_wildcard_match(pmu, pmu_name))
count += table_pmu->num_entries;
}
return count;
@@ -999,11 +1026,11 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
return 0;
}
-static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+static const struct pmu_events_map *map_for_cpu(struct perf_cpu cpu)
{
static struct {
const struct pmu_events_map *map;
- struct perf_pmu *pmu;
+ struct perf_cpu cpu;
} last_result;
static struct {
const struct pmu_events_map *map;
@@ -1014,10 +1041,10 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
char *cpuid = NULL;
size_t i;
- if (has_last_result && last_result.pmu == pmu)
+ if (has_last_result && last_result.cpu.cpu == cpu.cpu)
return last_result.map;
- cpuid = perf_pmu__getcpuid(pmu);
+ cpuid = get_cpuid_allow_env_override(cpu);
/*
* On some platforms which uses cpus map, cpuid can be NULL for
@@ -1048,12 +1075,21 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
has_last_map_search = true;
}
out_update_last_result:
- last_result.pmu = pmu;
+ last_result.cpu = cpu;
last_result.map = map;
has_last_result = true;
return map;
}
+static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+{
+ struct perf_cpu cpu = {-1};
+
+ if (pmu)
+ cpu = perf_cpu_map__min(pmu->cpus);
+ return map_for_cpu(cpu);
+}
+
const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
{
const struct pmu_events_map *map = map_for_pmu(pmu);
@@ -1068,30 +1104,18 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i];
const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
- if (pmu__name_match(pmu, pmu_name))
+ if (perf_pmu__name_wildcard_match(pmu, pmu_name))
return &map->event_table;
}
return NULL;
}
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
+const struct pmu_metrics_table *pmu_metrics_table__find(void)
{
- const struct pmu_events_map *map = map_for_pmu(pmu);
-
- if (!map)
- return NULL;
-
- if (!pmu)
- return &map->metric_table;
+ struct perf_cpu cpu = {-1};
+ const struct pmu_events_map *map = map_for_cpu(cpu);
- for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
- const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
- const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
- if (pmu__name_match(pmu, pmu_name))
- return &map->metric_table;
- }
- return NULL;
+ return map ? &map->metric_table : NULL;
}
const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
@@ -1233,9 +1257,12 @@ def main() -> None:
if len(parents) == _args.model.split(',')[0].count('/'):
# We're testing the correct directory.
item_path = '/'.join(parents) + ('/' if len(parents) > 0 else '') + item.name
- if 'test' not in item_path and item_path not in _args.model.split(','):
+ if 'test' not in item_path and 'common' not in item_path and item_path not in _args.model.split(','):
continue
- action(parents, item)
+ try:
+ action(parents, item)
+ except Exception as e:
+ raise RuntimeError(f'Action failure for \'{item.name}\' in {parents}') from e
if item.is_dir():
ftw(item.path, parents + [item.name], action)
@@ -1255,6 +1282,10 @@ such as "arm/cortex-a34".''',
'output_file', type=argparse.FileType('w', encoding='utf-8'), nargs='?', default=sys.stdout)
_args = ap.parse_args()
+ _args.output_file.write(f"""
+/* SPDX-License-Identifier: GPL-2.0 */
+/* THIS FILE WAS AUTOGENERATED BY jevents.py arch={_args.arch} model={_args.model} ! */
+""")
_args.output_file.write("""
#include <pmu-events/pmu-events.h>
#include "util/header.h"
@@ -1277,10 +1308,10 @@ struct pmu_table_entry {
for item in os.scandir(_args.starting_dir):
if not item.is_dir():
continue
- if item.name == _args.arch or _args.arch == 'all' or item.name == 'test':
+ if item.name == _args.arch or _args.arch == 'all' or item.name == 'test' or item.name == 'common':
archs.append(item.name)
- if len(archs) < 2:
+ if len(archs) < 2 and _args.arch != 'none':
raise IOError(f'Missing architecture directory \'{_args.arch}\'')
archs.sort()