perf parse-events: Remove non-json software events

Remove the hard coded encodings from parse-events. This has the
consequence that software events are matched using the sysfs/json
priority, will be case insensitive and will be wildcarded across PMUs.
As there were software and hardware types in the parsing code, the
removal means software vs hardware logic can be removed and hardware
assumed.

Now the perf json provides detailed descriptions of software events,
remove the previous listing support that didn't contain event
descriptions. When globbing is required for the "sw" option in perf
list, use string PMU globbing as was done previously for the tool PMU.

The output of `perf list sw` command changed like this.

Before:
  List of pre-defined events (to be used in -e or -M):

    alignment-faults                                   [Software event]
    bpf-output                                         [Software event]
    cgroup-switches                                    [Software event]
    context-switches OR cs                             [Software event]
    cpu-clock                                          [Software event]
    cpu-migrations OR migrations                       [Software event]
    dummy                                              [Software event]
    emulation-faults                                   [Software event]
    major-faults                                       [Software event]
    minor-faults                                       [Software event]
    page-faults OR faults                              [Software event]
    task-clock                                         [Software event]

After:
  List of pre-defined events (to be used in -e or -M):

  software:
    alignment-faults
         [Number of kernel handled memory alignment faults. Unit: software]
    bpf-output
         [An event used by BPF programs to write to the perf ring buffer. Unit: software]
    cgroup-switches
         [Number of context switches to a task in a different cgroup. Unit: software]
    context-switches
         [Number of context switches [This event is an alias of cs]. Unit: software]
    cpu-clock
         [Per-CPU high-resolution timer based event. Unit: software]
    cpu-migrations
         [Number of times a process has migrated to a new CPU [This event is an alias of migrations]. Unit: software]
    cs
         [Number of context switches [This event is an alias of context-switches]. Unit: software]
    dummy
         [A placeholder event that doesn't count anything. Unit: software]
    ...

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/r/20250725185202.68671-4-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ian Rogers
2025-07-25 11:51:49 -07:00
committed by Namhyung Kim
parent 9957d8c801
commit 6e9fa4131a
6 changed files with 33 additions and 107 deletions

View File

@@ -623,16 +623,17 @@ int cmd_list(int argc, const char **argv)
else if (strcmp(argv[i], "sw") == 0 ||
strcmp(argv[i], "software") == 0) {
char *old_pmu_glob = default_ps.pmu_glob;
static const char * const sw_globs[] = { "software", "tool" };
print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE,
event_symbols_sw, PERF_COUNT_SW_MAX);
default_ps.pmu_glob = strdup("tool");
if (!default_ps.pmu_glob) {
ret = -1;
goto out;
for (size_t j = 0; j < ARRAY_SIZE(sw_globs); j++) {
default_ps.pmu_glob = strdup(sw_globs[j]);
if (!default_ps.pmu_glob) {
ret = -1;
goto out;
}
perf_pmus__print_pmu_events(&print_cb, ps);
zfree(&default_ps.pmu_glob);
}
perf_pmus__print_pmu_events(&print_cb, ps);
zfree(&default_ps.pmu_glob);
default_ps.pmu_glob = old_pmu_glob;
} else if (strcmp(argv[i], "cache") == 0 ||
strcmp(argv[i], "hwcache") == 0)
@@ -679,8 +680,6 @@ int cmd_list(int argc, const char **argv)
default_ps.event_glob = s;
print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
event_symbols_hw, PERF_COUNT_HW_MAX);
print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE,
event_symbols_sw, PERF_COUNT_SW_MAX);
print_hwcache_events(&print_cb, ps);
perf_pmus__print_pmu_events(&print_cb, ps);
print_tracepoint_events(&print_cb, ps);

View File

@@ -84,57 +84,6 @@ const struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
},
};
const struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
[PERF_COUNT_SW_CPU_CLOCK] = {
.symbol = "cpu-clock",
.alias = "",
},
[PERF_COUNT_SW_TASK_CLOCK] = {
.symbol = "task-clock",
.alias = "",
},
[PERF_COUNT_SW_PAGE_FAULTS] = {
.symbol = "page-faults",
.alias = "faults",
},
[PERF_COUNT_SW_CONTEXT_SWITCHES] = {
.symbol = "context-switches",
.alias = "cs",
},
[PERF_COUNT_SW_CPU_MIGRATIONS] = {
.symbol = "cpu-migrations",
.alias = "migrations",
},
[PERF_COUNT_SW_PAGE_FAULTS_MIN] = {
.symbol = "minor-faults",
.alias = "",
},
[PERF_COUNT_SW_PAGE_FAULTS_MAJ] = {
.symbol = "major-faults",
.alias = "",
},
[PERF_COUNT_SW_ALIGNMENT_FAULTS] = {
.symbol = "alignment-faults",
.alias = "",
},
[PERF_COUNT_SW_EMULATION_FAULTS] = {
.symbol = "emulation-faults",
.alias = "",
},
[PERF_COUNT_SW_DUMMY] = {
.symbol = "dummy",
.alias = "",
},
[PERF_COUNT_SW_BPF_OUTPUT] = {
.symbol = "bpf-output",
.alias = "",
},
[PERF_COUNT_SW_CGROUP_SWITCHES] = {
.symbol = "cgroup-switches",
.alias = "",
},
};
static const char *const event_types[] = {
[PERF_TYPE_HARDWARE] = "hardware",
[PERF_TYPE_SOFTWARE] = "software",

View File

@@ -264,7 +264,6 @@ struct event_symbol {
const char *alias;
};
extern const struct event_symbol event_symbols_hw[];
extern const struct event_symbol event_symbols_sw[];
char *parse_events_formats_error_string(char *additional_terms);

View File

@@ -117,12 +117,12 @@ do { \
yyless(0); \
} while (0)
static int sym(yyscan_t scanner, int type, int config)
static int sym(yyscan_t scanner, int config)
{
YYSTYPE *yylval = parse_events_get_lval(scanner);
yylval->num = (type << 16) + config;
return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
yylval->num = config;
return PE_VALUE_SYM_HW;
}
static int term(yyscan_t scanner, enum parse_events__term_type type)
@@ -391,28 +391,16 @@ r0x{num_raw_hex} { return str(yyscanner, PE_RAW); }
<<EOF>> { BEGIN(INITIAL); }
}
cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); }
cgroup-switches { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CGROUP_SWITCHES); }
cpu-cycles|cycles { return sym(yyscanner, PERF_COUNT_HW_CPU_CYCLES); }
stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
instructions { return sym(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); }
cache-references { return sym(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); }
cache-misses { return sym(yyscanner, PERF_COUNT_HW_CACHE_MISSES); }
branch-instructions|branches { return sym(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
branch-misses { return sym(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); }
bus-cycles { return sym(yyscanner, PERF_COUNT_HW_BUS_CYCLES); }
ref-cycles { return sym(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); }
{lc_type} { return str(yyscanner, PE_LEGACY_CACHE); }
{lc_type}-{lc_op_result} { return str(yyscanner, PE_LEGACY_CACHE); }

View File

@@ -55,7 +55,7 @@ static void free_list_evsel(struct list_head* list_evsel)
%}
%token PE_START_EVENTS PE_START_TERMS
%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM
%token PE_VALUE PE_VALUE_SYM_HW PE_TERM
%token PE_EVENT_NAME
%token PE_RAW PE_NAME
%token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH
@@ -66,10 +66,8 @@ static void free_list_evsel(struct list_head* list_evsel)
%token PE_TERM_HW
%type <num> PE_VALUE
%type <num> PE_VALUE_SYM_HW
%type <num> PE_VALUE_SYM_SW
%type <mod> PE_MODIFIER_EVENT
%type <term_type> PE_TERM
%type <num> value_sym
%type <str> PE_RAW
%type <str> PE_NAME
%type <str> PE_LEGACY_CACHE
@@ -306,24 +304,19 @@ PE_NAME sep_dc
$$ = list;
}
value_sym:
PE_VALUE_SYM_HW
|
PE_VALUE_SYM_SW
event_legacy_symbol:
value_sym '/' event_config '/'
PE_VALUE_SYM_HW '/' event_config '/'
{
struct list_head *list;
int type = $1 >> 16;
int config = $1 & 255;
int err;
bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
list = alloc_list();
if (!list)
YYNOMEM;
err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard);
err = parse_events_add_numeric(_parse_state, list,
PERF_TYPE_HARDWARE, $1,
$3,
/*wildcard=*/true);
parse_events_terms__delete($3);
if (err) {
free_list_evsel(list);
@@ -332,18 +325,18 @@ value_sym '/' event_config '/'
$$ = list;
}
|
value_sym sep_slash_slash_dc
PE_VALUE_SYM_HW sep_slash_slash_dc
{
struct list_head *list;
int type = $1 >> 16;
int config = $1 & 255;
bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
int err;
list = alloc_list();
if (!list)
YYNOMEM;
err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard);
err = parse_events_add_numeric(_parse_state, list,
PERF_TYPE_HARDWARE, $1,
/*head_config=*/NULL,
/*wildcard=*/true);
if (err)
PE_ABORT(err);
$$ = list;

View File

@@ -521,8 +521,6 @@ void print_events(const struct print_callbacks *print_cb, void *print_state)
{
print_symbol_events(print_cb, print_state, PERF_TYPE_HARDWARE,
event_symbols_hw, PERF_COUNT_HW_MAX);
print_symbol_events(print_cb, print_state, PERF_TYPE_SOFTWARE,
event_symbols_sw, PERF_COUNT_SW_MAX);
print_hwcache_events(print_cb, print_state);