perf parse-events: Support wildcards on raw events
authorIan Rogers <irogers@google.com>
Tue, 2 May 2023 22:38:33 +0000 (15:38 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 15 May 2023 12:12:13 +0000 (09:12 -0300)
Legacy raw events like r1a open as PERF_TYPE_RAW on non-hybrid systems
and on each hybrid PMU on hybrid systems. Rather than iterate hybrid
PMUs add a perf_pmu__supports_wildcard_numeric function that says when
a numeric event should be opened upon it. If the parsed event
specifies the type of the PMU then don't wildcard match PMUs, use the
specified PMU type.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ahmad Yasin <ahmad.yasin@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Edward Baker <edward.baker@intel.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kang Minchul <tegongkang@gmail.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Samantha Alt <samantha.alt@intel.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20230502223851.2234828-27-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.y
tools/perf/util/pmu.c
tools/perf/util/pmu.h

index ec72f11..c8b4ec0 100644 (file)
@@ -25,7 +25,6 @@
 #include "util/parse-branch-options.h"
 #include "util/evsel_config.h"
 #include "util/event.h"
-#include "util/parse-events-hybrid.h"
 #include "util/pmu-hybrid.h"
 #include "util/bpf-filter.h"
 #include "util/util.h"
@@ -1448,15 +1447,14 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx,
 #endif
 }
 
-int parse_events_add_numeric(struct parse_events_state *parse_state,
-                            struct list_head *list,
-                            u32 type, u64 config,
-                            struct list_head *head_config)
+static int __parse_events_add_numeric(struct parse_events_state *parse_state,
+                               struct list_head *list,
+                               struct perf_pmu *pmu, u32 type, u64 config,
+                               struct list_head *head_config)
 {
        struct perf_event_attr attr;
        LIST_HEAD(config_terms);
        const char *name, *metric_id;
-       bool hybrid;
        int ret;
 
        memset(&attr, 0, sizeof(attr));
@@ -1474,19 +1472,41 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
 
        name = get_config_name(head_config);
        metric_id = get_config_metric_id(head_config);
-       ret = parse_events__add_numeric_hybrid(parse_state, list, &attr,
-                                              name, metric_id,
-                                              &config_terms, &hybrid);
-       if (hybrid)
-               goto out_free_terms;
-
-       ret = add_event(list, &parse_state->idx, &attr, name, metric_id,
-                       &config_terms);
-out_free_terms:
+       ret = __add_event(list, &parse_state->idx, &attr, /*init_attr*/true, name,
+                       metric_id, pmu, &config_terms, /*auto_merge_stats=*/false,
+                       /*cpu_list=*/NULL) ? 0 : -ENOMEM;
        free_config_terms(&config_terms);
        return ret;
 }
 
+int parse_events_add_numeric(struct parse_events_state *parse_state,
+                            struct list_head *list,
+                            u32 type, u64 config,
+                            struct list_head *head_config,
+                            bool wildcard)
+{
+       struct perf_pmu *pmu = NULL;
+       bool found_supported = false;
+
+       if (!wildcard)
+               return __parse_events_add_numeric(parse_state, list, /*pmu=*/NULL,
+                                                 type, config, head_config);
+
+       while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+               int ret;
+
+               if (!perf_pmu__supports_wildcard_numeric(pmu))
+                       continue;
+
+               found_supported = true;
+               ret = __parse_events_add_numeric(parse_state, list, pmu, pmu->type,
+                                                config, head_config);
+               if (ret)
+                       return ret;
+       }
+       return found_supported ? 0 : -EINVAL;
+}
+
 int parse_events_add_tool(struct parse_events_state *parse_state,
                          struct list_head *list,
                          int tool_event)
index 4e49be2..831cd1f 100644 (file)
@@ -166,7 +166,8 @@ int parse_events_load_bpf_obj(struct parse_events_state *parse_state,
 int parse_events_add_numeric(struct parse_events_state *parse_state,
                             struct list_head *list,
                             u32 type, u64 config,
-                            struct list_head *head_config);
+                            struct list_head *head_config,
+                            bool wildcard);
 int parse_events_add_tool(struct parse_events_state *parse_state,
                          struct list_head *list,
                          int tool_event);
index cc75285..5055a29 100644 (file)
@@ -435,7 +435,8 @@ value_sym '/' event_config '/'
 
        list = alloc_list();
        ABORT_ON(!list);
-       err = parse_events_add_numeric(_parse_state, list, type, config, $3);
+       err = parse_events_add_numeric(_parse_state, list, type, config, $3,
+                                      /*wildcard=*/false);
        parse_events_terms__delete($3);
        if (err) {
                free_list_evsel(list);
@@ -452,7 +453,9 @@ value_sym sep_slash_slash_dc
 
        list = alloc_list();
        ABORT_ON(!list);
-       ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
+       ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config,
+                                         /*head_config=*/NULL,
+                                         /*wildcard=*/false));
        $$ = list;
 }
 |
@@ -596,7 +599,8 @@ PE_VALUE ':' PE_VALUE opt_event_config
 
        list = alloc_list();
        ABORT_ON(!list);
-       err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4);
+       err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4,
+                                      /*wildcard=*/false);
        parse_events_terms__delete($4);
        if (err) {
                free(list);
@@ -618,7 +622,8 @@ PE_RAW opt_event_config
        num = strtoull($1 + 1, NULL, 16);
        ABORT_ON(errno);
        free($1);
-       err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2);
+       err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2,
+                                      /*wildcard=*/true);
        parse_events_terms__delete($2);
        if (err) {
                free(list);
index 63071d8..cd4247a 100644 (file)
@@ -1655,6 +1655,11 @@ bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu)
        return is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name);
 }
 
+bool perf_pmu__supports_wildcard_numeric(const struct perf_pmu *pmu)
+{
+       return is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name);
+}
+
 static bool pmu_alias_is_duplicate(struct sevent *alias_a,
                                   struct sevent *alias_b)
 {
index 05702bc..5a19536 100644 (file)
@@ -221,6 +221,7 @@ struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
 
 bool is_pmu_core(const char *name);
 bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu);
+bool perf_pmu__supports_wildcard_numeric(const struct perf_pmu *pmu);
 void print_pmu_events(const struct print_callbacks *print_cb, void *print_state);
 bool pmu_have_event(const char *pname, const char *name);