From 3cb614a261e43a82acfef437c3242820c1444e2d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 18 Jul 2025 20:05:11 -0700 Subject: [PATCH] perf pmus: Factor perf_pmus__find_by_attr out of evsel__find_pmu Allow a PMU to be found by a perf_event_attr, useful when creating evsels. Reviewed-by: Thomas Falcon Signed-off-by: Ian Rogers Tested-by: James Clark Link: https://lore.kernel.org/r/20250719030517.1990983-10-irogers@google.com Signed-off-by: Namhyung Kim --- tools/perf/util/pmus.c | 29 +++++++++++++++++------------ tools/perf/util/pmus.h | 2 ++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c index 409b909cfa02..9137bb9036ed 100644 --- a/tools/perf/util/pmus.c +++ b/tools/perf/util/pmus.c @@ -814,24 +814,18 @@ bool perf_pmus__supports_extended_type(void) return perf_pmus__do_support_extended_type; } -struct perf_pmu *evsel__find_pmu(const struct evsel *evsel) +struct perf_pmu *perf_pmus__find_by_attr(const struct perf_event_attr *attr) { - struct perf_pmu *pmu = evsel->pmu; - bool legacy_core_type; - - if (pmu) - return pmu; + struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type); + u32 type = attr->type; + bool legacy_core_type = type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE; - 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 && perf_pmus__supports_extended_type()) { - u32 type = evsel->core.attr.config >> PERF_PMU_TYPE_SHIFT; + type = attr->config >> PERF_PMU_TYPE_SHIFT; pmu = perf_pmus__find_by_type(type); } - if (!pmu && (legacy_core_type || evsel->core.attr.type == PERF_TYPE_RAW)) { + if (!pmu && (legacy_core_type || type == PERF_TYPE_RAW)) { /* * For legacy events, if there was no extended type info then * assume the PMU is the first core PMU. @@ -842,6 +836,17 @@ struct perf_pmu *evsel__find_pmu(const struct evsel *evsel) */ pmu = perf_pmus__find_core_pmu(); } + return pmu; +} + +struct perf_pmu *evsel__find_pmu(const struct evsel *evsel) +{ + struct perf_pmu *pmu = evsel->pmu; + + if (pmu) + return pmu; + + pmu = perf_pmus__find_by_attr(&evsel->core.attr); ((struct evsel *)evsel)->pmu = pmu; return pmu; } diff --git a/tools/perf/util/pmus.h b/tools/perf/util/pmus.h index 86842ee5f539..7cb36863711a 100644 --- a/tools/perf/util/pmus.h +++ b/tools/perf/util/pmus.h @@ -5,6 +5,7 @@ #include #include +struct perf_event_attr; struct perf_pmu; struct print_callbacks; @@ -16,6 +17,7 @@ void perf_pmus__destroy(void); struct perf_pmu *perf_pmus__find(const char *name); struct perf_pmu *perf_pmus__find_by_type(unsigned int type); +struct perf_pmu *perf_pmus__find_by_attr(const struct perf_event_attr *attr); struct perf_pmu *perf_pmus__scan(struct perf_pmu *pmu); struct perf_pmu *perf_pmus__scan_core(struct perf_pmu *pmu); -- 2.25.1