mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
perf jevents: Add support for metricgroup descriptions
Metrics have a field where the groups they belong to are listed like the following from tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json: "MetricGroup": "PGO;TmaL1;TopdownL1;tma_L1_group", "MetricName": "tma_frontend_bound", The metric groups are shown in 'perf list' like the following where TopdownL1 is a metric group: TopdownL1: tma_backend_bound [This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend] tma_bad_speculation [This category represents fraction of slots wasted due to incorrect speculations] tma_frontend_bound [This category represents fraction of slots where the processor's Frontend undersupplies its Backend] tma_retiring [This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired] This patch adds support for a new json file in each model directory called metricgroups.json that comprises a dictionary containing entries that map from a metric group to a description: { ... "TopdownL1": "Metrics for top-down breakdown at level 1", ... } perf list is then updated to support this changing the above output to: TopdownL1: [Metrics for top-down breakdown at level 1] Committer notes: Added a (int) cast to the ARRAY_SIZE() introduced in this patch to address: /tmp/build/perf-tools-next/pmu-events/pmu-events.c: In function ‘describe_metricgroup’: /var/home/acme/git/perf-tools-next/tools/include/linux/kernel.h:102:25: error: overflow in conversion from ‘long unsigned int’ to ‘int’ changes value from ‘18446744073709551615’ to ‘-1’ [-Werror=overflow] 102 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) | ^ /tmp/build/perf-tools-next/pmu-events/pmu-events.c:61603:29: note: in expansion of macro ‘ARRAY_SIZE’ 61603 | int low = 0, high = ARRAY_SIZE(metricgroups) - 1; | ^~~~~~~~~~ cc1: all warnings being treated as errors Reviewed-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com> Link: https://lore.kernel.org/r/20230517173805.602113-15-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
bfce728db3
commit
66c6e0c100
@ -192,9 +192,14 @@ static void default_print_metric(void *ps,
|
||||
if (group && print_state->metricgroups) {
|
||||
if (print_state->name_only)
|
||||
printf("%s ", group);
|
||||
else if (print_state->metrics)
|
||||
printf("\n%s:\n", group);
|
||||
else if (print_state->metrics) {
|
||||
const char *gdesc = describe_metricgroup(group);
|
||||
|
||||
if (gdesc)
|
||||
printf("\n%s: [%s]\n", group, gdesc);
|
||||
else
|
||||
printf("\n%s:\n", group);
|
||||
} else
|
||||
printf("%s\n", group);
|
||||
}
|
||||
zfree(&print_state->last_metricgroups);
|
||||
|
@ -420,3 +420,8 @@ int pmu_for_each_sys_metric(pmu_metric_iter_fn fn __maybe_unused, void *data __m
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *describe_metricgroup(const char *group __maybe_unused)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ _pending_metrics = []
|
||||
_pending_metrics_tblname = None
|
||||
# Global BigCString shared by all structures.
|
||||
_bcs = None
|
||||
# Map from the name of a metric group to a description of the group.
|
||||
_metricgroups = {}
|
||||
# Order specific JsonEvent attributes will be visited.
|
||||
_json_event_attributes = [
|
||||
# cmp_sevent related attributes.
|
||||
@ -512,6 +514,17 @@ def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
|
||||
if not item.is_file() or not item.name.endswith('.json'):
|
||||
return
|
||||
|
||||
if item.name == 'metricgroups.json':
|
||||
metricgroup_descriptions = json.load(open(item.path))
|
||||
for mgroup in metricgroup_descriptions:
|
||||
assert len(mgroup) > 1, parents
|
||||
description = f"{metricgroup_descriptions[mgroup]}\\000"
|
||||
mgroup = f"{mgroup}\\000"
|
||||
_bcs.add(mgroup)
|
||||
_bcs.add(description)
|
||||
_metricgroups[mgroup] = description
|
||||
return
|
||||
|
||||
topic = get_topic(item.name)
|
||||
for event in read_json_events(item.path, topic):
|
||||
if event.name:
|
||||
@ -548,7 +561,7 @@ def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
|
||||
|
||||
# Ignore other directories. If the file name does not have a .json
|
||||
# extension, ignore it. It could be a readme.txt for instance.
|
||||
if not item.is_file() or not item.name.endswith('.json'):
|
||||
if not item.is_file() or not item.name.endswith('.json') or item.name == 'metricgroups.json':
|
||||
return
|
||||
|
||||
add_events_table_entries(item, get_topic(item.name))
|
||||
@ -911,6 +924,38 @@ int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data)
|
||||
}
|
||||
""")
|
||||
|
||||
def print_metricgroups() -> None:
|
||||
_args.output_file.write("""
|
||||
static const int metricgroups[][2] = {
|
||||
""")
|
||||
for mgroup in sorted(_metricgroups):
|
||||
description = _metricgroups[mgroup]
|
||||
_args.output_file.write(
|
||||
f'\t{{ {_bcs.offsets[mgroup]}, {_bcs.offsets[description]} }}, /* {mgroup} => {description} */\n'
|
||||
)
|
||||
_args.output_file.write("""
|
||||
};
|
||||
|
||||
const char *describe_metricgroup(const char *group)
|
||||
{
|
||||
int low = 0, high = (int)ARRAY_SIZE(metricgroups) - 1;
|
||||
|
||||
while (low <= high) {
|
||||
int mid = (low + high) / 2;
|
||||
const char *mgroup = &big_c_string[metricgroups[mid][0]];
|
||||
int cmp = strcmp(mgroup, group);
|
||||
|
||||
if (cmp == 0) {
|
||||
return &big_c_string[metricgroups[mid][1]];
|
||||
} else if (cmp < 0) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
""")
|
||||
|
||||
def main() -> None:
|
||||
global _args
|
||||
@ -993,7 +1038,7 @@ struct compact_pmu_event {
|
||||
|
||||
print_mapping_table(archs)
|
||||
print_system_mapping_table()
|
||||
|
||||
print_metricgroups()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -93,4 +93,6 @@ const struct pmu_metrics_table *find_sys_metrics_table(const char *name);
|
||||
int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data);
|
||||
int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data);
|
||||
|
||||
const char *describe_metricgroup(const char *group);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user