1

Revert a patch causing a regression as described in the cset:

"This made a simple 'perf record -e cycles:pp make -j199' stop working on
     the Ampere ARM64 system Linus uses to test ARM64 kernels, as discussed
     at length in the threads in the Link tags below.
 
     The fix provided by Ian wasn't acceptable and work to fix this will take
     time we don't have at this point, so lets revert this and work on it on
     the next devel cycle."
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCZlMhdgAKCRCyPKLppCJ+
 JzCNAPwM7gQLjeoCdkn9KDl1fj1R7/jBE/TsVqP9s1htc9vJEgD/UgLDkpdzlxBC
 HbndVTOrnvyV9ySA28654ODHpQxmXwM=
 =WJwT
 -----END PGP SIGNATURE-----

Merge tag 'perf-tools-fixes-for-v6.10-1-2024-05-26' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools

Pull perf tool fix from Arnaldo Carvalho de Melo:
 "Revert a patch causing a regression.

  This made a simple 'perf record -e cycles:pp make -j199' stop working
  on the Ampere ARM64 system Linus uses to test ARM64 kernels".

* tag 'perf-tools-fixes-for-v6.10-1-2024-05-26' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools:
  Revert "perf parse-events: Prefer sysfs/JSON hardware events over legacy"
This commit is contained in:
Linus Torvalds 2024-05-26 09:54:26 -07:00
commit 6fbf71854e
4 changed files with 68 additions and 103 deletions

View File

@ -1549,7 +1549,7 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state,
} }
int parse_events_multi_pmu_add(struct parse_events_state *parse_state, 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, const struct parse_events_terms *const_parsed_terms,
struct list_head **listp, void *loc_) struct list_head **listp, void *loc_)
{ {
@ -1557,8 +1557,8 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
struct list_head *list = NULL; struct list_head *list = NULL;
struct perf_pmu *pmu = NULL; struct perf_pmu *pmu = NULL;
YYLTYPE *loc = loc_; YYLTYPE *loc = loc_;
int ok = 0, core_ok = 0; int ok = 0;
const char *tmp; const char *config;
struct parse_events_terms parsed_terms; struct parse_events_terms parsed_terms;
*listp = NULL; *listp = NULL;
@ -1571,15 +1571,15 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
return ret; return ret;
} }
tmp = strdup(event_name); config = strdup(event_name);
if (!tmp) if (!config)
goto out_err; goto out_err;
if (parse_events_term__num(&term, if (parse_events_term__num(&term,
PARSE_EVENTS__TERM_TYPE_USER, PARSE_EVENTS__TERM_TYPE_USER,
tmp, /*num=*/1, /*novalue=*/true, config, /*num=*/1, /*novalue=*/true,
loc, /*loc_val=*/NULL) < 0) { loc, /*loc_val=*/NULL) < 0) {
zfree(&tmp); zfree(&config);
goto out_err; goto out_err;
} }
list_add_tail(&term->list, &parsed_terms.terms); list_add_tail(&term->list, &parsed_terms.terms);
@ -1610,8 +1610,6 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
pr_debug("%s -> %s/%s/\n", event_name, pmu->name, sb.buf); pr_debug("%s -> %s/%s/\n", event_name, pmu->name, sb.buf);
strbuf_release(&sb); strbuf_release(&sb);
ok++; ok++;
if (pmu->is_core)
core_ok++;
} }
} }
@ -1628,18 +1626,6 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
} }
} }
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: out_err:
parse_events_terms__exit(&parsed_terms); parse_events_terms__exit(&parsed_terms);
if (ok) if (ok)
@ -1693,8 +1679,7 @@ int parse_events_multi_pmu_add_or_add_pmu(struct parse_events_state *parse_state
/* Failure to add, assume event_or_pmu is an event name. */ /* Failure to add, assume event_or_pmu is an event name. */
zfree(listp); zfree(listp);
if (!parse_events_multi_pmu_add(parse_state, event_or_pmu, PERF_COUNT_HW_MAX, if (!parse_events_multi_pmu_add(parse_state, event_or_pmu, const_parsed_terms, listp, loc))
const_parsed_terms, listp, loc))
return 0; return 0;
if (asprintf(&help, "Unable to find PMU or event on a PMU of '%s'", event_or_pmu) < 0) if (asprintf(&help, "Unable to find PMU or event on a PMU of '%s'", event_or_pmu) < 0)

View File

@ -237,7 +237,7 @@ struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
struct perf_pmu *pmu); struct perf_pmu *pmu);
int parse_events_multi_pmu_add(struct parse_events_state *parse_state, 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, const struct parse_events_terms *const_parsed_terms,
struct list_head **listp, void *loc); struct list_head **listp, void *loc);

View File

@ -113,12 +113,12 @@ do { \
yyless(0); \ yyless(0); \
} while (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); YYSTYPE *yylval = parse_events_get_lval(scanner);
yylval->num = config; yylval->num = (type << 16) + config;
return PE_VALUE_SYM_SW; return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
} }
static int tool(yyscan_t scanner, enum perf_tool_event event) static int tool(yyscan_t scanner, enum perf_tool_event event)
@ -137,13 +137,13 @@ static int term(yyscan_t scanner, enum parse_events__term_type type)
return PE_TERM; 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); YYSTYPE *yylval = parse_events_get_lval(scanner);
char *text = parse_events_get_text(scanner); char *text = parse_events_get_text(scanner);
yylval->hardware_event.str = strdup(text); yylval->hardware_term.str = strdup(text);
yylval->hardware_event.num = config; yylval->hardware_term.num = PERF_TYPE_HARDWARE + config;
return PE_TERM_HW; return PE_TERM_HW;
} }
@ -330,16 +330,16 @@ percore { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); }
aux-output { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); } aux-output { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); }
aux-sample-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE); } aux-sample-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE); }
metric-id { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_METRIC_ID); } metric-id { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_METRIC_ID); }
cpu-cycles|cycles { return hw(yyscanner, PERF_COUNT_HW_CPU_CYCLES); } cpu-cycles|cycles { return hw_term(yyscanner, PERF_COUNT_HW_CPU_CYCLES); }
stalled-cycles-frontend|idle-cycles-frontend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } stalled-cycles-frontend|idle-cycles-frontend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
stalled-cycles-backend|idle-cycles-backend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } stalled-cycles-backend|idle-cycles-backend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
instructions { return hw(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); } instructions { return hw_term(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); }
cache-references { return hw(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); } cache-references { return hw_term(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); }
cache-misses { return hw(yyscanner, PERF_COUNT_HW_CACHE_MISSES); } cache-misses { return hw_term(yyscanner, PERF_COUNT_HW_CACHE_MISSES); }
branch-instructions|branches { return hw(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } branch-instructions|branches { return hw_term(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
branch-misses { return hw(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); } branch-misses { return hw_term(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); }
bus-cycles { return hw(yyscanner, PERF_COUNT_HW_BUS_CYCLES); } bus-cycles { return hw_term(yyscanner, PERF_COUNT_HW_BUS_CYCLES); }
ref-cycles { return hw(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); } ref-cycles { return hw_term(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); }
r{num_raw_hex} { return str(yyscanner, PE_RAW); } r{num_raw_hex} { return str(yyscanner, PE_RAW); }
r0x{num_raw_hex} { return str(yyscanner, PE_RAW); } r0x{num_raw_hex} { return str(yyscanner, PE_RAW); }
, { return ','; } , { return ','; }
@ -383,31 +383,31 @@ r0x{num_raw_hex} { return str(yyscanner, PE_RAW); }
<<EOF>> { BEGIN(INITIAL); } <<EOF>> { BEGIN(INITIAL); }
} }
cpu-cycles|cycles { return hw(yyscanner, PERF_COUNT_HW_CPU_CYCLES); } cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
stalled-cycles-frontend|idle-cycles-frontend { return hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } 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 hw(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
instructions { return hw(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); } instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
cache-references { return hw(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); } cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
cache-misses { return hw(yyscanner, PERF_COUNT_HW_CACHE_MISSES); } cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
branch-instructions|branches { return hw(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
branch-misses { return hw(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); } branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
bus-cycles { return hw(yyscanner, PERF_COUNT_HW_BUS_CYCLES); } bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
ref-cycles { return hw(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); } ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
cpu-clock { return sym(yyscanner, PERF_COUNT_SW_CPU_CLOCK); } cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
task-clock { return sym(yyscanner, PERF_COUNT_SW_TASK_CLOCK); } task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
page-faults|faults { return sym(yyscanner, PERF_COUNT_SW_PAGE_FAULTS); } page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
minor-faults { return sym(yyscanner, PERF_COUNT_SW_PAGE_FAULTS_MIN); } minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
major-faults { return sym(yyscanner, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
context-switches|cs { return sym(yyscanner, PERF_COUNT_SW_CONTEXT_SWITCHES); } context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
cpu-migrations|migrations { return sym(yyscanner, PERF_COUNT_SW_CPU_MIGRATIONS); } cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
alignment-faults { return sym(yyscanner, PERF_COUNT_SW_ALIGNMENT_FAULTS); } alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
emulation-faults { return sym(yyscanner, PERF_COUNT_SW_EMULATION_FAULTS); } emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
dummy { return sym(yyscanner, PERF_COUNT_SW_DUMMY); } dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); } duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); }
user_time { return tool(yyscanner, PERF_TOOL_USER_TIME); } user_time { return tool(yyscanner, PERF_TOOL_USER_TIME); }
system_time { return tool(yyscanner, PERF_TOOL_SYSTEM_TIME); } system_time { return tool(yyscanner, PERF_TOOL_SYSTEM_TIME); }
bpf-output { return sym(yyscanner, PERF_COUNT_SW_BPF_OUTPUT); } bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); }
cgroup-switches { return sym(yyscanner, PERF_COUNT_SW_CGROUP_SWITCHES); } cgroup-switches { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CGROUP_SWITCHES); }
{lc_type} { return str(yyscanner, PE_LEGACY_CACHE); } {lc_type} { return str(yyscanner, PE_LEGACY_CACHE); }
{lc_type}-{lc_op_result} { 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_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_VALUE_SYM_TOOL
%token PE_EVENT_NAME %token PE_EVENT_NAME
%token PE_RAW PE_NAME %token PE_RAW PE_NAME
@ -66,10 +66,12 @@ static void free_list_evsel(struct list_head* list_evsel)
%token PE_DRV_CFG_TERM %token PE_DRV_CFG_TERM
%token PE_TERM_HW %token PE_TERM_HW
%type <num> PE_VALUE %type <num> PE_VALUE
%type <num> PE_VALUE_SYM_HW
%type <num> PE_VALUE_SYM_SW %type <num> PE_VALUE_SYM_SW
%type <num> PE_VALUE_SYM_TOOL %type <num> PE_VALUE_SYM_TOOL
%type <mod> PE_MODIFIER_EVENT %type <mod> PE_MODIFIER_EVENT
%type <term_type> PE_TERM %type <term_type> PE_TERM
%type <num> value_sym
%type <str> PE_RAW %type <str> PE_RAW
%type <str> PE_NAME %type <str> PE_NAME
%type <str> PE_LEGACY_CACHE %type <str> PE_LEGACY_CACHE
@ -85,7 +87,6 @@ static void free_list_evsel(struct list_head* list_evsel)
%type <list_terms> opt_pmu_config %type <list_terms> opt_pmu_config
%destructor { parse_events_terms__delete ($$); } <list_terms> %destructor { parse_events_terms__delete ($$); } <list_terms>
%type <list_evsel> event_pmu %type <list_evsel> event_pmu
%type <list_evsel> event_legacy_hardware
%type <list_evsel> event_legacy_symbol %type <list_evsel> event_legacy_symbol
%type <list_evsel> event_legacy_cache %type <list_evsel> event_legacy_cache
%type <list_evsel> event_legacy_mem %type <list_evsel> event_legacy_mem
@ -103,8 +104,8 @@ static void free_list_evsel(struct list_head* list_evsel)
%destructor { free_list_evsel ($$); } <list_evsel> %destructor { free_list_evsel ($$); } <list_evsel>
%type <tracepoint_name> tracepoint_name %type <tracepoint_name> tracepoint_name
%destructor { free ($$.sys); free ($$.event); } <tracepoint_name> %destructor { free ($$.sys); free ($$.event); } <tracepoint_name>
%type <hardware_event> PE_TERM_HW %type <hardware_term> PE_TERM_HW
%destructor { free ($$.str); } <hardware_event> %destructor { free ($$.str); } <hardware_term>
%union %union
{ {
@ -119,10 +120,10 @@ static void free_list_evsel(struct list_head* list_evsel)
char *sys; char *sys;
char *event; char *event;
} tracepoint_name; } tracepoint_name;
struct hardware_event { struct hardware_term {
char *str; char *str;
u64 num; u64 num;
} hardware_event; } hardware_term;
} }
%% %%
@ -265,7 +266,6 @@ PE_EVENT_NAME event_def
event_def event_def
event_def: event_pmu | event_def: event_pmu |
event_legacy_hardware |
event_legacy_symbol | event_legacy_symbol |
event_legacy_cache sep_dc | event_legacy_cache sep_dc |
event_legacy_mem sep_dc | event_legacy_mem sep_dc |
@ -292,7 +292,7 @@ PE_NAME sep_dc
struct list_head *list; struct list_head *list;
int err; 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) { if (err < 0) {
struct parse_events_state *parse_state = _parse_state; struct parse_events_state *parse_state = _parse_state;
struct parse_events_error *error = parse_state->error; struct parse_events_error *error = parse_state->error;
@ -308,45 +308,24 @@ PE_NAME sep_dc
$$ = list; $$ = list;
} }
event_legacy_hardware: value_sym:
PE_TERM_HW opt_pmu_config PE_VALUE_SYM_HW
{
/* 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;
}
| |
PE_TERM_HW sep_dc PE_VALUE_SYM_SW
{
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;
}
event_legacy_symbol: event_legacy_symbol:
PE_VALUE_SYM_SW '/' event_config '/' value_sym '/' event_config '/'
{ {
struct list_head *list; struct list_head *list;
int type = $1 >> 16;
int config = $1 & 255;
int err; int err;
bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
list = alloc_list(); list = alloc_list();
if (!list) if (!list)
YYNOMEM; YYNOMEM;
err = parse_events_add_numeric(_parse_state, list, err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard);
/*type=*/PERF_TYPE_SOFTWARE, /*config=*/$1,
$3, /*wildcard=*/false);
parse_events_terms__delete($3); parse_events_terms__delete($3);
if (err) { if (err) {
free_list_evsel(list); free_list_evsel(list);
@ -355,17 +334,18 @@ PE_VALUE_SYM_SW '/' event_config '/'
$$ = list; $$ = list;
} }
| |
PE_VALUE_SYM_SW sep_slash_slash_dc value_sym sep_slash_slash_dc
{ {
struct list_head *list; 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; int err;
list = alloc_list(); list = alloc_list();
if (!list) if (!list)
YYNOMEM; YYNOMEM;
err = parse_events_add_numeric(_parse_state, list, err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard);
/*type=*/PERF_TYPE_SOFTWARE, /*config=*/$1,
/*head_config=*/NULL, /*wildcard=*/false);
if (err) if (err)
PE_ABORT(err); PE_ABORT(err);
$$ = list; $$ = list;