When there are no events and on Intel, the topdown events will be
added by default if present. To display the metrics associated with
these request special handling in stat-shadow.c. To more easily update
these metrics use the json metric version via the TopdownL1
group. This makes the handling less platform specific.
Modify the metricgroup__has_metric code to also cover metric groups.
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.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: Sandipan Das <sandipan.das@amd.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Link: https://lore.kernel.org/r/20230219092848.639226-40-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
                                   struct perf_event_attr *attrs,
                                   size_t nr_attrs)
 {
-       if (nr_attrs)
-               return ___evlist__add_default_attrs(evlist, attrs, nr_attrs);
+       if (!nr_attrs)
+               return 0;
 
-       return topdown_parse_events(evlist);
+       return ___evlist__add_default_attrs(evlist, attrs, nr_attrs);
 }
 
 struct evsel *arch_evlist__leader(struct list_head *list)
 
 #include "topdown.h"
 #include "evsel.h"
 
-#define TOPDOWN_L1_EVENTS       "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound}"
-#define TOPDOWN_L1_EVENTS_CORE  "{slots,cpu_core/topdown-retiring/,cpu_core/topdown-bad-spec/,cpu_core/topdown-fe-bound/,cpu_core/topdown-be-bound/}"
-#define TOPDOWN_L2_EVENTS       "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound,topdown-heavy-ops,topdown-br-mispredict,topdown-fetch-lat,topdown-mem-bound}"
-#define TOPDOWN_L2_EVENTS_CORE  "{slots,cpu_core/topdown-retiring/,cpu_core/topdown-bad-spec/,cpu_core/topdown-fe-bound/,cpu_core/topdown-be-bound/,cpu_core/topdown-heavy-ops/,cpu_core/topdown-br-mispredict/,cpu_core/topdown-fetch-lat/,cpu_core/topdown-mem-bound/}"
-
 /* Check whether there is a PMU which supports the perf metrics. */
 bool topdown_sys_has_perf_metrics(void)
 {
 
        return pmu_name;
 }
-
-int topdown_parse_events(struct evlist *evlist)
-{
-       const char *topdown_events;
-       const char *pmu_name;
-
-       if (!topdown_sys_has_perf_metrics())
-               return 0;
-
-       pmu_name = arch_get_topdown_pmu_name(evlist, false);
-
-       if (pmu_have_event(pmu_name, "topdown-heavy-ops")) {
-               if (!strcmp(pmu_name, "cpu_core"))
-                       topdown_events = TOPDOWN_L2_EVENTS_CORE;
-               else
-                       topdown_events = TOPDOWN_L2_EVENTS;
-       } else {
-               if (!strcmp(pmu_name, "cpu_core"))
-                       topdown_events = TOPDOWN_L1_EVENTS_CORE;
-               else
-                       topdown_events = TOPDOWN_L1_EVENTS;
-       }
-
-       return parse_event(evlist, topdown_events);
-}
 
 #define _TOPDOWN_H 1
 
 bool topdown_sys_has_perf_metrics(void);
-int topdown_parse_events(struct evlist *evlist);
 
 #endif
 
                stat_config.topdown_level = TOPDOWN_MAX_LEVEL;
 
        if (!evsel_list->core.nr_entries) {
+               /* No events so add defaults. */
                if (target__has_cpu(&target))
                        default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
 
                }
                if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
                        return -1;
+               /*
+                * Add TopdownL1 metrics if they exist. To minimize
+                * multiplexing, don't request threshold computation.
+                */
+               if (metricgroup__has_metric("TopdownL1") &&
+                   metricgroup__parse_groups(evsel_list, "TopdownL1",
+                                           /*metric_no_group=*/false,
+                                           /*metric_no_merge=*/false,
+                                           /*metric_no_threshold=*/true,
+                                           stat_config.user_requested_cpu_list,
+                                           stat_config.system_wide,
+                                           &stat_config.metric_events) < 0)
+                       return -1;
                /* Platform specific attrs */
                if (evlist__add_default_attrs(evsel_list, default_null_attrs) < 0)
                        return -1;
 
 {
        const char *metric = vdata;
 
-       if (!pm->metric_expr)
-               return 0;
-
-       if (match_metric(pm->metric_name, metric))
+       if (match_metric(pm->metric_name, metric) ||
+           match_metric(pm->metric_group, metric))
                return 1;
 
        return 0;