diff options
Diffstat (limited to 'tools/perf/pmu-events/jevents.py')
-rwxr-xr-x | tools/perf/pmu-events/jevents.py | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py index 2bcd07ce609f..ca99b9cfe4ad 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -44,16 +44,18 @@ _json_event_attributes = [ # Seems useful, put it early. 'event', # Short things in alphabetical order. - 'aggr_mode', 'compat', 'deprecated', 'perpkg', 'unit', + 'compat', 'deprecated', 'perpkg', 'unit', # Longer things (the last won't be iterated over during decompress). 'long_desc' ] # Attributes that are in pmu_metric rather than pmu_event. _json_metric_attributes = [ - 'metric_name', 'metric_group', 'metric_constraint', 'metric_expr', 'desc', - 'long_desc', 'unit', 'compat', 'aggr_mode' + 'metric_name', 'metric_group', 'metric_expr', 'metric_threshold', 'desc', + 'long_desc', 'unit', 'compat', 'aggr_mode', 'event_grouping' ] +# Attributes that are bools or enum int values, encoded as '0', '1',... +_json_enum_attributes = ['aggr_mode', 'deprecated', 'event_grouping', 'perpkg'] def removesuffix(s: str, suffix: str) -> str: """Remove the suffix from a string @@ -204,6 +206,18 @@ class JsonEvent: } return aggr_mode_to_enum[aggr_mode] + def convert_metric_constraint(metric_constraint: str) -> Optional[str]: + """Returns the metric_event_groups enum value associated with the JSON string.""" + if not metric_constraint: + return None + metric_constraint_to_enum = { + 'NO_GROUP_EVENTS': '1', + 'NO_GROUP_EVENTS_NMI': '2', + 'NO_NMI_WATCHDOG': '2', + 'NO_GROUP_EVENTS_SMT': '3', + } + return metric_constraint_to_enum[metric_constraint] + def lookup_msr(num: str) -> Optional[str]: """Converts the msr number, or first in a list to the appropriate event field.""" if not num: @@ -246,6 +260,7 @@ class JsonEvent: 'CPU-M-CF': 'cpum_cf', 'CPU-M-SF': 'cpum_sf', 'PAI-CRYPTO' : 'pai_crypto', + 'PAI-EXT' : 'pai_ext', 'UPI LL': 'uncore_upi', 'hisi_sicl,cpa': 'hisi_sicl,cpa', 'hisi_sccl,ddrc': 'hisi_sccl,ddrc', @@ -288,10 +303,13 @@ class JsonEvent: self.deprecated = jd.get('Deprecated') self.metric_name = jd.get('MetricName') self.metric_group = jd.get('MetricGroup') - self.metric_constraint = jd.get('MetricConstraint') + self.event_grouping = convert_metric_constraint(jd.get('MetricConstraint')) self.metric_expr = None if 'MetricExpr' in jd: self.metric_expr = metric.ParsePerfJson(jd['MetricExpr']).Simplify() + # Note, the metric formula for the threshold isn't parsed as the & + # and > have incorrect precedence. + self.metric_threshold = jd.get('MetricThreshold') arch_std = jd.get('ArchStdEvent') if precise and self.desc and '(Precise Event)' not in self.desc: @@ -348,7 +366,12 @@ class JsonEvent: # Convert parsed metric expressions into a string. Slashes # must be doubled in the file. x = x.ToPerfJson().replace('\\', '\\\\') - s += f'{x}\\000' if x else '\\000' + if metric and x and attr == 'metric_threshold': + x = x.replace('\\', '\\\\') + if attr in _json_enum_attributes: + s += x if x else '0' + else: + s += f'{x}\\000' if x else '\\000' return s def to_c_string(self, metric: bool) -> str: @@ -679,12 +702,17 @@ static void decompress_event(int offset, struct pmu_event *pe) \tconst char *p = &big_c_string[offset]; """) for attr in _json_event_attributes: - _args.output_file.write(f""" -\tpe->{attr} = (*p == '\\0' ? NULL : p); -""") + _args.output_file.write(f'\n\tpe->{attr} = ') + if attr in _json_enum_attributes: + _args.output_file.write("*p - '0';\n") + else: + _args.output_file.write("(*p == '\\0' ? NULL : p);\n") if attr == _json_event_attributes[-1]: continue - _args.output_file.write('\twhile (*p++);') + if attr in _json_enum_attributes: + _args.output_file.write('\tp++;') + else: + _args.output_file.write('\twhile (*p++);') _args.output_file.write("""} static void decompress_metric(int offset, struct pmu_metric *pm) @@ -692,12 +720,17 @@ static void decompress_metric(int offset, struct pmu_metric *pm) \tconst char *p = &big_c_string[offset]; """) for attr in _json_metric_attributes: - _args.output_file.write(f""" -\tpm->{attr} = (*p == '\\0' ? NULL : p); -""") + _args.output_file.write(f'\n\tpm->{attr} = ') + if attr in _json_enum_attributes: + _args.output_file.write("*p - '0';\n") + else: + _args.output_file.write("(*p == '\\0' ? NULL : p);\n") if attr == _json_metric_attributes[-1]: continue - _args.output_file.write('\twhile (*p++);') + if attr in _json_enum_attributes: + _args.output_file.write('\tp++;') + else: + _args.output_file.write('\twhile (*p++);') _args.output_file.write("""} int pmu_events_table_for_each_event(const struct pmu_events_table *table, @@ -889,7 +922,7 @@ def main() -> None: def ftw(path: str, parents: Sequence[str], action: Callable[[Sequence[str], os.DirEntry], None]) -> None: """Replicate the directory/file walking behavior of C's file tree walk.""" - for item in os.scandir(path): + for item in sorted(os.scandir(path), key=lambda e: e.name): if _args.model != 'all' and item.is_dir(): # Check if the model matches one in _args.model. if len(parents) == _args.model.split(',')[0].count('/'): |