Commit 62774db2 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf jevents: Generate metrics and events as separate tables

Turn a perf json event into an event, metric or both. This reduces the
number of events needed to scan to find an event or metric. As events
no longer need the relatively seldom used metric fields, 4 bytes is
saved per event. This reduces the big C string's size by 335kb (14.8%)
on x86.

Note, for the test PMU architecture pme_test_soc_cpu is renamed
pmu_events__test_soc_cpu for consistency with the event vs metric
naming convention.
Reviewed-by: default avatarKajol Jain <kjain@linux.ibm.com>
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Kang Minchul <tegongkang@gmail.com>
Cc: Kim Phillips <kim.phillips@amd.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Link: https://lore.kernel.org/r/20230126233645.200509-11-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f8ea2c15
...@@ -13,28 +13,40 @@ import collections ...@@ -13,28 +13,40 @@ import collections
# Global command line arguments. # Global command line arguments.
_args = None _args = None
# List of regular event tables.
_event_tables = []
# List of event tables generated from "/sys" directories. # List of event tables generated from "/sys" directories.
_sys_event_tables = [] _sys_event_tables = []
# List of regular metric tables.
_metric_tables = []
# List of metric tables generated from "/sys" directories.
_sys_metric_tables = []
# Mapping between sys event table names and sys metric table names.
_sys_event_table_to_metric_table_mapping = {}
# Map from an event name to an architecture standard # Map from an event name to an architecture standard
# JsonEvent. Architecture standard events are in json files in the top # JsonEvent. Architecture standard events are in json files in the top
# f'{_args.starting_dir}/{_args.arch}' directory. # f'{_args.starting_dir}/{_args.arch}' directory.
_arch_std_events = {} _arch_std_events = {}
# Events to write out when the table is closed # Events to write out when the table is closed
_pending_events = [] _pending_events = []
# Name of table to be written out # Name of events table to be written out
_pending_events_tblname = None _pending_events_tblname = None
# Metrics to write out when the table is closed
_pending_metrics = []
# Name of metrics table to be written out
_pending_metrics_tblname = None
# Global BigCString shared by all structures. # Global BigCString shared by all structures.
_bcs = None _bcs = None
# Order specific JsonEvent attributes will be visited. # Order specific JsonEvent attributes will be visited.
_json_event_attributes = [ _json_event_attributes = [
# cmp_sevent related attributes. # cmp_sevent related attributes.
'name', 'pmu', 'topic', 'desc', 'metric_name', 'metric_group', 'name', 'pmu', 'topic', 'desc',
# Seems useful, put it early. # Seems useful, put it early.
'event', 'event',
# Short things in alphabetical order. # Short things in alphabetical order.
'aggr_mode', 'compat', 'deprecated', 'perpkg', 'unit', 'aggr_mode', 'compat', 'deprecated', 'perpkg', 'unit',
# Longer things (the last won't be iterated over during decompress). # Longer things (the last won't be iterated over during decompress).
'metric_constraint', 'metric_expr', 'long_desc' 'long_desc'
] ]
# Attributes that are in pmu_metric rather than pmu_event. # Attributes that are in pmu_metric rather than pmu_event.
...@@ -52,14 +64,16 @@ def removesuffix(s: str, suffix: str) -> str: ...@@ -52,14 +64,16 @@ def removesuffix(s: str, suffix: str) -> str:
return s[0:-len(suffix)] if s.endswith(suffix) else s return s[0:-len(suffix)] if s.endswith(suffix) else s
def file_name_to_table_name(parents: Sequence[str], dirname: str) -> str: def file_name_to_table_name(prefix: str, parents: Sequence[str],
dirname: str) -> str:
"""Generate a C table name from directory names.""" """Generate a C table name from directory names."""
tblname = 'pme' tblname = prefix
for p in parents: for p in parents:
tblname += '_' + p tblname += '_' + p
tblname += '_' + dirname tblname += '_' + dirname
return tblname.replace('-', '_') return tblname.replace('-', '_')
def c_len(s: str) -> int: def c_len(s: str) -> int:
"""Return the length of s a C string """Return the length of s a C string
...@@ -277,7 +291,7 @@ class JsonEvent: ...@@ -277,7 +291,7 @@ class JsonEvent:
self.metric_constraint = jd.get('MetricConstraint') self.metric_constraint = jd.get('MetricConstraint')
self.metric_expr = None self.metric_expr = None
if 'MetricExpr' in jd: if 'MetricExpr' in jd:
self.metric_expr = metric.ParsePerfJson(jd['MetricExpr']).Simplify() self.metric_expr = metric.ParsePerfJson(jd['MetricExpr']).Simplify()
arch_std = jd.get('ArchStdEvent') arch_std = jd.get('ArchStdEvent')
if precise and self.desc and '(Precise Event)' not in self.desc: if precise and self.desc and '(Precise Event)' not in self.desc:
...@@ -326,23 +340,24 @@ class JsonEvent: ...@@ -326,23 +340,24 @@ class JsonEvent:
s += f'\t{attr} = {value},\n' s += f'\t{attr} = {value},\n'
return s + '}' return s + '}'
def build_c_string(self) -> str: def build_c_string(self, metric: bool) -> str:
s = '' s = ''
for attr in _json_event_attributes: for attr in _json_metric_attributes if metric else _json_event_attributes:
x = getattr(self, attr) x = getattr(self, attr)
if x and attr == 'metric_expr': if metric and x and attr == 'metric_expr':
# Convert parsed metric expressions into a string. Slashes # Convert parsed metric expressions into a string. Slashes
# must be doubled in the file. # must be doubled in the file.
x = x.ToPerfJson().replace('\\', '\\\\') x = x.ToPerfJson().replace('\\', '\\\\')
s += f'{x}\\000' if x else '\\000' s += f'{x}\\000' if x else '\\000'
return s return s
def to_c_string(self) -> str: def to_c_string(self, metric: bool) -> str:
"""Representation of the event as a C struct initializer.""" """Representation of the event as a C struct initializer."""
s = self.build_c_string() s = self.build_c_string(metric)
return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n' return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n'
@lru_cache(maxsize=None) @lru_cache(maxsize=None)
def read_json_events(path: str, topic: str) -> Sequence[JsonEvent]: def read_json_events(path: str, topic: str) -> Sequence[JsonEvent]:
"""Read json events from the specified file.""" """Read json events from the specified file."""
...@@ -381,7 +396,10 @@ def preprocess_arch_std_files(archpath: str) -> None: ...@@ -381,7 +396,10 @@ def preprocess_arch_std_files(archpath: str) -> None:
def add_events_table_entries(item: os.DirEntry, topic: str) -> None: def add_events_table_entries(item: os.DirEntry, topic: str) -> None:
"""Add contents of file to _pending_events table.""" """Add contents of file to _pending_events table."""
for e in read_json_events(item.path, topic): for e in read_json_events(item.path, topic):
_pending_events.append(e) if e.name:
_pending_events.append(e)
if e.metric_name:
_pending_metrics.append(e)
def print_pending_events() -> None: def print_pending_events() -> None:
...@@ -401,15 +419,54 @@ def print_pending_events() -> None: ...@@ -401,15 +419,54 @@ def print_pending_events() -> None:
return return
global _pending_events_tblname global _pending_events_tblname
if _pending_events_tblname.endswith('_sys'):
global _sys_event_tables
_sys_event_tables.append(_pending_events_tblname)
else:
global event_tables
_event_tables.append(_pending_events_tblname)
_args.output_file.write( _args.output_file.write(
f'static const struct compact_pmu_event {_pending_events_tblname}[] = {{\n') f'static const struct compact_pmu_event {_pending_events_tblname}[] = {{\n')
for event in sorted(_pending_events, key=event_cmp_key): for event in sorted(_pending_events, key=event_cmp_key):
_args.output_file.write(event.to_c_string()) _args.output_file.write(event.to_c_string(metric=False))
_pending_events = [] _pending_events = []
_args.output_file.write('};\n\n') _args.output_file.write('};\n\n')
def print_pending_metrics() -> None:
"""Optionally close metrics table."""
def metric_cmp_key(j: JsonEvent) -> Tuple[bool, str, str]:
def fix_none(s: Optional[str]) -> str:
if s is None:
return ''
return s
return (j.desc is not None, fix_none(j.pmu), fix_none(j.metric_name))
global _pending_metrics
if not _pending_metrics:
return
global _pending_metrics_tblname
if _pending_metrics_tblname.endswith('_sys'):
global _sys_metric_tables
_sys_metric_tables.append(_pending_metrics_tblname)
else:
global metric_tables
_metric_tables.append(_pending_metrics_tblname)
_args.output_file.write(
f'static const struct compact_pmu_event {_pending_metrics_tblname}[] = {{\n')
for metric in sorted(_pending_metrics, key=metric_cmp_key):
_args.output_file.write(metric.to_c_string(metric=True))
_pending_metrics = []
_args.output_file.write('};\n\n')
def get_topic(topic: str) -> str: def get_topic(topic: str) -> str:
if topic.endswith('metrics.json'): if topic.endswith('metrics.json'):
return 'metrics' return 'metrics'
...@@ -432,12 +489,13 @@ def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None: ...@@ -432,12 +489,13 @@ def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
topic = get_topic(item.name) topic = get_topic(item.name)
for event in read_json_events(item.path, topic): for event in read_json_events(item.path, topic):
_bcs.add(event.build_c_string()) if event.name:
_bcs.add(event.build_c_string(metric=False))
if event.metric_name:
_bcs.add(event.build_c_string(metric=True))
def process_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.""" """Process a JSON file during the main walk."""
global _sys_event_tables
def is_leaf_dir(path: str) -> bool: def is_leaf_dir(path: str) -> bool:
for item in os.scandir(path): for item in os.scandir(path):
if item.is_dir(): if item.is_dir():
...@@ -447,12 +505,15 @@ def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None: ...@@ -447,12 +505,15 @@ def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
# model directory, reset topic # model directory, reset topic
if item.is_dir() and is_leaf_dir(item.path): if item.is_dir() and is_leaf_dir(item.path):
print_pending_events() print_pending_events()
print_pending_metrics()
tblname = file_name_to_table_name(parents, item.name)
if item.name == 'sys':
_sys_event_tables.append(tblname)
global _pending_events_tblname global _pending_events_tblname
_pending_events_tblname = tblname _pending_events_tblname = file_name_to_table_name('pmu_events_', parents, item.name)
global _pending_metrics_tblname
_pending_metrics_tblname = file_name_to_table_name('pmu_metrics_', parents, item.name)
if item.name == 'sys':
_sys_event_table_to_metric_table_mapping[_pending_events_tblname] = _pending_metrics_tblname
return return
# base dir or too deep # base dir or too deep
...@@ -477,6 +538,12 @@ struct pmu_events_table { ...@@ -477,6 +538,12 @@ struct pmu_events_table {
size_t length; size_t length;
}; };
/* Struct used to make the PMU metric table implementation opaque to callers. */
struct pmu_metrics_table {
const struct compact_pmu_event *entries;
size_t length;
};
/* /*
* Map a CPU to its table of PMU events. The CPU is identified by the * Map a CPU to its table of PMU events. The CPU is identified by the
* cpuid field, which is an arch-specific identifier for the CPU. * cpuid field, which is an arch-specific identifier for the CPU.
...@@ -488,7 +555,8 @@ struct pmu_events_table { ...@@ -488,7 +555,8 @@ struct pmu_events_table {
struct pmu_events_map { struct pmu_events_map {
const char *arch; const char *arch;
const char *cpuid; const char *cpuid;
struct pmu_events_table table; struct pmu_events_table event_table;
struct pmu_metrics_table metric_table;
}; };
/* /*
...@@ -502,9 +570,13 @@ const struct pmu_events_map pmu_events_map[] = { ...@@ -502,9 +570,13 @@ const struct pmu_events_map pmu_events_map[] = {
_args.output_file.write("""{ _args.output_file.write("""{
\t.arch = "testarch", \t.arch = "testarch",
\t.cpuid = "testcpu", \t.cpuid = "testcpu",
\t.table = { \t.event_table = {
\t.entries = pme_test_soc_cpu, \t\t.entries = pmu_events__test_soc_cpu,
\t.length = ARRAY_SIZE(pme_test_soc_cpu), \t\t.length = ARRAY_SIZE(pmu_events__test_soc_cpu),
\t},
\t.metric_table = {
\t\t.entries = pmu_metrics__test_soc_cpu,
\t\t.length = ARRAY_SIZE(pmu_metrics__test_soc_cpu),
\t} \t}
}, },
""") """)
...@@ -515,14 +587,29 @@ const struct pmu_events_map pmu_events_map[] = { ...@@ -515,14 +587,29 @@ const struct pmu_events_map pmu_events_map[] = {
for row in table: for row in table:
# Skip the first row or any row beginning with #. # Skip the first row or any row beginning with #.
if not first and len(row) > 0 and not row[0].startswith('#'): if not first and len(row) > 0 and not row[0].startswith('#'):
tblname = file_name_to_table_name([], row[2].replace('/', '_')) event_tblname = file_name_to_table_name('pmu_events_', [], row[2].replace('/', '_'))
if event_tblname in _event_tables:
event_size = f'ARRAY_SIZE({event_tblname})'
else:
event_tblname = 'NULL'
event_size = '0'
metric_tblname = file_name_to_table_name('pmu_metrics_', [], row[2].replace('/', '_'))
if metric_tblname in _metric_tables:
metric_size = f'ARRAY_SIZE({metric_tblname})'
else:
metric_tblname = 'NULL'
metric_size = '0'
cpuid = row[0].replace('\\', '\\\\') cpuid = row[0].replace('\\', '\\\\')
_args.output_file.write(f"""{{ _args.output_file.write(f"""{{
\t.arch = "{arch}", \t.arch = "{arch}",
\t.cpuid = "{cpuid}", \t.cpuid = "{cpuid}",
\t.table = {{ \t.event_table = {{
\t\t.entries = {tblname}, \t\t.entries = {event_tblname},
\t\t.length = ARRAY_SIZE({tblname}) \t\t.length = {event_size}
\t}},
\t.metric_table = {{
\t\t.entries = {metric_tblname},
\t\t.length = {metric_size}
\t}} \t}}
}}, }},
""") """)
...@@ -531,7 +618,8 @@ const struct pmu_events_map pmu_events_map[] = { ...@@ -531,7 +618,8 @@ const struct pmu_events_map pmu_events_map[] = {
_args.output_file.write("""{ _args.output_file.write("""{
\t.arch = 0, \t.arch = 0,
\t.cpuid = 0, \t.cpuid = 0,
\t.table = { 0, 0 }, \t.event_table = { 0, 0 },
\t.metric_table = { 0, 0 },
} }
}; };
""") """)
...@@ -542,14 +630,36 @@ def print_system_mapping_table() -> None: ...@@ -542,14 +630,36 @@ def print_system_mapping_table() -> None:
_args.output_file.write(""" _args.output_file.write("""
struct pmu_sys_events { struct pmu_sys_events {
\tconst char *name; \tconst char *name;
\tstruct pmu_events_table table; \tstruct pmu_events_table event_table;
\tstruct pmu_metrics_table metric_table;
}; };
static const struct pmu_sys_events pmu_sys_event_tables[] = { static const struct pmu_sys_events pmu_sys_event_tables[] = {
""") """)
printed_metric_tables = []
for tblname in _sys_event_tables: for tblname in _sys_event_tables:
_args.output_file.write(f"""\t{{ _args.output_file.write(f"""\t{{
\t\t.table = {{ \t\t.event_table = {{
\t\t\t.entries = {tblname},
\t\t\t.length = ARRAY_SIZE({tblname})
\t\t}},""")
metric_tblname = _sys_event_table_to_metric_table_mapping[tblname]
if metric_tblname in _sys_metric_tables:
_args.output_file.write(f"""
\t\t.metric_table = {{
\t\t\t.entries = {metric_tblname},
\t\t\t.length = ARRAY_SIZE({metric_tblname})
\t\t}},""")
printed_metric_tables.append(metric_tblname)
_args.output_file.write(f"""
\t\t.name = \"{tblname}\",
\t}},
""")
for tblname in _sys_metric_tables:
if tblname in printed_metric_tables:
continue
_args.output_file.write(f"""\t{{
\t\t.metric_table = {{
\t\t\t.entries = {tblname}, \t\t\t.entries = {tblname},
\t\t\t.length = ARRAY_SIZE({tblname}) \t\t\t.length = ARRAY_SIZE({tblname})
\t\t}}, \t\t}},
...@@ -557,7 +667,8 @@ static const struct pmu_sys_events pmu_sys_event_tables[] = { ...@@ -557,7 +667,8 @@ static const struct pmu_sys_events pmu_sys_event_tables[] = {
\t}}, \t}},
""") """)
_args.output_file.write("""\t{ _args.output_file.write("""\t{
\t\t.table = { 0, 0 } \t\t.event_table = { 0, 0 },
\t\t.metric_table = { 0, 0 },
\t}, \t},
}; };
...@@ -566,10 +677,7 @@ static void decompress_event(int offset, struct pmu_event *pe) ...@@ -566,10 +677,7 @@ static void decompress_event(int offset, struct pmu_event *pe)
\tconst char *p = &big_c_string[offset]; \tconst char *p = &big_c_string[offset];
""") """)
for attr in _json_event_attributes: for attr in _json_event_attributes:
if attr in _json_metric_attributes and 'metric_' in attr: _args.output_file.write(f"""
_args.output_file.write(f'\n\t/* Skip {attr} */\n')
else:
_args.output_file.write(f"""
\tpe->{attr} = (*p == '\\0' ? NULL : p); \tpe->{attr} = (*p == '\\0' ? NULL : p);
""") """)
if attr == _json_event_attributes[-1]: if attr == _json_event_attributes[-1]:
...@@ -581,14 +689,11 @@ static void decompress_metric(int offset, struct pmu_metric *pm) ...@@ -581,14 +689,11 @@ static void decompress_metric(int offset, struct pmu_metric *pm)
{ {
\tconst char *p = &big_c_string[offset]; \tconst char *p = &big_c_string[offset];
""") """)
for attr in _json_event_attributes: for attr in _json_metric_attributes:
if attr in _json_metric_attributes: _args.output_file.write(f"""
_args.output_file.write(f"""
\tpm->{attr} = (*p == '\\0' ? NULL : p); \tpm->{attr} = (*p == '\\0' ? NULL : p);
""") """)
else: if attr == _json_metric_attributes[-1]:
_args.output_file.write(f'\n\t/* Skip {attr} */\n')
if attr == _json_event_attributes[-1]:
continue continue
_args.output_file.write('\twhile (*p++);') _args.output_file.write('\twhile (*p++);')
_args.output_file.write("""} _args.output_file.write("""}
...@@ -611,12 +716,10 @@ int pmu_events_table_for_each_event(const struct pmu_events_table *table, ...@@ -611,12 +716,10 @@ int pmu_events_table_for_each_event(const struct pmu_events_table *table,
return 0; return 0;
} }
int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *mtable, int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *table,
pmu_metric_iter_fn fn, pmu_metric_iter_fn fn,
void *data) void *data)
{ {
const struct pmu_events_table *table = (const struct pmu_events_table *)mtable;
for (size_t i = 0; i < table->length; i++) { for (size_t i = 0; i < table->length; i++) {
struct pmu_metric pm; struct pmu_metric pm;
int ret; int ret;
...@@ -624,7 +727,7 @@ int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *mtable, ...@@ -624,7 +727,7 @@ int pmu_metrics_table_for_each_metric(const struct pmu_metrics_table *mtable,
decompress_metric(table->entries[i].offset, &pm); decompress_metric(table->entries[i].offset, &pm);
if (!pm.metric_expr) if (!pm.metric_expr)
continue; continue;
ret = fn(&pm, mtable, data); ret = fn(&pm, table, data);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -650,7 +753,7 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu) ...@@ -650,7 +753,7 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
break; break;
if (!strcmp_cpuid_str(map->cpuid, cpuid)) { if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
table = &map->table; table = &map->event_table;
break; break;
} }
} }
...@@ -660,7 +763,29 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu) ...@@ -660,7 +763,29 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu) const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
{ {
return (struct pmu_metrics_table *)perf_pmu__find_events_table(pmu); const struct pmu_metrics_table *table = NULL;
char *cpuid = perf_pmu__getcpuid(pmu);
int i;
/* on some platforms which uses cpus map, cpuid can be NULL for
* PMUs other than CORE PMUs.
*/
if (!cpuid)
return NULL;
i = 0;
for (;;) {
const struct pmu_events_map *map = &pmu_events_map[i++];
if (!map->arch)
break;
if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
table = &map->metric_table;
break;
}
}
free(cpuid);
return table;
} }
const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid) const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
...@@ -669,14 +794,20 @@ const struct pmu_events_table *find_core_events_table(const char *arch, const ch ...@@ -669,14 +794,20 @@ const struct pmu_events_table *find_core_events_table(const char *arch, const ch
tables->arch; tables->arch;
tables++) { tables++) {
if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
return &tables->table; return &tables->event_table;
} }
return NULL; return NULL;
} }
const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid) const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid)
{ {
return (struct pmu_metrics_table *)find_core_events_table(arch, cpuid); for (const struct pmu_events_map *tables = &pmu_events_map[0];
tables->arch;
tables++) {
if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
return &tables->metric_table;
}
return NULL;
} }
int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
...@@ -684,7 +815,7 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) ...@@ -684,7 +815,7 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
for (const struct pmu_events_map *tables = &pmu_events_map[0]; for (const struct pmu_events_map *tables = &pmu_events_map[0];
tables->arch; tables->arch;
tables++) { tables++) {
int ret = pmu_events_table_for_each_event(&tables->table, fn, data); int ret = pmu_events_table_for_each_event(&tables->event_table, fn, data);
if (ret) if (ret)
return ret; return ret;
...@@ -697,8 +828,7 @@ int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data) ...@@ -697,8 +828,7 @@ int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data)
for (const struct pmu_events_map *tables = &pmu_events_map[0]; for (const struct pmu_events_map *tables = &pmu_events_map[0];
tables->arch; tables->arch;
tables++) { tables++) {
int ret = pmu_metrics_table_for_each_metric( int ret = pmu_metrics_table_for_each_metric(&tables->metric_table, fn, data);
(struct pmu_metrics_table *)&tables->table, fn, data);
if (ret) if (ret)
return ret; return ret;
...@@ -712,7 +842,7 @@ const struct pmu_events_table *find_sys_events_table(const char *name) ...@@ -712,7 +842,7 @@ const struct pmu_events_table *find_sys_events_table(const char *name)
tables->name; tables->name;
tables++) { tables++) {
if (!strcmp(tables->name, name)) if (!strcmp(tables->name, name))
return &tables->table; return &tables->event_table;
} }
return NULL; return NULL;
} }
...@@ -722,7 +852,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) ...@@ -722,7 +852,7 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
tables->name; tables->name;
tables++) { tables++) {
int ret = pmu_events_table_for_each_event(&tables->table, fn, data); int ret = pmu_events_table_for_each_event(&tables->event_table, fn, data);
if (ret) if (ret)
return ret; return ret;
...@@ -735,8 +865,7 @@ int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data) ...@@ -735,8 +865,7 @@ int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data)
for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
tables->name; tables->name;
tables++) { tables++) {
int ret = pmu_metrics_table_for_each_metric( int ret = pmu_metrics_table_for_each_metric(&tables->metric_table, fn, data);
(struct pmu_metrics_table *)&tables->table, fn, data);
if (ret) if (ret)
return ret; return ret;
...@@ -811,6 +940,7 @@ struct compact_pmu_event { ...@@ -811,6 +940,7 @@ struct compact_pmu_event {
arch_path = f'{_args.starting_dir}/{arch}' arch_path = f'{_args.starting_dir}/{arch}'
ftw(arch_path, [], process_one_file) ftw(arch_path, [], process_one_file)
print_pending_events() print_pending_events()
print_pending_metrics()
print_mapping_table(archs) print_mapping_table(archs)
print_system_mapping_table() print_system_mapping_table()
......
...@@ -469,7 +469,8 @@ static int test__pmu_event_table_sys_callback(const struct pmu_event *pe, ...@@ -469,7 +469,8 @@ static int test__pmu_event_table_sys_callback(const struct pmu_event *pe,
static int test__pmu_event_table(struct test_suite *test __maybe_unused, static int test__pmu_event_table(struct test_suite *test __maybe_unused,
int subtest __maybe_unused) int subtest __maybe_unused)
{ {
const struct pmu_events_table *sys_event_table = find_sys_events_table("pme_test_soc_sys"); const struct pmu_events_table *sys_event_table =
find_sys_events_table("pmu_events__test_soc_sys");
const struct pmu_events_table *table = find_core_events_table("testarch", "testcpu"); const struct pmu_events_table *table = find_core_events_table("testarch", "testcpu");
int map_events = 0, expected_events, err; int map_events = 0, expected_events, err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment