Skip to content

Commit 8ce0d2d

Browse files
captain5050namhyung
authored andcommitted
perf stat: Fix find_stat for mixed legacy/non-legacy events
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: 3612ca8 ("perf stat: Fix the hard-coded metrics calculation on the hybrid") Signed-off-by: Ian Rogers <[email protected]> Tested-by: James Clark <[email protected]> Tested-by: Leo Yan <[email protected]> Tested-by: Atish Patra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Namhyung Kim <[email protected]>
1 parent 6ab89b7 commit 8ce0d2d

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

tools/perf/util/pmus.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,11 +710,25 @@ char *perf_pmus__default_pmu_name(void)
710710
struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
711711
{
712712
struct perf_pmu *pmu = evsel->pmu;
713+
bool legacy_core_type;
713714

714-
if (!pmu) {
715-
pmu = perf_pmus__find_by_type(evsel->core.attr.type);
716-
((struct evsel *)evsel)->pmu = pmu;
715+
if (pmu)
716+
return pmu;
717+
718+
pmu = perf_pmus__find_by_type(evsel->core.attr.type);
719+
legacy_core_type =
720+
evsel->core.attr.type == PERF_TYPE_HARDWARE ||
721+
evsel->core.attr.type == PERF_TYPE_HW_CACHE;
722+
if (!pmu && legacy_core_type) {
723+
if (perf_pmus__supports_extended_type()) {
724+
u32 type = evsel->core.attr.config >> PERF_PMU_TYPE_SHIFT;
725+
726+
pmu = perf_pmus__find_by_type(type);
727+
} else {
728+
pmu = perf_pmus__find_core_pmu();
729+
}
717730
}
731+
((struct evsel *)evsel)->pmu = pmu;
718732
return pmu;
719733
}
720734

tools/perf/util/stat-shadow.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type
151151
{
152152
struct evsel *cur;
153153
int evsel_ctx = evsel_context(evsel);
154+
struct perf_pmu *evsel_pmu = evsel__find_pmu(evsel);
154155

155156
evlist__for_each_entry(evsel->evlist, cur) {
156157
struct perf_stat_aggr *aggr;
@@ -177,7 +178,7 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type
177178
* Except the SW CLOCK events,
178179
* ignore if not the PMU we're looking for.
179180
*/
180-
if ((type != STAT_NSECS) && (evsel->pmu != cur->pmu))
181+
if ((type != STAT_NSECS) && (evsel_pmu != evsel__find_pmu(cur)))
181182
continue;
182183

183184
aggr = &cur->stats->aggr[aggr_idx];

0 commit comments

Comments
 (0)