}
int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
- const char *event_name, u64 hw_config,
+ const char *event_name,
const struct parse_events_terms *const_parsed_terms,
struct list_head **listp, void *loc_)
{
struct list_head *list = NULL;
struct perf_pmu *pmu = NULL;
YYLTYPE *loc = loc_;
- int ok = 0, core_ok = 0;
- const char *tmp;
+ int ok = 0;
+ const char *config;
struct parse_events_terms parsed_terms;
*listp = NULL;
return ret;
}
- tmp = strdup(event_name);
- if (!tmp)
+ config = strdup(event_name);
+ if (!config)
goto out_err;
if (parse_events_term__num(&term,
PARSE_EVENTS__TERM_TYPE_USER,
- tmp, /*num=*/1, /*novalue=*/true,
+ config, /*num=*/1, /*novalue=*/true,
loc, /*loc_val=*/NULL) < 0) {
- zfree(&tmp);
+ zfree(&config);
goto out_err;
}
list_add_tail(&term->list, &parsed_terms.terms);
pr_debug("%s -> %s/%s/\n", event_name, pmu->name, sb.buf);
strbuf_release(&sb);
ok++;
- if (pmu->is_core)
- core_ok++;
}
}
}
}
- if (hw_config != PERF_COUNT_HW_MAX && !core_ok) {
- /*
- * The event wasn't found on core PMUs but it has a hardware
- * config version to try.
- */
- if (!parse_events_add_numeric(parse_state, list,
- PERF_TYPE_HARDWARE, hw_config,
- const_parsed_terms,
- /*wildcard=*/true))
- ok++;
- }
-
out_err:
parse_events_terms__exit(&parsed_terms);
if (ok)
/* Failure to add, assume event_or_pmu is an event name. */
zfree(listp);
- if (!parse_events_multi_pmu_add(parse_state, event_or_pmu, PERF_COUNT_HW_MAX,
- const_parsed_terms, listp, loc))
+ if (!parse_events_multi_pmu_add(parse_state, event_or_pmu, const_parsed_terms, listp, loc))
return 0;
if (asprintf(&help, "Unable to find PMU or event on a PMU of '%s'", event_or_pmu) < 0)
yyless(0); \
} while (0)
-static int sym(yyscan_t scanner, int config)
+static int sym(yyscan_t scanner, int type, int config)
{
YYSTYPE *yylval = parse_events_get_lval(scanner);
- yylval->num = config;
- return PE_VALUE_SYM_SW;
+ yylval->num = (type << 16) + config;
+ return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
}
static int tool(yyscan_t scanner, enum perf_tool_event event)
return PE_TERM;
}
-static int hw(yyscan_t scanner, int config)
+static int hw_term(yyscan_t scanner, int config)
{
YYSTYPE *yylval = parse_events_get_lval(scanner);
char *text = parse_events_get_text(scanner);
- yylval->hardware_event.str = strdup(text);
- yylval->hardware_event.num = config;
+ yylval->hardware_term.str = strdup(text);
+ yylval->hardware_term.num = PERF_TYPE_HARDWARE + config;
return PE_TERM_HW;
}
aux-output { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); }
aux-sample-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE); }
metric-id { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_METRIC_ID); }
-cpu-cycles|cycles { return hw(yyscanner, PERF_COUNT_HW_CPU_CYCLES); }
-stalled-cycles-frontend|idle-cycles-frontend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
-stalled-cycles-backend|idle-cycles-backend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
-instructions { return hw(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); }
-cache-references { return hw(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); }
-cache-misses { return hw(yyscanner, PERF_COUNT_HW_CACHE_MISSES); }
-branch-instructions|branches { return hw(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
-branch-misses { return hw(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); }
-bus-cycles { return hw(yyscanner, PERF_COUNT_HW_BUS_CYCLES); }
-ref-cycles { return hw(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); }
+cpu-cycles|cycles { return hw_term(yyscanner, PERF_COUNT_HW_CPU_CYCLES); }
+stalled-cycles-frontend|idle-cycles-frontend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
+stalled-cycles-backend|idle-cycles-backend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
+instructions { return hw_term(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); }
+cache-references { return hw_term(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); }
+cache-misses { return hw_term(yyscanner, PERF_COUNT_HW_CACHE_MISSES); }
+branch-instructions|branches { return hw_term(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
+branch-misses { return hw_term(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); }
+bus-cycles { return hw_term(yyscanner, PERF_COUNT_HW_BUS_CYCLES); }
+ref-cycles { return hw_term(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); }
r{num_raw_hex} { return str(yyscanner, PE_RAW); }
r0x{num_raw_hex} { return str(yyscanner, PE_RAW); }
, { return ','; }
<<EOF>> { BEGIN(INITIAL); }
}
-cpu-cycles|cycles { return hw(yyscanner, PERF_COUNT_HW_CPU_CYCLES); }
-stalled-cycles-frontend|idle-cycles-frontend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
-stalled-cycles-backend|idle-cycles-backend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
-instructions { return hw(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); }
-cache-references { return hw(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); }
-cache-misses { return hw(yyscanner, PERF_COUNT_HW_CACHE_MISSES); }
-branch-instructions|branches { return hw(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
-branch-misses { return hw(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); }
-bus-cycles { return hw(yyscanner, PERF_COUNT_HW_BUS_CYCLES); }
-ref-cycles { return hw(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); }
-cpu-clock { return sym(yyscanner, PERF_COUNT_SW_CPU_CLOCK); }
-task-clock { return sym(yyscanner, PERF_COUNT_SW_TASK_CLOCK); }
-page-faults|faults { return sym(yyscanner, PERF_COUNT_SW_PAGE_FAULTS); }
-minor-faults { return sym(yyscanner, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
-major-faults { return sym(yyscanner, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
-context-switches|cs { return sym(yyscanner, PERF_COUNT_SW_CONTEXT_SWITCHES); }
-cpu-migrations|migrations { return sym(yyscanner, PERF_COUNT_SW_CPU_MIGRATIONS); }
-alignment-faults { return sym(yyscanner, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
-emulation-faults { return sym(yyscanner, PERF_COUNT_SW_EMULATION_FAULTS); }
-dummy { return sym(yyscanner, PERF_COUNT_SW_DUMMY); }
+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); }
duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); }
user_time { return tool(yyscanner, PERF_TOOL_USER_TIME); }
system_time { return tool(yyscanner, PERF_TOOL_SYSTEM_TIME); }
-bpf-output { return sym(yyscanner, PERF_COUNT_SW_BPF_OUTPUT); }
-cgroup-switches { return sym(yyscanner, PERF_COUNT_SW_CGROUP_SWITCHES); }
+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); }
{lc_type} { return str(yyscanner, PE_LEGACY_CACHE); }
{lc_type}-{lc_op_result} { return str(yyscanner, PE_LEGACY_CACHE); }
%}
%token PE_START_EVENTS PE_START_TERMS
-%token PE_VALUE PE_VALUE_SYM_SW PE_TERM
+%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM
%token PE_VALUE_SYM_TOOL
%token PE_EVENT_NAME
%token PE_RAW PE_NAME
%token PE_DRV_CFG_TERM
%token PE_TERM_HW
%type <num> PE_VALUE
+%type <num> PE_VALUE_SYM_HW
%type <num> PE_VALUE_SYM_SW
%type <num> PE_VALUE_SYM_TOOL
%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
%type <list_terms> opt_pmu_config
%destructor { parse_events_terms__delete ($$); } <list_terms>
%type <list_evsel> event_pmu
-%type <list_evsel> event_legacy_hardware
%type <list_evsel> event_legacy_symbol
%type <list_evsel> event_legacy_cache
%type <list_evsel> event_legacy_mem
%destructor { free_list_evsel ($$); } <list_evsel>
%type <tracepoint_name> tracepoint_name
%destructor { free ($$.sys); free ($$.event); } <tracepoint_name>
-%type <hardware_event> PE_TERM_HW
-%destructor { free ($$.str); } <hardware_event>
+%type <hardware_term> PE_TERM_HW
+%destructor { free ($$.str); } <hardware_term>
%union
{
char *sys;
char *event;
} tracepoint_name;
- struct hardware_event {
+ struct hardware_term {
char *str;
u64 num;
- } hardware_event;
+ } hardware_term;
}
%%
event_def
event_def: event_pmu |
- event_legacy_hardware |
event_legacy_symbol |
event_legacy_cache sep_dc |
event_legacy_mem sep_dc |
struct list_head *list;
int err;
- err = parse_events_multi_pmu_add(_parse_state, $1, PERF_COUNT_HW_MAX, NULL, &list, &@1);
+ err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list, &@1);
if (err < 0) {
struct parse_events_state *parse_state = _parse_state;
struct parse_events_error *error = parse_state->error;
$$ = list;
}
-event_legacy_hardware:
-PE_TERM_HW opt_pmu_config
-{
- /* List of created evsels. */
- struct list_head *list = NULL;
- int err = parse_events_multi_pmu_add(_parse_state, $1.str, $1.num, $2, &list, &@1);
-
- free($1.str);
- parse_events_terms__delete($2);
- if (err)
- PE_ABORT(err);
-
- $$ = list;
-}
+value_sym:
+PE_VALUE_SYM_HW
|
-PE_TERM_HW sep_dc
-{
- struct list_head *list;
- int err;
-
- err = parse_events_multi_pmu_add(_parse_state, $1.str, $1.num, NULL, &list, &@1);
- free($1.str);
- if (err)
- PE_ABORT(err);
- $$ = list;
-}
+PE_VALUE_SYM_SW
event_legacy_symbol:
-PE_VALUE_SYM_SW '/' event_config '/'
+value_sym '/' 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=*/PERF_TYPE_SOFTWARE, /*config=*/$1,
- $3, /*wildcard=*/false);
+ err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard);
parse_events_terms__delete($3);
if (err) {
free_list_evsel(list);
$$ = list;
}
|
-PE_VALUE_SYM_SW sep_slash_slash_dc
+value_sym 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=*/PERF_TYPE_SOFTWARE, /*config=*/$1,
- /*head_config=*/NULL, /*wildcard=*/false);
+ err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard);
if (err)
PE_ABORT(err);
$$ = list;