* [PATCH v2 1/3] perf list: Print matching PMU events for --unit
@ 2025-11-20 0:47 Namhyung Kim
2025-11-20 0:47 ` [PATCH v2 2/3] perf list: Share print state with JSON output Namhyung Kim
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Namhyung Kim @ 2025-11-20 0:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ian Rogers, James Clark
Cc: Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML,
linux-perf-users
When --unit option is used, pmu_glob is set to the argument. It should
match with event PMU and display the matching ones only. But it also
shows raw events and metrics after that.
$ perf list --unit tool
List of pre-defined events (to be used in -e or -M):
tool:
core_wide
[1 if not SMT,if SMT are events being gathered on all SMT threads 1 otherwise 0. Unit: tool]
duration_time
[Wall clock interval time in nanoseconds. Unit: tool]
has_pmem
[1 if persistent memory installed otherwise 0. Unit: tool]
num_cores
[Number of cores. A core consists of 1 or more thread,with each thread being associated with a logical Linux CPU. Unit: tool]
num_cpus
[Number of logical Linux CPUs. There may be multiple such CPUs on a core. Unit: tool]
...
rNNN [Raw event descriptor]
cpu/event=0..255,pc,edge,.../modifier [Raw event descriptor]
[(see 'man perf-list' or 'man perf-record' on how to encode it)]
breakpoint//modifier [Raw event descriptor]
cstate_core/event=0..0xffffffffffffffff/modifier [Raw event descriptor]
cstate_pkg/event=0..0xffffffffffffffff/modifier [Raw event descriptor]
drm_i915//modifier [Raw event descriptor]
hwmon_acpitz//modifier [Raw event descriptor]
hwmon_ac//modifier [Raw event descriptor]
hwmon_bat0//modifier [Raw event descriptor]
hwmon_coretemp//modifier [Raw event descriptor]
...
Metric Groups:
Backend: [Grouping from Top-down Microarchitecture Analysis Metrics spreadsheet]
tma_core_bound
[This metric represents fraction of slots where Core non-memory issues were of a bottleneck]
tma_info_core_ilp
[Instruction-Level-Parallelism (average number of uops executed when there is execution) per thread (logical-processor)]
tma_info_memory_l2mpki
[L2 cache true misses per kilo instruction for retired demand loads]
...
This change makes it print the tool PMU events only.
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/builtin-list.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 16400366f8276a7a..28bf1fc7f5eeff8f 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -130,7 +130,7 @@ static void default_print_event(void *ps, const char *topic,
if (deprecated && !print_state->deprecated)
return;
- if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_state->pmu_glob))
+ if (print_state->pmu_glob && (!pmu_name || !strglobmatch(pmu_name, print_state->pmu_glob)))
return;
if (print_state->exclude_abi && pmu_type < PERF_TYPE_MAX && pmu_type != PERF_TYPE_RAW)
@@ -612,8 +612,10 @@ int cmd_list(int argc, const char **argv)
print_cb.print_start(ps);
if (argc == 0) {
- default_ps.metrics = true;
- default_ps.metricgroups = true;
+ if (!unit_name) {
+ default_ps.metrics = true;
+ default_ps.metricgroups = true;
+ }
print_events(&print_cb, ps);
goto out;
}
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/3] perf list: Share print state with JSON output 2025-11-20 0:47 [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim @ 2025-11-20 0:47 ` Namhyung Kim 2025-11-20 5:30 ` Ian Rogers 2025-11-20 0:47 ` [PATCH v2 3/3] perf list: Support filtering in " Namhyung Kim 2025-11-21 20:02 ` [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim 2 siblings, 1 reply; 7+ messages in thread From: Namhyung Kim @ 2025-11-20 0:47 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Ian Rogers, James Clark Cc: Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML, linux-perf-users The JSON print state has only one different field (need_sep). Let's add the default print state to the json state and use it. Then we can use the 'ps' variable to update the state properly. This is a preparation for the next commit. Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- tools/perf/builtin-list.c | 127 +++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 28bf1fc7f5eeff8f..6c5913f129f39c94 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -283,8 +283,8 @@ static void default_print_metric(void *ps, } struct json_print_state { - /** @fp: File to write output to. */ - FILE *fp; + /** The shared print_state */ + struct print_state common; /** Should a separator be printed prior to the next item? */ bool need_sep; }; @@ -292,7 +292,7 @@ struct json_print_state { static void json_print_start(void *ps) { struct json_print_state *print_state = ps; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; fprintf(fp, "[\n"); } @@ -300,7 +300,7 @@ static void json_print_start(void *ps) static void json_print_end(void *ps) { struct json_print_state *print_state = ps; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; fprintf(fp, "%s]\n", print_state->need_sep ? "\n" : ""); } @@ -370,7 +370,7 @@ static void json_print_event(void *ps, const char *topic, { struct json_print_state *print_state = ps; bool need_sep = false; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; struct strbuf buf; strbuf_init(&buf, 0); @@ -446,7 +446,7 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, { struct json_print_state *print_state = ps; bool need_sep = false; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; struct strbuf buf; strbuf_init(&buf, 0); @@ -521,10 +521,12 @@ int cmd_list(int argc, const char **argv) .fp = stdout, .desc = true, }; - struct print_state json_ps = { - .fp = stdout, + struct json_print_state json_ps = { + .common = { + .fp = stdout, + }, }; - void *ps = &default_ps; + struct print_state *ps = &default_ps; struct print_callbacks print_cb = { .print_start = default_print_start, .print_end = default_print_end, @@ -572,9 +574,11 @@ int cmd_list(int argc, const char **argv) argc = parse_options(argc, argv, list_options, list_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (json) + ps = &json_ps.common; + if (output_path) { - default_ps.fp = fopen(output_path, "w"); - json_ps.fp = default_ps.fp; + ps->fp = fopen(output_path, "w"); } setup_pager(); @@ -590,14 +594,13 @@ int cmd_list(int argc, const char **argv) .print_metric = json_print_metric, .skip_duplicate_pmus = json_skip_duplicate_pmus, }; - ps = &json_ps; } else { - default_ps.last_topic = strdup(""); - assert(default_ps.last_topic); - default_ps.visited_metrics = strlist__new(NULL, NULL); - assert(default_ps.visited_metrics); + ps->last_topic = strdup(""); + assert(ps->last_topic); + ps->visited_metrics = strlist__new(NULL, NULL); + assert(ps->visited_metrics); if (unit_name) - default_ps.pmu_glob = strdup(unit_name); + ps->pmu_glob = strdup(unit_name); else if (cputype) { const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype); @@ -606,15 +609,15 @@ int cmd_list(int argc, const char **argv) ret = -1; goto out; } - default_ps.pmu_glob = strdup(pmu->name); + ps->pmu_glob = strdup(pmu->name); } } print_cb.print_start(ps); if (argc == 0) { if (!unit_name) { - default_ps.metrics = true; - default_ps.metricgroups = true; + ps->metrics = true; + ps->metricgroups = true; } print_events(&print_cb, ps); goto out; @@ -636,57 +639,57 @@ int cmd_list(int argc, const char **argv) default_ps.pmu_glob = old_pmu_glob; } else if (strcmp(argv[i], "hw") == 0 || strcmp(argv[i], "hardware") == 0) { - char *old_event_glob = default_ps.event_glob; + char *old_event_glob = ps->event_glob; - default_ps.event_glob = strdup("legacy hardware"); - if (!default_ps.event_glob) { + ps->event_glob = strdup("legacy hardware"); + if (!ps->event_glob) { ret = -1; goto out; } perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.event_glob); - default_ps.event_glob = old_event_glob; + zfree(&ps->event_glob); + ps->event_glob = old_event_glob; } else if (strcmp(argv[i], "sw") == 0 || strcmp(argv[i], "software") == 0) { - char *old_pmu_glob = default_ps.pmu_glob; + char *old_pmu_glob = ps->pmu_glob; static const char * const sw_globs[] = { "software", "tool" }; for (size_t j = 0; j < ARRAY_SIZE(sw_globs); j++) { - default_ps.pmu_glob = strdup(sw_globs[j]); - if (!default_ps.pmu_glob) { + ps->pmu_glob = strdup(sw_globs[j]); + if (!ps->pmu_glob) { ret = -1; goto out; } perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.pmu_glob); + zfree(&ps->pmu_glob); } - default_ps.pmu_glob = old_pmu_glob; + ps->pmu_glob = old_pmu_glob; } else if (strcmp(argv[i], "cache") == 0 || strcmp(argv[i], "hwcache") == 0) { - char *old_event_glob = default_ps.event_glob; + char *old_event_glob = ps->event_glob; - default_ps.event_glob = strdup("legacy cache"); - if (!default_ps.event_glob) { + ps->event_glob = strdup("legacy cache"); + if (!ps->event_glob) { ret = -1; goto out; } perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.event_glob); - default_ps.event_glob = old_event_glob; + zfree(&ps->event_glob); + ps->event_glob = old_event_glob; } else if (strcmp(argv[i], "pmu") == 0) { - default_ps.exclude_abi = true; + ps->exclude_abi = true; perf_pmus__print_pmu_events(&print_cb, ps); - default_ps.exclude_abi = false; + ps->exclude_abi = false; } else if (strcmp(argv[i], "sdt") == 0) print_sdt_events(&print_cb, ps); else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { - default_ps.metricgroups = false; - default_ps.metrics = true; + ps->metricgroups = false; + ps->metrics = true; metricgroup__print(&print_cb, ps); } else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) { - default_ps.metricgroups = true; - default_ps.metrics = false; + ps->metricgroups = true; + ps->metrics = false; metricgroup__print(&print_cb, ps); } #ifdef HAVE_LIBPFM @@ -694,40 +697,40 @@ int cmd_list(int argc, const char **argv) print_libpfm_events(&print_cb, ps); #endif else if ((sep = strchr(argv[i], ':')) != NULL) { - char *old_pmu_glob = default_ps.pmu_glob; - char *old_event_glob = default_ps.event_glob; + char *old_pmu_glob = ps->pmu_glob; + char *old_event_glob = ps->event_glob; - default_ps.event_glob = strdup(argv[i]); - if (!default_ps.event_glob) { + ps->event_glob = strdup(argv[i]); + if (!ps->event_glob) { ret = -1; goto out; } - default_ps.pmu_glob = strdup("tracepoint"); - if (!default_ps.pmu_glob) { - zfree(&default_ps.event_glob); + ps->pmu_glob = strdup("tracepoint"); + if (!ps->pmu_glob) { + zfree(&ps->event_glob); ret = -1; goto out; } perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.pmu_glob); - default_ps.pmu_glob = old_pmu_glob; + zfree(&ps->pmu_glob); + ps->pmu_glob = old_pmu_glob; print_sdt_events(&print_cb, ps); - default_ps.metrics = true; - default_ps.metricgroups = true; + ps->metrics = true; + ps->metricgroups = true; metricgroup__print(&print_cb, ps); - zfree(&default_ps.event_glob); - default_ps.event_glob = old_event_glob; + zfree(&ps->event_glob); + ps->event_glob = old_event_glob; } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); continue; } - default_ps.event_glob = s; + ps->event_glob = s; perf_pmus__print_pmu_events(&print_cb, ps); print_sdt_events(&print_cb, ps); - default_ps.metrics = true; - default_ps.metricgroups = true; + ps->metrics = true; + ps->metricgroups = true; metricgroup__print(&print_cb, ps); free(s); } @@ -735,12 +738,12 @@ int cmd_list(int argc, const char **argv) out: print_cb.print_end(ps); - free(default_ps.pmu_glob); - free(default_ps.last_topic); - free(default_ps.last_metricgroups); - strlist__delete(default_ps.visited_metrics); + free(ps->pmu_glob); + free(ps->last_topic); + free(ps->last_metricgroups); + strlist__delete(ps->visited_metrics); if (output_path) - fclose(default_ps.fp); + fclose(ps->fp); return ret; } -- 2.52.0.rc1.455.g30608eb744-goog ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/3] perf list: Share print state with JSON output 2025-11-20 0:47 ` [PATCH v2 2/3] perf list: Share print state with JSON output Namhyung Kim @ 2025-11-20 5:30 ` Ian Rogers 0 siblings, 0 replies; 7+ messages in thread From: Ian Rogers @ 2025-11-20 5:30 UTC (permalink / raw) To: Namhyung Kim Cc: Arnaldo Carvalho de Melo, James Clark, Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML, linux-perf-users On Wed, Nov 19, 2025 at 4:47 PM Namhyung Kim <namhyung@kernel.org> wrote: > > The JSON print state has only one different field (need_sep). Let's > add the default print state to the json state and use it. Then we can > use the 'ps' variable to update the state properly. > > This is a preparation for the next commit. > > Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Thanks, Ian > --- > tools/perf/builtin-list.c | 127 +++++++++++++++++++------------------- > 1 file changed, 65 insertions(+), 62 deletions(-) > > diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c > index 28bf1fc7f5eeff8f..6c5913f129f39c94 100644 > --- a/tools/perf/builtin-list.c > +++ b/tools/perf/builtin-list.c > @@ -283,8 +283,8 @@ static void default_print_metric(void *ps, > } > > struct json_print_state { > - /** @fp: File to write output to. */ > - FILE *fp; > + /** The shared print_state */ > + struct print_state common; > /** Should a separator be printed prior to the next item? */ > bool need_sep; > }; > @@ -292,7 +292,7 @@ struct json_print_state { > static void json_print_start(void *ps) > { > struct json_print_state *print_state = ps; > - FILE *fp = print_state->fp; > + FILE *fp = print_state->common.fp; > > fprintf(fp, "[\n"); > } > @@ -300,7 +300,7 @@ static void json_print_start(void *ps) > static void json_print_end(void *ps) > { > struct json_print_state *print_state = ps; > - FILE *fp = print_state->fp; > + FILE *fp = print_state->common.fp; > > fprintf(fp, "%s]\n", print_state->need_sep ? "\n" : ""); > } > @@ -370,7 +370,7 @@ static void json_print_event(void *ps, const char *topic, > { > struct json_print_state *print_state = ps; > bool need_sep = false; > - FILE *fp = print_state->fp; > + FILE *fp = print_state->common.fp; > struct strbuf buf; > > strbuf_init(&buf, 0); > @@ -446,7 +446,7 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, > { > struct json_print_state *print_state = ps; > bool need_sep = false; > - FILE *fp = print_state->fp; > + FILE *fp = print_state->common.fp; > struct strbuf buf; > > strbuf_init(&buf, 0); > @@ -521,10 +521,12 @@ int cmd_list(int argc, const char **argv) > .fp = stdout, > .desc = true, > }; > - struct print_state json_ps = { > - .fp = stdout, > + struct json_print_state json_ps = { > + .common = { > + .fp = stdout, > + }, > }; > - void *ps = &default_ps; > + struct print_state *ps = &default_ps; > struct print_callbacks print_cb = { > .print_start = default_print_start, > .print_end = default_print_end, > @@ -572,9 +574,11 @@ int cmd_list(int argc, const char **argv) > argc = parse_options(argc, argv, list_options, list_usage, > PARSE_OPT_STOP_AT_NON_OPTION); > > + if (json) > + ps = &json_ps.common; > + > if (output_path) { > - default_ps.fp = fopen(output_path, "w"); > - json_ps.fp = default_ps.fp; > + ps->fp = fopen(output_path, "w"); > } > > setup_pager(); > @@ -590,14 +594,13 @@ int cmd_list(int argc, const char **argv) > .print_metric = json_print_metric, > .skip_duplicate_pmus = json_skip_duplicate_pmus, > }; > - ps = &json_ps; > } else { > - default_ps.last_topic = strdup(""); > - assert(default_ps.last_topic); > - default_ps.visited_metrics = strlist__new(NULL, NULL); > - assert(default_ps.visited_metrics); > + ps->last_topic = strdup(""); > + assert(ps->last_topic); > + ps->visited_metrics = strlist__new(NULL, NULL); > + assert(ps->visited_metrics); > if (unit_name) > - default_ps.pmu_glob = strdup(unit_name); > + ps->pmu_glob = strdup(unit_name); > else if (cputype) { > const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype); > > @@ -606,15 +609,15 @@ int cmd_list(int argc, const char **argv) > ret = -1; > goto out; > } > - default_ps.pmu_glob = strdup(pmu->name); > + ps->pmu_glob = strdup(pmu->name); > } > } > print_cb.print_start(ps); > > if (argc == 0) { > if (!unit_name) { > - default_ps.metrics = true; > - default_ps.metricgroups = true; > + ps->metrics = true; > + ps->metricgroups = true; > } > print_events(&print_cb, ps); > goto out; > @@ -636,57 +639,57 @@ int cmd_list(int argc, const char **argv) > default_ps.pmu_glob = old_pmu_glob; > } else if (strcmp(argv[i], "hw") == 0 || > strcmp(argv[i], "hardware") == 0) { > - char *old_event_glob = default_ps.event_glob; > + char *old_event_glob = ps->event_glob; > > - default_ps.event_glob = strdup("legacy hardware"); > - if (!default_ps.event_glob) { > + ps->event_glob = strdup("legacy hardware"); > + if (!ps->event_glob) { > ret = -1; > goto out; > } > perf_pmus__print_pmu_events(&print_cb, ps); > - zfree(&default_ps.event_glob); > - default_ps.event_glob = old_event_glob; > + zfree(&ps->event_glob); > + ps->event_glob = old_event_glob; > } else if (strcmp(argv[i], "sw") == 0 || > strcmp(argv[i], "software") == 0) { > - char *old_pmu_glob = default_ps.pmu_glob; > + char *old_pmu_glob = ps->pmu_glob; > static const char * const sw_globs[] = { "software", "tool" }; > > for (size_t j = 0; j < ARRAY_SIZE(sw_globs); j++) { > - default_ps.pmu_glob = strdup(sw_globs[j]); > - if (!default_ps.pmu_glob) { > + ps->pmu_glob = strdup(sw_globs[j]); > + if (!ps->pmu_glob) { > ret = -1; > goto out; > } > perf_pmus__print_pmu_events(&print_cb, ps); > - zfree(&default_ps.pmu_glob); > + zfree(&ps->pmu_glob); > } > - default_ps.pmu_glob = old_pmu_glob; > + ps->pmu_glob = old_pmu_glob; > } else if (strcmp(argv[i], "cache") == 0 || > strcmp(argv[i], "hwcache") == 0) { > - char *old_event_glob = default_ps.event_glob; > + char *old_event_glob = ps->event_glob; > > - default_ps.event_glob = strdup("legacy cache"); > - if (!default_ps.event_glob) { > + ps->event_glob = strdup("legacy cache"); > + if (!ps->event_glob) { > ret = -1; > goto out; > } > perf_pmus__print_pmu_events(&print_cb, ps); > - zfree(&default_ps.event_glob); > - default_ps.event_glob = old_event_glob; > + zfree(&ps->event_glob); > + ps->event_glob = old_event_glob; > } else if (strcmp(argv[i], "pmu") == 0) { > - default_ps.exclude_abi = true; > + ps->exclude_abi = true; > perf_pmus__print_pmu_events(&print_cb, ps); > - default_ps.exclude_abi = false; > + ps->exclude_abi = false; > } else if (strcmp(argv[i], "sdt") == 0) > print_sdt_events(&print_cb, ps); > else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { > - default_ps.metricgroups = false; > - default_ps.metrics = true; > + ps->metricgroups = false; > + ps->metrics = true; > metricgroup__print(&print_cb, ps); > } else if (strcmp(argv[i], "metricgroup") == 0 || > strcmp(argv[i], "metricgroups") == 0) { > - default_ps.metricgroups = true; > - default_ps.metrics = false; > + ps->metricgroups = true; > + ps->metrics = false; > metricgroup__print(&print_cb, ps); > } > #ifdef HAVE_LIBPFM > @@ -694,40 +697,40 @@ int cmd_list(int argc, const char **argv) > print_libpfm_events(&print_cb, ps); > #endif > else if ((sep = strchr(argv[i], ':')) != NULL) { > - char *old_pmu_glob = default_ps.pmu_glob; > - char *old_event_glob = default_ps.event_glob; > + char *old_pmu_glob = ps->pmu_glob; > + char *old_event_glob = ps->event_glob; > > - default_ps.event_glob = strdup(argv[i]); > - if (!default_ps.event_glob) { > + ps->event_glob = strdup(argv[i]); > + if (!ps->event_glob) { > ret = -1; > goto out; > } > > - default_ps.pmu_glob = strdup("tracepoint"); > - if (!default_ps.pmu_glob) { > - zfree(&default_ps.event_glob); > + ps->pmu_glob = strdup("tracepoint"); > + if (!ps->pmu_glob) { > + zfree(&ps->event_glob); > ret = -1; > goto out; > } > perf_pmus__print_pmu_events(&print_cb, ps); > - zfree(&default_ps.pmu_glob); > - default_ps.pmu_glob = old_pmu_glob; > + zfree(&ps->pmu_glob); > + ps->pmu_glob = old_pmu_glob; > print_sdt_events(&print_cb, ps); > - default_ps.metrics = true; > - default_ps.metricgroups = true; > + ps->metrics = true; > + ps->metricgroups = true; > metricgroup__print(&print_cb, ps); > - zfree(&default_ps.event_glob); > - default_ps.event_glob = old_event_glob; > + zfree(&ps->event_glob); > + ps->event_glob = old_event_glob; > } else { > if (asprintf(&s, "*%s*", argv[i]) < 0) { > printf("Critical: Not enough memory! Trying to continue...\n"); > continue; > } > - default_ps.event_glob = s; > + ps->event_glob = s; > perf_pmus__print_pmu_events(&print_cb, ps); > print_sdt_events(&print_cb, ps); > - default_ps.metrics = true; > - default_ps.metricgroups = true; > + ps->metrics = true; > + ps->metricgroups = true; > metricgroup__print(&print_cb, ps); > free(s); > } > @@ -735,12 +738,12 @@ int cmd_list(int argc, const char **argv) > > out: > print_cb.print_end(ps); > - free(default_ps.pmu_glob); > - free(default_ps.last_topic); > - free(default_ps.last_metricgroups); > - strlist__delete(default_ps.visited_metrics); > + free(ps->pmu_glob); > + free(ps->last_topic); > + free(ps->last_metricgroups); > + strlist__delete(ps->visited_metrics); > if (output_path) > - fclose(default_ps.fp); > + fclose(ps->fp); > > return ret; > } > -- > 2.52.0.rc1.455.g30608eb744-goog > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] perf list: Support filtering in JSON output 2025-11-20 0:47 [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim 2025-11-20 0:47 ` [PATCH v2 2/3] perf list: Share print state with JSON output Namhyung Kim @ 2025-11-20 0:47 ` Namhyung Kim 2025-11-20 5:42 ` Ian Rogers 2025-11-21 20:02 ` [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim 2 siblings, 1 reply; 7+ messages in thread From: Namhyung Kim @ 2025-11-20 0:47 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Ian Rogers, James Clark Cc: Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML, linux-perf-users Like regular output mode, it should honor command line arguments to limit to a certain type of PMUs or events. $ perf list -j hw [ { "Unit": "cpu", "Topic": "legacy hardware", "EventName": "branch-instructions", "EventType": "Kernel PMU event", "BriefDescription": "Retired branch instructions [This event is an alias of branches]", "Encoding": "cpu/event=0xc4\n/" }, { "Unit": "cpu", "Topic": "legacy hardware", "EventName": "branch-misses", "EventType": "Kernel PMU event", "BriefDescription": "Mispredicted branch instructions", "Encoding": "cpu/event=0xc5\n/" }, ... Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- tools/perf/builtin-list.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 6c5913f129f39c94..5cbca0bacd35237e 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -373,6 +373,23 @@ static void json_print_event(void *ps, const char *topic, FILE *fp = print_state->common.fp; struct strbuf buf; + if (deprecated && !print_state->common.deprecated) + return; + + if (print_state->common.pmu_glob && + (!pmu_name || !strglobmatch(pmu_name, print_state->common.pmu_glob))) + return; + + if (print_state->common.exclude_abi && pmu_type < PERF_TYPE_MAX && + pmu_type != PERF_TYPE_RAW) + return; + + if (print_state->common.event_glob && + (!event_name || !strglobmatch(event_name, print_state->common.event_glob)) && + (!event_alias || !strglobmatch(event_alias, print_state->common.event_glob)) && + (!topic || !strglobmatch_nocase(topic, print_state->common.event_glob))) + return; + strbuf_init(&buf, 0); fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); print_state->need_sep = true; @@ -449,6 +466,13 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, FILE *fp = print_state->common.fp; struct strbuf buf; + if (print_state->common.event_glob && + (!print_state->common.metrics || !name || + !strglobmatch(name, print_state->common.event_glob)) && + (!print_state->common.metricgroups || !group || + !strglobmatch(group, print_state->common.event_glob))) + return; + strbuf_init(&buf, 0); fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); print_state->need_sep = true; -- 2.52.0.rc1.455.g30608eb744-goog ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 3/3] perf list: Support filtering in JSON output 2025-11-20 0:47 ` [PATCH v2 3/3] perf list: Support filtering in " Namhyung Kim @ 2025-11-20 5:42 ` Ian Rogers 2025-11-20 19:11 ` Namhyung Kim 0 siblings, 1 reply; 7+ messages in thread From: Ian Rogers @ 2025-11-20 5:42 UTC (permalink / raw) To: Namhyung Kim Cc: Arnaldo Carvalho de Melo, James Clark, Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML, linux-perf-users On Wed, Nov 19, 2025 at 4:47 PM Namhyung Kim <namhyung@kernel.org> wrote: > > Like regular output mode, it should honor command line arguments to > limit to a certain type of PMUs or events. > > $ perf list -j hw > [ > { > "Unit": "cpu", > "Topic": "legacy hardware", > "EventName": "branch-instructions", > "EventType": "Kernel PMU event", > "BriefDescription": "Retired branch instructions [This event is an alias of branches]", > "Encoding": "cpu/event=0xc4\n/" > }, > { > "Unit": "cpu", > "Topic": "legacy hardware", > "EventName": "branch-misses", > "EventType": "Kernel PMU event", > "BriefDescription": "Mispredicted branch instructions", > "Encoding": "cpu/event=0xc5\n/" I think these newlines can be fixed by changing: https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmu.c?h=perf-tools-next#n643 ``` ret = io__getline(&io, &alias->terms, &line_len) < 0 ? -errno : 0; if (ret) { ... } ``` to something like: ``` ret = io__getline(&io, &alias->terms, &line_len) < 0 ? -errno : 0; if (ret) { ... } if (alias->terms[line_len - 1] == '\n') alias->terms[line_len - 1] = '\0'; ``` > }, > ... > > Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Thanks, Ian > --- > tools/perf/builtin-list.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c > index 6c5913f129f39c94..5cbca0bacd35237e 100644 > --- a/tools/perf/builtin-list.c > +++ b/tools/perf/builtin-list.c > @@ -373,6 +373,23 @@ static void json_print_event(void *ps, const char *topic, > FILE *fp = print_state->common.fp; > struct strbuf buf; > > + if (deprecated && !print_state->common.deprecated) > + return; > + > + if (print_state->common.pmu_glob && > + (!pmu_name || !strglobmatch(pmu_name, print_state->common.pmu_glob))) > + return; > + > + if (print_state->common.exclude_abi && pmu_type < PERF_TYPE_MAX && > + pmu_type != PERF_TYPE_RAW) > + return; > + > + if (print_state->common.event_glob && > + (!event_name || !strglobmatch(event_name, print_state->common.event_glob)) && > + (!event_alias || !strglobmatch(event_alias, print_state->common.event_glob)) && > + (!topic || !strglobmatch_nocase(topic, print_state->common.event_glob))) > + return; > + > strbuf_init(&buf, 0); > fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); > print_state->need_sep = true; > @@ -449,6 +466,13 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, > FILE *fp = print_state->common.fp; > struct strbuf buf; > > + if (print_state->common.event_glob && > + (!print_state->common.metrics || !name || > + !strglobmatch(name, print_state->common.event_glob)) && > + (!print_state->common.metricgroups || !group || > + !strglobmatch(group, print_state->common.event_glob))) > + return; > + > strbuf_init(&buf, 0); > fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); > print_state->need_sep = true; > -- > 2.52.0.rc1.455.g30608eb744-goog > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 3/3] perf list: Support filtering in JSON output 2025-11-20 5:42 ` Ian Rogers @ 2025-11-20 19:11 ` Namhyung Kim 0 siblings, 0 replies; 7+ messages in thread From: Namhyung Kim @ 2025-11-20 19:11 UTC (permalink / raw) To: Ian Rogers Cc: Arnaldo Carvalho de Melo, James Clark, Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML, linux-perf-users On Wed, Nov 19, 2025 at 09:42:51PM -0800, Ian Rogers wrote: > On Wed, Nov 19, 2025 at 4:47 PM Namhyung Kim <namhyung@kernel.org> wrote: > > > > Like regular output mode, it should honor command line arguments to > > limit to a certain type of PMUs or events. > > > > $ perf list -j hw > > [ > > { > > "Unit": "cpu", > > "Topic": "legacy hardware", > > "EventName": "branch-instructions", > > "EventType": "Kernel PMU event", > > "BriefDescription": "Retired branch instructions [This event is an alias of branches]", > > "Encoding": "cpu/event=0xc4\n/" > > }, > > { > > "Unit": "cpu", > > "Topic": "legacy hardware", > > "EventName": "branch-misses", > > "EventType": "Kernel PMU event", > > "BriefDescription": "Mispredicted branch instructions", > > "Encoding": "cpu/event=0xc5\n/" > > I think these newlines can be fixed by changing: > https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmu.c?h=perf-tools-next#n643 > ``` > ret = io__getline(&io, &alias->terms, &line_len) < 0 ? -errno : 0; > if (ret) { > ... > } > ``` > to something like: > ``` > ret = io__getline(&io, &alias->terms, &line_len) < 0 ? -errno : 0; > if (ret) { > ... > } > if (alias->terms[line_len - 1] == '\n') > alias->terms[line_len - 1] = '\0'; > ``` Yep, will do in a separate patch. > > > }, > > ... > > > > Signed-off-by: Namhyung Kim <namhyung@kernel.org> > > Reviewed-by: Ian Rogers <irogers@google.com> Thanks for your review! Namhyung > > --- > > tools/perf/builtin-list.c | 24 ++++++++++++++++++++++++ > > 1 file changed, 24 insertions(+) > > > > diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c > > index 6c5913f129f39c94..5cbca0bacd35237e 100644 > > --- a/tools/perf/builtin-list.c > > +++ b/tools/perf/builtin-list.c > > @@ -373,6 +373,23 @@ static void json_print_event(void *ps, const char *topic, > > FILE *fp = print_state->common.fp; > > struct strbuf buf; > > > > + if (deprecated && !print_state->common.deprecated) > > + return; > > + > > + if (print_state->common.pmu_glob && > > + (!pmu_name || !strglobmatch(pmu_name, print_state->common.pmu_glob))) > > + return; > > + > > + if (print_state->common.exclude_abi && pmu_type < PERF_TYPE_MAX && > > + pmu_type != PERF_TYPE_RAW) > > + return; > > + > > + if (print_state->common.event_glob && > > + (!event_name || !strglobmatch(event_name, print_state->common.event_glob)) && > > + (!event_alias || !strglobmatch(event_alias, print_state->common.event_glob)) && > > + (!topic || !strglobmatch_nocase(topic, print_state->common.event_glob))) > > + return; > > + > > strbuf_init(&buf, 0); > > fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); > > print_state->need_sep = true; > > @@ -449,6 +466,13 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, > > FILE *fp = print_state->common.fp; > > struct strbuf buf; > > > > + if (print_state->common.event_glob && > > + (!print_state->common.metrics || !name || > > + !strglobmatch(name, print_state->common.event_glob)) && > > + (!print_state->common.metricgroups || !group || > > + !strglobmatch(group, print_state->common.event_glob))) > > + return; > > + > > strbuf_init(&buf, 0); > > fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); > > print_state->need_sep = true; > > -- > > 2.52.0.rc1.455.g30608eb744-goog > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] perf list: Print matching PMU events for --unit 2025-11-20 0:47 [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim 2025-11-20 0:47 ` [PATCH v2 2/3] perf list: Share print state with JSON output Namhyung Kim 2025-11-20 0:47 ` [PATCH v2 3/3] perf list: Support filtering in " Namhyung Kim @ 2025-11-21 20:02 ` Namhyung Kim 2 siblings, 0 replies; 7+ messages in thread From: Namhyung Kim @ 2025-11-21 20:02 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Ian Rogers, James Clark, Namhyung Kim Cc: Jiri Olsa, Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML, linux-perf-users On Wed, 19 Nov 2025 16:47:24 -0800, Namhyung Kim wrote: > When --unit option is used, pmu_glob is set to the argument. It should > match with event PMU and display the matching ones only. But it also > shows raw events and metrics after that. > > $ perf list --unit tool > List of pre-defined events (to be used in -e or -M): > > [...] Applied to perf-tools-next, thanks! Best regards, Namhyung ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-11-21 20:02 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-20 0:47 [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim 2025-11-20 0:47 ` [PATCH v2 2/3] perf list: Share print state with JSON output Namhyung Kim 2025-11-20 5:30 ` Ian Rogers 2025-11-20 0:47 ` [PATCH v2 3/3] perf list: Support filtering in " Namhyung Kim 2025-11-20 5:42 ` Ian Rogers 2025-11-20 19:11 ` Namhyung Kim 2025-11-21 20:02 ` [PATCH v2 1/3] perf list: Print matching PMU events for --unit Namhyung Kim
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).