diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py index e86989c1389d..5c15485d695a 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -14,27 +14,27 @@ import collections # Global command line arguments. _args = None # List of regular event tables. -_event_tables = [] +_event_tables: list[str] = [] # List of event tables generated from "/sys" directories. -_sys_event_tables = [] +_sys_event_tables: list[str] = [] # List of regular metric tables. -_metric_tables = [] +_metric_tables: list[str] = [] # List of metric tables generated from "/sys" directories. -_sys_metric_tables = [] +_sys_metric_tables: list[str] = [] # 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 # JsonEvent. Architecture standard events are in json files in the top # f'{_args.starting_dir}/{_args.arch}' directory. -_arch_std_events = {} +_arch_std_events: Dict[str, "JsonEvent"] = {} # Events to write out when the table is closed -_pending_events = [] +_pending_events: list["JsonEvent"] = [] # Name of events table to be written out -_pending_events_tblname = None +_pending_events_tblname: Optional[str] = None # Metrics to write out when the table is closed -_pending_metrics = [] +_pending_metrics: list["JsonEvent"] = [] # Name of metrics table to be written out -_pending_metrics_tblname = None +_pending_metrics_tblname: Optional[str] = None # Global BigCString shared by all structures. _bcs = None # Map from the name of a metric group to a description of the group. @@ -210,7 +210,7 @@ class JsonEvent: """Convert an int to a string similar to a printf modifier of %#llx.""" return str(x) if x >= 0 and x < 10 else hex(x) - def fixdesc(s: str) -> str: + def fixdesc(s: Optional[str]) -> Optional[str]: """Fix formatting issue for the desc string.""" if s is None: return None @@ -218,7 +218,7 @@ class JsonEvent: '. '), '.').replace('\n', '\\n').replace( '\"', '\\"').replace('\r', '\\r') - def convert_aggr_mode(aggr_mode: str) -> Optional[str]: + def convert_aggr_mode(aggr_mode: Optional[str]) -> Optional[str]: """Returns the aggr_mode_class enum value associated with the JSON string.""" if not aggr_mode: return None @@ -228,7 +228,7 @@ class JsonEvent: } return aggr_mode_to_enum[aggr_mode] - def convert_metric_constraint(metric_constraint: str) -> Optional[str]: + def convert_metric_constraint(metric_constraint: Optional[str]) -> Optional[str]: """Returns the metric_event_groups enum value associated with the JSON string.""" if not metric_constraint: return None @@ -241,7 +241,7 @@ class JsonEvent: } return metric_constraint_to_enum[metric_constraint] - def lookup_msr(num: str) -> Optional[str]: + def lookup_msr(num: Optional[str]) -> Optional[str]: """Converts the msr number, or first in a list to the appropriate event field.""" if not num: return None @@ -257,7 +257,7 @@ class JsonEvent: } return msrmap[int(num.split(',', 1)[0], 0)] - def real_event(name: str, event: str) -> Optional[str]: + def real_event(name: Optional[str], event: Optional[str]) -> Optional[str]: """Convert well known event names to an event string otherwise use the event argument.""" fixed = { 'inst_retired.any': 'event=0xc0,period=2000003', @@ -273,7 +273,7 @@ class JsonEvent: return fixed[name.lower()] return event - def unit_to_pmu(unit: str) -> Optional[str]: + def unit_to_pmu(unit: Optional[str]) -> Optional[str]: """Convert a JSON Unit to Linux PMU name.""" if not unit: return 'default_core' @@ -308,21 +308,21 @@ class JsonEvent: return table[unit] if unit in table else f'uncore_{unit.lower()}' def is_zero(val: str) -> bool: - try: - if val.startswith('0x'): - return int(val, 16) == 0 - else: - return int(val) == 0 - except e: - return False + try: + if val.startswith('0x'): + return int(val, 16) == 0 + else: + return int(val) == 0 + except: + return False def canonicalize_value(val: str) -> str: - try: - if val.startswith('0x'): - return llx(int(val, 16)) - return str(int(val)) - except e: - return val + try: + if val.startswith('0x'): + return llx(int(val, 16)) + return str(int(val)) + except: + return val eventcode = 0 if 'EventCode' in jd: @@ -374,7 +374,8 @@ class JsonEvent: if precise and self.desc and '(Precise Event)' not in self.desc: extra_desc += ' (Must be precise)' if precise == '2' else (' (Precise ' 'event)') - event = None + self.event: Optional[str] = None + event: Optional[str] = None if configcode is not None: event = f'config={llx(configcode)}' elif eventidcode is not None: @@ -459,6 +460,7 @@ class JsonEvent: return f'\t/* {s} */\n' if len(s) < 80 else f'\t/* {s[0:80]}... */\n' s = self.build_c_string(metric) + assert _bcs is not None return f'{make_comment(s)}\t{{ { _bcs.offsets[s] } }},\n' @@ -528,6 +530,7 @@ def print_pending_events() -> None: return global _pending_events_tblname + assert _pending_events_tblname is not None if _pending_events_tblname.endswith('_sys'): global _sys_event_tables _sys_event_tables.append(_pending_events_tblname) @@ -538,7 +541,8 @@ def print_pending_events() -> None: first = True last_pmu = None last_name = None - pmus = set() + pmus: Set[Tuple[str, str]] = set() + assert _args is not None 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}" @@ -580,6 +584,7 @@ def print_pending_metrics() -> None: return '' return s + assert j.metric_expr is not None return (fix_none(j.pmu), fix_none(j.metric_name), j.metric_expr.ToPerfJson(), fix_none(j.desc)) @@ -588,6 +593,7 @@ def print_pending_metrics() -> None: return global _pending_metrics_tblname + assert _pending_metrics_tblname is not None if _pending_metrics_tblname.endswith('_sys'): global _sys_metric_tables _sys_metric_tables.append(_pending_metrics_tblname) @@ -597,7 +603,8 @@ def print_pending_metrics() -> None: first = True last_pmu = None - pmus = set() + pmus: Set[Tuple[str, str]] = set() + assert _args is not None for metric in sorted(_pending_metrics, key=metric_cmp_key): if metric.pmu != last_pmu: if not first: @@ -633,7 +640,6 @@ def get_topic(topic: str) -> str: return removesuffix(topic, '.json').replace('-', ' ') def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None: - if item.is_dir(): return @@ -647,6 +653,7 @@ def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None: if not item.is_file() or not item.name.endswith('.json'): return + assert _bcs is not None if item.name.endswith('metricgroups.json'): metricgroup_descriptions = json.load(open(item.path)) for mgroup in metricgroup_descriptions: @@ -708,6 +715,7 @@ def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None: def print_mapping_table(archs: Sequence[str]) -> None: """Read the mapfile and generate the struct from cpuid string to event table.""" + assert _args is not None _args.output_file.write(""" /* Struct used to make the PMU event table implementation opaque to callers. */ struct pmu_events_table { @@ -825,6 +833,7 @@ static const struct pmu_events_map pmu_events_map[] = { def print_metric_table_functions() -> None: + assert _args is not None _args.output_file.write(""" const char *pmu_metrics_table__name(const struct pmu_metrics_table *table) { @@ -868,6 +877,7 @@ int pmu_metrics_table__iterate_tables(pmu_metrics_table_iter_t fn, void *data) def print_system_mapping_table() -> None: + assert _args is not None """C struct mapping table array for tables from /sys directories.""" _args.output_file.write(""" struct pmu_sys_events { @@ -1404,6 +1414,7 @@ int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data) """) def print_metricgroups() -> None: + assert _args is not None _args.output_file.write(""" static const int metricgroups[][2] = { """) @@ -1447,6 +1458,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.""" + assert _args is not None 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. @@ -1517,6 +1529,7 @@ struct pmu_table_entry { preprocess_arch_std_files(arch_path) ftw(arch_path, [], preprocess_one_file) + assert _bcs is not None _bcs.compute() _args.output_file.write('/* clang-format off */\n') if not _args.output_string_file: