Commit 6e9fa413 authored by Ian Rogers's avatar Ian Rogers Committed by Namhyung Kim
Browse files

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: default avatarIan Rogers <irogers@google.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/r/20250725185202.68671-4-irogers@google.com


Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
parent 9957d8c8
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -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");
			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);
			}
			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);
+0 −51
Original line number Diff line number Diff line
@@ -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",
+0 −1
Original line number Diff line number Diff line
@@ -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);

+13 −25
Original line number Diff line number Diff line
@@ -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); }
+11 −18
Original line number Diff line number Diff line
@@ -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;
Loading