]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
perf stat: Fix find_stat for mixed legacy/non-legacy events
authorIan Rogers <irogers@google.com>
Thu, 9 Jan 2025 22:21:07 +0000 (14:21 -0800)
committerNamhyung Kim <namhyung@kernel.org>
Wed, 29 Jan 2025 22:06:25 +0000 (14:06 -0800)
Legacy events typically don't have a PMU when added leading to
mismatched legacy/non-legacy cases in find_stat. Use evsel__find_pmu
to make sure the evsel PMU is looked up. Update the evsel__find_pmu
code to look for the PMU using the extended config type or, for legacy
hardware/hw_cache events on non-hybrid systems, just use the core PMU.

Before:
```
$ perf stat -e cycles,cpu/instructions/ -a sleep 1
 Performance counter stats for 'system wide':

       215,309,764      cycles
        44,326,491      cpu/instructions/

       1.002555314 seconds time elapsed
```
After:
```
$ perf stat -e cycles,cpu/instructions/ -a sleep 1

 Performance counter stats for 'system wide':

       990,676,332      cycles
     1,235,762,487      cpu/instructions/                #    1.25  insn per cycle

       1.002667198 seconds time elapsed
```

Fixes: 3612ca8e2935 ("perf stat: Fix the hard-coded metrics calculation on the hybrid")
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: James Clark <james.clark@linaro.org>
Tested-by: Leo Yan <leo.yan@arm.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
Link: https://lore.kernel.org/r/20250109222109.567031-3-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/util/pmus.c
tools/perf/util/stat-shadow.c

index b493da0d22ef7bc4637cd21182199cf9aa3addae..60d81d69503e3eb515ff1e75d44ce4e442be798c 100644 (file)
@@ -710,11 +710,25 @@ char *perf_pmus__default_pmu_name(void)
 struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
 {
        struct perf_pmu *pmu = evsel->pmu;
+       bool legacy_core_type;
 
-       if (!pmu) {
-               pmu = perf_pmus__find_by_type(evsel->core.attr.type);
-               ((struct evsel *)evsel)->pmu = pmu;
+       if (pmu)
+               return pmu;
+
+       pmu = perf_pmus__find_by_type(evsel->core.attr.type);
+       legacy_core_type =
+               evsel->core.attr.type == PERF_TYPE_HARDWARE ||
+               evsel->core.attr.type == PERF_TYPE_HW_CACHE;
+       if (!pmu && legacy_core_type) {
+               if (perf_pmus__supports_extended_type()) {
+                       u32 type = evsel->core.attr.config >> PERF_PMU_TYPE_SHIFT;
+
+                       pmu = perf_pmus__find_by_type(type);
+               } else {
+                       pmu = perf_pmus__find_core_pmu();
+               }
        }
+       ((struct evsel *)evsel)->pmu = pmu;
        return pmu;
 }
 
index fa8b2a1048ff99326f7245d5c43c8a6e0baed0f5..d83bda5824d22bce0b33b811619fb3758c95ae63 100644 (file)
@@ -151,6 +151,7 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type
 {
        struct evsel *cur;
        int evsel_ctx = evsel_context(evsel);
+       struct perf_pmu *evsel_pmu = evsel__find_pmu(evsel);
 
        evlist__for_each_entry(evsel->evlist, cur) {
                struct perf_stat_aggr *aggr;
@@ -177,7 +178,7 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type
                 * Except the SW CLOCK events,
                 * ignore if not the PMU we're looking for.
                 */
-               if ((type != STAT_NSECS) && (evsel->pmu != cur->pmu))
+               if ((type != STAT_NSECS) && (evsel_pmu != evsel__find_pmu(cur)))
                        continue;
 
                aggr = &cur->stats->aggr[aggr_idx];