diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index a4378a0cd914..17e582998474 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt @@ -10,6 +10,7 @@ SYNOPSIS [verse] 'perf list' [] [hw|sw|cache|tracepoint|pmu|sdt|metric|metricgroup|event_glob] +'perf list' --tui [-- ] DESCRIPTION ----------- @@ -51,6 +52,15 @@ Output in JSON format. --output=:: Output file name. By default output is written to stdout. +--tui:: +Rather than printing the events, interactively browse the PMUs, events and +metrics in the terminal using the 'ilist' python script (see +linkperf:perf-script[1]). Selecting an event or metric shows its description +and counts it on each CPU. The script requires the perf python module and the +python 'textual' library. Other options are ignored, arguments after '--' are +passed to the script, for example 'perf list --tui -- -I 0.5' to update the +counts every 0.5 seconds. + [[EVENT_MODIFIERS]] EVENT MODIFIERS --------------- diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 4118424cb364..47668d66c395 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -24,8 +24,10 @@ #include #include #include +#include #include #include +#include /** * struct print_state - State and configuration passed to the default_print @@ -538,6 +540,31 @@ static bool default_skip_duplicate_pmus(void *ps) return !print_state->long_desc; } +/* + * Launch the interactive textual based ilist python script via 'perf script' + * that finds the script and sets up the python environment. Arguments are + * passed to the script. + */ +static int list__tui(int argc, const char **argv) +{ + const char **script_argv; + int script_argc = 0, ret; + + script_argv = calloc(argc + 4, sizeof(*script_argv)); + if (!script_argv) + return -ENOMEM; + + script_argv[script_argc++] = "script"; + script_argv[script_argc++] = "ilist"; + script_argv[script_argc++] = "--"; + for (int i = 0; i < argc; i++) + script_argv[script_argc++] = argv[i]; + + ret = cmd_script(script_argc, script_argv); + free(script_argv); + return ret; +} + int cmd_list(int argc, const char **argv) { int i, ret = 0; @@ -562,6 +589,7 @@ int cmd_list(int argc, const char **argv) const char *unit_name = NULL; const char *output_path = NULL; bool json = false; + bool use_tui = false; struct option list_options[] = { OPT_BOOLEAN(0, "raw-dump", &default_ps.name_only, "Dump raw events"), OPT_BOOLEAN('j', "json", &json, "JSON encode events and metrics"), @@ -578,6 +606,8 @@ int cmd_list(int argc, const char **argv) "Limit PMU or metric printing to the given PMU (e.g. cpu, core or atom)."), OPT_STRING(0, "unit", &unit_name, "PMU name", "Limit PMU or metric printing to the specified PMU."), + OPT_BOOLEAN(0, "tui", &use_tui, + "Interactively browse and count events and metrics with ilist"), OPT_INCR(0, "debug", &verbose, "Enable debugging output"), OPT_END() @@ -588,6 +618,7 @@ int cmd_list(int argc, const char **argv) #else "perf list [] [hw|sw|cache|tracepoint|pmu|sdt|metric|metricgroup|event_glob]", #endif + "perf list --tui [-- ]", NULL }; @@ -598,6 +629,9 @@ int cmd_list(int argc, const char **argv) argc = parse_options(argc, argv, list_options, list_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (use_tui) + return list__tui(argc, argv); + if (json) ps = &json_ps.common;