]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf parse-events: Fix legacy cache events if event is duplicated in a PMU
authorIan Rogers <irogers@google.com>
Sun, 5 Oct 2025 18:24:04 +0000 (11:24 -0700)
committerNamhyung Kim <namhyung@kernel.org>
Wed, 15 Oct 2025 14:59:10 +0000 (23:59 +0900)
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: 62593394f66a ("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>
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.y

index da73d686f6b937be5a608f379044c2821b2b71af..90a765016f64f31a838e0a1e8caffbb3fe5b0d91 100644 (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);
index 8f8c8e7fbcf186c045dd2e3d1f75484039ac8049..8af19dec6a17dac83ee7e170a9c58f5e5b899cb1 100644 (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,
index a2361c0040d75901c20372ffe3644be715d87a89..ced26c549c33ac4eef32c810294da5694ee704d3 100644 (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);