perf list: Simplify cache event printing

The current code computes an array of cache names then sorts and prints
them. Use a strlist to create a list of names that is sorted. Keep the
hybrid names, it is unclear how to generalize it, but drop the
computation of evt_pmus that is never used.

Signed-off-by: Ian 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: Jiri Olsa <jolsa@kernel.org>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Kang Minchul <tegongkang@gmail.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
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: Weilin Wang <weilin.wang@intel.com>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: http://lore.kernel.org/lkml/20221114210723.2749751-7-irogers@google.com
[ Fixed up clash with cf9f67b363 ("perf print-events: Remove redundant comparison with zero")]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2022-11-14 13:07:19 -08:00 committed by Arnaldo Carvalho de Melo
parent ca0fe62413
commit 3301b3fe9b
1 changed files with 27 additions and 103 deletions

View File

@ -206,135 +206,59 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob,
int print_hwcache_events(const char *event_glob, bool name_only) int print_hwcache_events(const char *event_glob, bool name_only)
{ {
unsigned int type, op, i, evt_i = 0, evt_num = 0, npmus = 0; struct strlist *evt_name_list = strlist__new(NULL, NULL);
char name[64], new_name[128]; struct str_node *nd;
char **evt_list = NULL, **evt_pmus = NULL;
bool evt_num_known = false;
struct perf_pmu *pmu = NULL;
if (perf_pmu__has_hybrid()) { if (!evt_name_list) {
npmus = perf_pmu__hybrid_pmu_num(); pr_debug("Failed to allocate new strlist for hwcache events\n");
evt_pmus = zalloc(sizeof(char *) * npmus); return -ENOMEM;
if (!evt_pmus)
goto out_enomem;
} }
for (int type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
restart: for (int op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
if (evt_num_known) {
evt_list = zalloc(sizeof(char *) * evt_num);
if (!evt_list)
goto out_enomem;
}
for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
/* skip invalid cache type */ /* skip invalid cache type */
if (!evsel__is_cache_op_valid(type, op)) if (!evsel__is_cache_op_valid(type, op))
continue; continue;
for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { for (int i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
unsigned int hybrid_supported = 0, j; struct perf_pmu *pmu = NULL;
bool supported; char name[64];
__evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
if (event_glob != NULL && !strglobmatch(name, event_glob)) if (event_glob != NULL && !strglobmatch(name, event_glob))
continue; continue;
if (!perf_pmu__has_hybrid()) { if (!perf_pmu__has_hybrid()) {
if (!is_event_supported(PERF_TYPE_HW_CACHE, if (is_event_supported(PERF_TYPE_HW_CACHE,
type | (op << 8) | (i << 16))) { type | (op << 8) | (i << 16)))
strlist__add(evt_name_list, name);
continue; continue;
} }
} else {
perf_pmu__for_each_hybrid_pmu(pmu) { perf_pmu__for_each_hybrid_pmu(pmu) {
if (!evt_num_known) { if (is_event_supported(PERF_TYPE_HW_CACHE,
evt_num++;
continue;
}
supported = is_event_supported(
PERF_TYPE_HW_CACHE,
type | (op << 8) | (i << 16) | type | (op << 8) | (i << 16) |
((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)); ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT))) {
if (supported) { char new_name[128];
snprintf(new_name, sizeof(new_name), snprintf(new_name, sizeof(new_name),
"%s/%s/", pmu->name, name); "%s/%s/", pmu->name, name);
evt_pmus[hybrid_supported] = strlist__add(evt_name_list, new_name);
strdup(new_name); }
hybrid_supported++; }
}
} }
} }
if (hybrid_supported == 0) strlist__for_each_entry(nd, evt_name_list) {
continue;
}
if (!evt_num_known) {
evt_num++;
continue;
}
if ((hybrid_supported == 0) ||
(hybrid_supported == npmus)) {
evt_list[evt_i] = strdup(name);
for (j = 0; j < npmus; j++)
zfree(&evt_pmus[j]);
} else {
for (j = 0; j < hybrid_supported; j++) {
evt_list[evt_i++] = evt_pmus[j];
evt_pmus[j] = NULL;
}
continue;
}
if (evt_list[evt_i] == NULL)
goto out_enomem;
evt_i++;
}
}
}
if (!evt_num_known) {
evt_num_known = true;
goto restart;
}
for (evt_i = 0; evt_i < evt_num; evt_i++) {
if (!evt_list[evt_i])
break;
}
evt_num = evt_i;
qsort(evt_list, evt_num, sizeof(char *), cmp_string);
evt_i = 0;
while (evt_i < evt_num) {
if (name_only) { if (name_only) {
printf("%s ", evt_list[evt_i++]); printf("%s ", nd->s);
continue; continue;
} }
printf(" %-50s [%s]\n", evt_list[evt_i++], printf(" %-50s [%s]\n", nd->s, event_type_descriptors[PERF_TYPE_HW_CACHE]);
event_type_descriptors[PERF_TYPE_HW_CACHE]);
} }
if (evt_num && pager_in_use()) if (!strlist__empty(evt_name_list) && pager_in_use())
printf("\n"); printf("\n");
out_free: strlist__delete(evt_name_list);
evt_num = evt_i; return 0;
for (evt_i = 0; evt_i < evt_num; evt_i++)
zfree(&evt_list[evt_i]);
zfree(&evt_list);
for (evt_i = 0; evt_i < npmus; evt_i++)
zfree(&evt_pmus[evt_i]);
zfree(&evt_pmus);
return evt_num;
out_enomem:
printf("FATAL: not enough memory to print %s\n",
event_type_descriptors[PERF_TYPE_HW_CACHE]);
if (evt_list)
goto out_free;
return evt_num;
} }
static void print_tool_event(const struct event_symbol *syms, const char *event_glob, static void print_tool_event(const struct event_symbol *syms, const char *event_glob,