perf parse-events: Fix legacy cache events if event is duplicated in a PMU

The term list when adding an event to a PMU is expected to have the
event name for the alias lookup. Also, set found_supported so that
-EINVAL isn't returned.

Fixes: 62593394f6 ("perf parse-events: Legacy cache names on all
PMUs and lower priority")

Tested-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ian Rogers 2025-10-05 11:24:04 -07:00 committed by Namhyung Kim
parent 2a67955de1
commit b7b76f607a
3 changed files with 30 additions and 3 deletions

View File

@ -475,8 +475,10 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state,
int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
struct parse_events_state *parse_state,
struct parse_events_terms *parsed_terms)
struct parse_events_terms *parsed_terms,
void *loc_)
{
YYLTYPE *loc = loc_;
struct perf_pmu *pmu = NULL;
bool found_supported = false;
const char *config_name = get_config_name(parsed_terms);
@ -497,12 +499,36 @@ int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
* The PMU has the event so add as not a legacy cache
* event.
*/
struct parse_events_terms temp_terms;
struct parse_events_term *term;
char *config = strdup(name);
if (!config)
goto out_err;
parse_events_terms__init(&temp_terms);
if (!parsed_terms)
parsed_terms = &temp_terms;
if (parse_events_term__num(&term,
PARSE_EVENTS__TERM_TYPE_USER,
config, /*num=*/1, /*novalue=*/true,
loc, /*loc_val=*/NULL) < 0) {
zfree(&config);
goto out_err;
}
list_add(&term->list, &parsed_terms->terms);
ret = parse_events_add_pmu(parse_state, list, pmu,
parsed_terms,
first_wildcard_match,
/*alternate_hw_config=*/PERF_COUNT_HW_MAX);
list_del_init(&term->list);
parse_events_term__delete(term);
parse_events_terms__exit(&temp_terms);
if (ret)
goto out_err;
found_supported = true;
if (first_wildcard_match == NULL)
first_wildcard_match =
container_of(list->prev, struct evsel, core.node);

View File

@ -237,7 +237,8 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
bool wildcard);
int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
struct parse_events_state *parse_state,
struct parse_events_terms *parsed_terms);
struct parse_events_terms *parsed_terms,
void *loc);
int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config);
int parse_events_add_breakpoint(struct parse_events_state *parse_state,
struct list_head *list,

View File

@ -353,7 +353,7 @@ PE_LEGACY_CACHE opt_event_config
if (!list)
YYNOMEM;
err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2);
err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2, &@1);
parse_events_terms__delete($2);
free($1);