From: Ian Rogers <irogers@google.com>
To: linux-perf-users@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>, Jiri Olsa <jolsa@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
Kan Liang <kan.liang@linux.intel.com>,
Dapeng Mi <dapeng1.mi@linux.intel.com>,
Thomas Falcon <thomas.falcon@intel.com>,
John Garry <john.garry@linux.dev>, Will Deacon <will@kernel.org>,
Leo Yan <leo.yan@arm.com>,
Athira Rajeev <atrajeev@linux.ibm.com>,
Thomas Richter <tmricht@linux.ibm.com>,
Ravi Bangoria <ravi.bangoria@amd.com>,
Sandipan Das <sandipan.das@amd.com>,
Ian Rogers <irogers@google.com>
Subject: [PATCH v1 05/41] perf pmus: Pass struct perf_pmus to find helpers
Date: Tue, 3 Nov 2026 15:44:21 -0800 [thread overview]
Message-ID: <20261103234502.1008382-6-irogers@google.com> (raw)
In-Reply-To: <20261103234502.1008382-1-irogers@google.com>
Update perf_pmus__find(), perf_pmus__find_by_type(), and
perf_pmus__find_core_pmu() to take a struct perf_pmus * argument and
update callers to pass the appropriate environment's PMUs.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/arch/arm/util/auxtrace.c | 9 ++--
tools/perf/arch/arm/util/cs-etm.c | 3 +-
tools/perf/arch/arm64/util/pmu.c | 3 +-
tools/perf/arch/x86/tests/amd-ibs-period.c | 5 +-
.../arch/x86/tests/amd-ibs-via-core-pmu.c | 3 +-
tools/perf/arch/x86/tests/hybrid.c | 3 +-
tools/perf/arch/x86/tests/topdown.c | 3 +-
tools/perf/arch/x86/util/auxtrace.c | 9 ++--
tools/perf/arch/x86/util/evsel.c | 6 ++-
tools/perf/arch/x86/util/intel-bts.c | 4 +-
tools/perf/arch/x86/util/intel-pt.c | 4 +-
tools/perf/arch/x86/util/topdown.c | 3 +-
tools/perf/bench/pmu-scan.c | 3 +-
tools/perf/builtin-stat.c | 8 +--
tools/perf/tests/parse-events.c | 14 +++---
tools/perf/trace/beauty/perf_event_open.c | 4 +-
tools/perf/util/aslr.c | 7 ++-
tools/perf/util/env.c | 2 +-
tools/perf/util/evsel.c | 6 ++-
tools/perf/util/evsel_fprintf.c | 6 ++-
tools/perf/util/evsel_fprintf.h | 4 +-
| 8 +--
tools/perf/util/metricgroup.c | 50 ++++++++++++-------
tools/perf/util/metricgroup.h | 4 +-
tools/perf/util/parse-events.c | 18 ++++---
.../perf/util/perf-regs-arch/perf_regs_x86.c | 2 +-
tools/perf/util/perf_event_attr_fprintf.c | 7 +--
tools/perf/util/pfm.c | 6 ++-
tools/perf/util/pmus.c | 28 ++++-------
tools/perf/util/pmus.h | 27 ++++++++--
tools/perf/util/s390-sample-raw.c | 16 ++++--
31 files changed, 175 insertions(+), 100 deletions(-)
diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
index 27bb14c8b880..f3a4f292a2c7 100644
--- a/tools/perf/arch/arm/util/auxtrace.c
+++ b/tools/perf/arch/arm/util/auxtrace.c
@@ -13,6 +13,7 @@
#include "../../../util/auxtrace.h"
#include "../../../util/debug.h"
+#include "../../../util/env.h"
#include "../../../util/evlist.h"
#include "../../../util/pmu.h"
#include "../../../util/pmus.h"
@@ -22,6 +23,7 @@
static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
{
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
struct perf_pmu **arm_spe_pmus = NULL;
int ret, i, nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
/* arm_spe_xxxxxxxxx\0 */
@@ -42,7 +44,7 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
return NULL;
}
- arm_spe_pmus[*nr_spes] = perf_pmus__find(arm_spe_pmu_name);
+ arm_spe_pmus[*nr_spes] = perf_pmus__find(pmus, arm_spe_pmu_name);
if (arm_spe_pmus[*nr_spes]) {
pr_debug2("%s %d: arm_spe_pmu %d type %d name %s\n",
__func__, __LINE__, *nr_spes,
@@ -57,6 +59,7 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
static struct perf_pmu **find_all_hisi_ptt_pmus(int *nr_ptts, int *err)
{
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
struct perf_pmu **hisi_ptt_pmus = NULL;
struct dirent *dent;
char path[PATH_MAX];
@@ -89,7 +92,7 @@ static struct perf_pmu **find_all_hisi_ptt_pmus(int *nr_ptts, int *err)
rewinddir(dir);
while ((dent = readdir(dir))) {
if (strstr(dent->d_name, HISI_PTT_PMU_NAME) && idx < *nr_ptts) {
- hisi_ptt_pmus[idx] = perf_pmus__find(dent->d_name);
+ hisi_ptt_pmus[idx] = perf_pmus__find(pmus, dent->d_name);
if (hisi_ptt_pmus[idx])
idx++;
}
@@ -133,7 +136,7 @@ struct auxtrace_record
if (!evlist)
return NULL;
- cs_etm_pmu = perf_pmus__find(CORESIGHT_ETM_PMU_NAME);
+ cs_etm_pmu = perf_pmus__find(perf_env__pmus(host_env()), CORESIGHT_ETM_PMU_NAME);
arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err);
hisi_ptt_pmus = find_all_hisi_ptt_pmus(&nr_ptts, err);
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index d2861d66a661..e15bd87f65fb 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -25,6 +25,7 @@
#include "../../../util/auxtrace.h"
#include "../../../util/cpumap.h"
#include "../../../util/debug.h"
+#include "../../../util/env.h"
#include "../../../util/event.h"
#include "../../../util/evlist.h"
#include "../../../util/evsel.h"
@@ -883,7 +884,7 @@ struct auxtrace_record *cs_etm_record_init(int *err)
struct perf_pmu *cs_etm_pmu;
struct cs_etm_recording *ptr;
- cs_etm_pmu = perf_pmus__find(CORESIGHT_ETM_PMU_NAME);
+ cs_etm_pmu = perf_pmus__find(perf_env__pmus(host_env()), CORESIGHT_ETM_PMU_NAME);
if (!cs_etm_pmu) {
*err = -EINVAL;
diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c
index 895fb0d0610c..798b423fe149 100644
--- a/tools/perf/arch/arm64/util/pmu.c
+++ b/tools/perf/arch/arm64/util/pmu.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
+#include "../../../util/env.h"
#include "../../../util/pmu.h"
#include "../../../util/pmus.h"
#include "../../../util/tool_pmu.h"
@@ -9,7 +10,7 @@ u64 tool_pmu__cpu_slots_per_cycle(void)
{
char path[PATH_MAX];
unsigned long long slots = 0;
- struct perf_pmu *pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
if (pmu) {
perf_pmu__pathname_scnprintf(path, sizeof(path),
diff --git a/tools/perf/arch/x86/tests/amd-ibs-period.c b/tools/perf/arch/x86/tests/amd-ibs-period.c
index 32713f8fcd5c..4a32eaea61c7 100644
--- a/tools/perf/arch/x86/tests/amd-ibs-period.c
+++ b/tools/perf/arch/x86/tests/amd-ibs-period.c
@@ -930,6 +930,7 @@ static bool kernel_v6_15_or_newer(void)
int test__amd_ibs_period(struct test_suite *test __maybe_unused,
int subtest __maybe_unused)
{
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
char perf[PATH_MAX] = {'\0'};
int ret = TEST_OK;
@@ -940,8 +941,8 @@ int test__amd_ibs_period(struct test_suite *test __maybe_unused,
* of the test to fail if kernel changes it after reading it here.
*/
perf_event_max_sample_rate = get_perf_event_max_sample_rate();
- fetch_pmu = perf_pmus__find("ibs_fetch");
- op_pmu = perf_pmus__find("ibs_op");
+ fetch_pmu = perf_pmus__find(pmus, "ibs_fetch");
+ op_pmu = perf_pmus__find(pmus, "ibs_op");
if (!x86__is_amd_cpu() || !fetch_pmu || !op_pmu)
return TEST_SKIP;
diff --git a/tools/perf/arch/x86/tests/amd-ibs-via-core-pmu.c b/tools/perf/arch/x86/tests/amd-ibs-via-core-pmu.c
index 78b1902f6f59..a509a861b4f5 100644
--- a/tools/perf/arch/x86/tests/amd-ibs-via-core-pmu.c
+++ b/tools/perf/arch/x86/tests/amd-ibs-via-core-pmu.c
@@ -2,6 +2,7 @@
#include "arch-tests.h"
#include "linux/perf_event.h"
#include "tests/tests.h"
+#include "env.h"
#include "pmu.h"
#include "pmus.h"
#include "../perf-sys.h"
@@ -44,7 +45,7 @@ int test__amd_ibs_via_core_pmu(struct test_suite *test __maybe_unused,
int ret = TEST_OK;
int fd, i;
- ibs_pmu = perf_pmus__find("ibs_op");
+ ibs_pmu = perf_pmus__find(perf_env__pmus(host_env()), "ibs_op");
if (!ibs_pmu)
return TEST_SKIP;
diff --git a/tools/perf/arch/x86/tests/hybrid.c b/tools/perf/arch/x86/tests/hybrid.c
index 011217998a3e..0146cc2e0c5b 100644
--- a/tools/perf/arch/x86/tests/hybrid.c
+++ b/tools/perf/arch/x86/tests/hybrid.c
@@ -112,10 +112,11 @@ static int test__hybrid_group_modifier1(struct evlist *evlist)
static int test__hybrid_raw1(struct evlist *evlist)
{
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
struct perf_evsel *evsel;
perf_evlist__for_each_evsel(evlist__core(evlist), evsel) {
- struct perf_pmu *pmu = perf_pmus__find_by_type(evsel->attr.type);
+ struct perf_pmu *pmu = perf_pmus__find_by_type(pmus, evsel->attr.type);
TEST_ASSERT_VAL("missing pmu", pmu);
TEST_ASSERT_VAL("unexpected pmu", !strncmp(pmu->name, "cpu_", 4));
diff --git a/tools/perf/arch/x86/tests/topdown.c b/tools/perf/arch/x86/tests/topdown.c
index 520075329c37..827169b60813 100644
--- a/tools/perf/arch/x86/tests/topdown.c
+++ b/tools/perf/arch/x86/tests/topdown.c
@@ -5,6 +5,7 @@
#include "arch-tests.h"
#include "../util/topdown.h"
#include "debug.h"
+#include "env.h"
#include "evlist.h"
#include "parse-events.h"
#include "pmu.h"
@@ -245,7 +246,7 @@ static int test__x86_topdown_metrics_clear(struct test_suite *test __maybe_unuse
if (!topdown_sys_has_perf_metrics())
return TEST_OK;
- pmu = perf_pmus__find_by_type(PERF_TYPE_RAW);
+ pmu = perf_pmus__find_by_type(perf_env__pmus(host_env()), PERF_TYPE_RAW);
if (!pmu || !perf_pmu__has_format(pmu, "metrics_clear"))
return TEST_OK;
diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c
index 84fce0b51ccf..540caf06d15c 100644
--- a/tools/perf/arch/x86/util/auxtrace.c
+++ b/tools/perf/arch/x86/util/auxtrace.c
@@ -9,6 +9,7 @@
#include "../../../util/header.h"
#include "../../../util/debug.h"
+#include "../../../util/env.h"
#include "../../../util/pmu.h"
#include "../../../util/pmus.h"
#include "../../../util/auxtrace.h"
@@ -20,15 +21,13 @@ static
struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist,
int *err)
{
- struct perf_pmu *intel_pt_pmu;
- struct perf_pmu *intel_bts_pmu;
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
+ struct perf_pmu *intel_pt_pmu = perf_pmus__find(pmus, INTEL_PT_PMU_NAME);
+ struct perf_pmu *intel_bts_pmu = perf_pmus__find(pmus, INTEL_BTS_PMU_NAME);
struct evsel *evsel;
bool found_pt = false;
bool found_bts = false;
- intel_pt_pmu = perf_pmus__find(INTEL_PT_PMU_NAME);
- intel_bts_pmu = perf_pmus__find(INTEL_BTS_PMU_NAME);
-
evlist__for_each_entry(evlist, evsel) {
if (intel_pt_pmu && evsel->core.attr.type == intel_pt_pmu->type)
found_pt = true;
diff --git a/tools/perf/arch/x86/util/evsel.c b/tools/perf/arch/x86/util/evsel.c
index 23a8e662a912..a8e239d29b72 100644
--- a/tools/perf/arch/x86/util/evsel.c
+++ b/tools/perf/arch/x86/util/evsel.c
@@ -132,6 +132,7 @@ static void ibs_l3miss_warn(void)
void arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr)
{
+ struct perf_pmus *pmus;
struct perf_pmu *evsel_pmu, *ibs_fetch_pmu, *ibs_op_pmu;
static int warned_once;
@@ -142,8 +143,9 @@ void arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr)
if (!evsel_pmu)
return;
- ibs_fetch_pmu = perf_pmus__find("ibs_fetch");
- ibs_op_pmu = perf_pmus__find("ibs_op");
+ pmus = perf_env__pmus(host_env());
+ ibs_fetch_pmu = perf_pmus__find(pmus, "ibs_fetch");
+ ibs_op_pmu = perf_pmus__find(pmus, "ibs_op");
if (ibs_fetch_pmu && ibs_fetch_pmu->type == evsel_pmu->type) {
if (attr->config & IBS_FETCH_L3MISSONLY) {
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index d44d568a6d21..2a7b20f5a1ca 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -19,6 +19,7 @@
#include "../../../util/auxtrace.h"
#include "../../../util/cpumap.h"
#include "../../../util/debug.h"
+#include "../../../util/env.h"
#include "../../../util/event.h"
#include "../../../util/evlist.h"
#include "../../../util/evsel.h"
@@ -420,7 +421,8 @@ static int intel_bts_find_snapshot(struct auxtrace_record *itr, int idx,
struct auxtrace_record *intel_bts_recording_init(int *err)
{
- struct perf_pmu *intel_bts_pmu = perf_pmus__find(INTEL_BTS_PMU_NAME);
+ struct perf_pmu *intel_bts_pmu = perf_pmus__find(perf_env__pmus(host_env()),
+ INTEL_BTS_PMU_NAME);
struct intel_bts_recording *btsr;
if (!intel_bts_pmu)
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index a533114c0048..7756971ade50 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -23,6 +23,7 @@
#include "../../../util/config.h"
#include "../../../util/cpumap.h"
#include "../../../util/debug.h"
+#include "../../../util/env.h"
#include "../../../util/event.h"
#include "../../../util/evlist.h"
#include "../../../util/evsel.h"
@@ -1195,7 +1196,8 @@ static int intel_pt_perf_config(const char *var, const char *value, void *data)
struct auxtrace_record *intel_pt_recording_init(int *err)
{
- struct perf_pmu *intel_pt_pmu = perf_pmus__find(INTEL_PT_PMU_NAME);
+ struct perf_pmu *intel_pt_pmu = perf_pmus__find(perf_env__pmus(host_env()),
+ INTEL_PT_PMU_NAME);
struct intel_pt_recording *ptr;
if (!intel_pt_pmu)
diff --git a/tools/perf/arch/x86/util/topdown.c b/tools/perf/arch/x86/util/topdown.c
index 64bc64e335a2..797ace8999e4 100644
--- a/tools/perf/arch/x86/util/topdown.c
+++ b/tools/perf/arch/x86/util/topdown.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
+#include "util/env.h"
#include "util/evlist.h"
#include "util/pmu.h"
#include "util/pmus.h"
@@ -26,7 +27,7 @@ bool topdown_sys_has_perf_metrics(void)
* The slots event is only available when the core PMU
* supports the perf metrics feature.
*/
- pmu = perf_pmus__find_by_type(PERF_TYPE_RAW);
+ pmu = perf_pmus__find_by_type(perf_env__pmus(host_env()), PERF_TYPE_RAW);
if (pmu && perf_pmu__have_event(pmu, "slots"))
has_perf_metrics = true;
diff --git a/tools/perf/bench/pmu-scan.c b/tools/perf/bench/pmu-scan.c
index 1d7dd4b203e0..754486d1d87b 100644
--- a/tools/perf/bench/pmu-scan.c
+++ b/tools/perf/bench/pmu-scan.c
@@ -77,6 +77,7 @@ static int save_result(void)
static int check_result(bool core_only)
{
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
struct pmu_scan_result *r;
struct perf_pmu *pmu;
struct list_head *list;
@@ -87,7 +88,7 @@ static int check_result(bool core_only)
if (core_only && !r->is_core)
continue;
- pmu = perf_pmus__find(r->name);
+ pmu = perf_pmus__find(pmus, r->name);
if (pmu == NULL) {
pr_err("Cannot find PMU %s\n", r->name);
return -1;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8706798290eb..f81192cec481 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1982,6 +1982,7 @@ static int default_evlist_evsel_cmp(void *priv __maybe_unused,
static int add_default_events(void)
{
const char *pmu = parse_events_option_args.pmu_filter ?: "all";
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
struct parse_events_error err;
struct evlist *evlist = evlist__new();
struct evsel *evsel;
@@ -2002,7 +2003,7 @@ static int add_default_events(void)
* will use this approach. To determine transaction support
* on an architecture test for such a metric name.
*/
- if (!metricgroup__has_metric_or_groups(pmu, "transaction")) {
+ if (!metricgroup__has_metric_or_groups(pmus, pmu, "transaction")) {
pr_err("Missing transaction metrics\n");
ret = -1;
goto out;
@@ -2037,7 +2038,7 @@ static int add_default_events(void)
smi_reset = true;
}
- if (!metricgroup__has_metric_or_groups(pmu, "smi")) {
+ if (!metricgroup__has_metric_or_groups(pmus, pmu, "smi")) {
pr_err("Missing smi metrics\n");
ret = -1;
goto out;
@@ -2113,7 +2114,8 @@ static int add_default_events(void)
for (size_t i = 0; i < ARRAY_SIZE(default_metricgroup_names); i++) {
struct evlist *metric_evlist;
- if (!metricgroup__has_metric_or_groups(pmu, default_metricgroup_names[i]))
+ if (!metricgroup__has_metric_or_groups(pmus, pmu,
+ default_metricgroup_names[i]))
continue;
if ((int)i > detailed_run)
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 8969bcf004ea..c95f6d6f5854 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -641,7 +641,7 @@ static int test__checkevent_pmu(struct evlist *evlist)
{
struct evsel *evsel = evlist__first(evlist);
- struct perf_pmu *core_pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *core_pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
TEST_ASSERT_EVSEL("wrong number of entries", 1 == evlist__nr_entries(evlist), evsel);
TEST_ASSERT_EVSEL("wrong type", core_pmu->type == evsel->core.attr.type, evsel);
@@ -705,7 +705,7 @@ static int test__checkevent_list(struct evlist *evlist)
static int test__checkevent_pmu_name(struct evlist *evlist)
{
struct evsel *evsel = evlist__first(evlist);
- struct perf_pmu *core_pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *core_pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
char buf[256];
/* default_core/config=1,name=krava/u */
@@ -729,7 +729,7 @@ static int test__checkevent_pmu_name(struct evlist *evlist)
static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist)
{
struct evsel *evsel = evlist__first(evlist);
- struct perf_pmu *core_pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *core_pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
/* default_core/config=1,call-graph=fp,time,period=100000/ */
TEST_ASSERT_EVLIST("wrong number of entries",
@@ -762,7 +762,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist)
static int test__checkevent_pmu_events(struct evlist *evlist)
{
struct evsel *evsel;
- struct perf_pmu *core_pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *core_pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
TEST_ASSERT_EVLIST("wrong number of entries", 1 <= evlist__nr_entries(evlist), evlist);
@@ -1768,7 +1768,7 @@ static int test__checkevent_config_cache(struct evlist *evlist)
static bool test__pmu_default_core_event_valid(void)
{
- struct perf_pmu *pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
if (!pmu)
return false;
@@ -1778,7 +1778,7 @@ static bool test__pmu_default_core_event_valid(void)
static bool test__intel_pt_valid(void)
{
- return !!perf_pmus__find("intel_pt");
+ return !!perf_pmus__find(perf_env__pmus(host_env()), "intel_pt");
}
static int test__intel_pt(struct evlist *evlist)
@@ -2624,7 +2624,7 @@ static int combine_test_results(int existing, int latest)
static int test_events(const struct evlist_test *events, int cnt)
{
int ret = TEST_OK;
- struct perf_pmu *core_pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *core_pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
for (int i = 0; i < cnt; i++) {
struct evlist_test e = events[i];
diff --git a/tools/perf/trace/beauty/perf_event_open.c b/tools/perf/trace/beauty/perf_event_open.c
index bfdf322c6ede..edf156995be6 100644
--- a/tools/perf/trace/beauty/perf_event_open.c
+++ b/tools/perf/trace/beauty/perf_event_open.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: LGPL-2.1
#include <string.h>
#include "trace/beauty/beauty.h"
+#include "util/env.h"
#include "util/evsel_fprintf.h"
#include <linux/perf_event.h>
@@ -75,7 +76,8 @@ static size_t perf_event_attr___scnprintf(struct perf_event_attr *attr, char *bf
.bf = bf,
};
- perf_event_attr__fprintf(stdout, attr, attr__fprintf, &args);
+ perf_event_attr__fprintf(stdout, attr, attr__fprintf, &args,
+ perf_env__pmus(host_env()));
return args.printed + scnprintf(bf + args.printed, size - args.printed, " }");
}
diff --git a/tools/perf/util/aslr.c b/tools/perf/util/aslr.c
index e365f807b021..60928c490eb1 100644
--- a/tools/perf/util/aslr.c
+++ b/tools/perf/util/aslr.c
@@ -3,6 +3,7 @@
#include "addr_location.h"
#include "debug.h"
+#include "env.h"
#include "event.h"
#include "evsel.h"
#include "evlist.h"
@@ -1255,9 +1256,10 @@ void aslr_tool__strip_attr_event(union perf_event *event, struct evlist *evlist)
attr_size >= (offsetof(struct perf_event_attr, bp_addr) + sizeof(u64))) {
event->attr.attr.bp_addr = 0;
} else if (type >= PERF_TYPE_MAX) {
+ struct perf_env *env = evlist__env(evlist) ?: host_env();
struct perf_pmu *pmu;
- pmu = perf_pmus__find_by_type(type);
+ pmu = perf_pmus__find_by_type(perf_env__pmus(env), type);
if (pmu && (!strcmp(pmu->name, "kprobe") ||
!strcmp(pmu->name, "uprobe"))) {
if (attr_size >= (offsetof(struct perf_event_attr, config1) + sizeof(u64)))
@@ -1407,6 +1409,7 @@ int aslr_tool__cache_orig_attrs(struct perf_tool *tool, struct evsel *evsel)
void aslr_tool__strip_evlist(const struct perf_tool *tool __maybe_unused, struct evlist *evlist)
{
+ struct perf_pmus *pmus = perf_env__pmus(evlist__env(evlist) ?: host_env());
struct evsel *evsel;
evlist__for_each_entry(evlist, evsel) {
@@ -1419,7 +1422,7 @@ void aslr_tool__strip_evlist(const struct perf_tool *tool __maybe_unused, struct
if (evsel->core.attr.type == PERF_TYPE_BREAKPOINT) {
evsel->core.attr.bp_addr = 0;
} else if (evsel->core.attr.type >= PERF_TYPE_MAX) {
- struct perf_pmu *pmu = perf_pmus__find_by_type(evsel->core.attr.type);
+ struct perf_pmu *pmu = perf_pmus__find_by_type(pmus, evsel->core.attr.type);
if (pmu && (!strcmp(pmu->name, "kprobe") ||
!strcmp(pmu->name, "uprobe"))) {
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 5f16920f0a89..4f4ec49b6a6b 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -616,7 +616,7 @@ int perf_env__read_core_pmu_caps(struct perf_env *env)
return -ENODEV;
if (nr_pmu == 1) {
- pmu = perf_pmus__find_core_pmu();
+ pmu = perf_pmus__find_core_pmu(pmus);
if (!pmu)
return -ENODEV;
ret = perf_pmu__caps_parse(pmu);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 34ee1db63b9c..4053a80d3ba7 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2472,7 +2472,8 @@ static void display_attr(struct perf_event_attr *attr)
if (verbose >= 2 || debug_peo_args) {
fprintf(stderr, "%.60s\n", graph_dotted_line);
fprintf(stderr, "perf_event_attr:\n");
- perf_event_attr__fprintf(stderr, attr, __open_attr__fprintf, NULL);
+ perf_event_attr__fprintf(stderr, attr, __open_attr__fprintf, NULL,
+ perf_env__pmus(host_env()));
fprintf(stderr, "%.60s\n", graph_dotted_line);
}
}
@@ -4317,7 +4318,8 @@ bool evsel__fallback(struct evsel *evsel, struct target *target, int err,
* available even if no PMU support. PPC returned ENXIO rather
* than ENODEV or ENOENT until 2.6.37.
*/
- evsel->pmu = perf_pmus__find_by_type(PERF_TYPE_SOFTWARE);
+ evsel->pmu = perf_pmus__find_by_type(perf_env__pmus(host_env()),
+ PERF_TYPE_SOFTWARE);
assert(evsel->pmu); /* software is a "well-known" and can't fail PMU type. */
/* Configure the event. */
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
index 0f7a25500a44..ed7d13461575 100644
--- a/tools/perf/util/evsel_fprintf.c
+++ b/tools/perf/util/evsel_fprintf.c
@@ -2,6 +2,7 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
+#include "util/env.h"
#include "util/evlist.h"
#include "evsel.h"
#include "util/evsel_fprintf.h"
@@ -66,8 +67,11 @@ int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE
printed += fprintf(fp, "%s", evsel__name(evsel));
if (details->verbose) {
+ struct perf_env *env = evsel__env(evsel) ?: host_env();
+
printed += perf_event_attr__fprintf(fp, &evsel->core.attr,
- __print_attr__fprintf, &first);
+ __print_attr__fprintf, &first,
+ perf_env__pmus(env));
} else if (details->freq) {
const char *term = "sample_freq";
diff --git a/tools/perf/util/evsel_fprintf.h b/tools/perf/util/evsel_fprintf.h
index c8a9fac2f2dd..792437ceb578 100644
--- a/tools/perf/util/evsel_fprintf.h
+++ b/tools/perf/util/evsel_fprintf.h
@@ -6,6 +6,7 @@
#include <stdbool.h>
struct evsel;
+struct perf_pmus;
struct perf_attr_details {
bool freq;
@@ -46,5 +47,6 @@ int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *);
int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
- attr__fprintf_f attr__fprintf, void *priv);
+ attr__fprintf_f attr__fprintf, void *priv,
+ struct perf_pmus *pmus);
#endif // __PERF_EVSEL_H
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index b6f86f557caf..48ff46c165fd 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1704,7 +1704,7 @@ static int __write_pmu_caps(struct feat_fd *ff, struct perf_pmu *pmu,
static int write_cpu_pmu_caps(struct feat_fd *ff,
struct evlist *evlist __maybe_unused)
{
- struct perf_pmu *cpu_pmu = perf_pmus__find_core_pmu();
+ struct perf_pmu *cpu_pmu = perf_pmus__find_core_pmu(perf_env__pmus(host_env()));
int ret;
if (!cpu_pmu)
@@ -2492,6 +2492,7 @@ static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val,
static void print_event_desc(struct feat_fd *ff, FILE *fp)
{
+ struct perf_pmus *pmus = perf_env__pmus(&ff->ph->env);
struct evsel *evsel, *events;
u32 j;
u64 *id;
@@ -2519,7 +2520,7 @@ static void print_event_desc(struct feat_fd *ff, FILE *fp)
fprintf(fp, " }");
}
- perf_event_attr__fprintf(fp, &evsel->core.attr, __desc_attr__fprintf, NULL);
+ perf_event_attr__fprintf(fp, &evsel->core.attr, __desc_attr__fprintf, NULL, pmus);
fputc('\n', fp);
}
@@ -5735,7 +5736,8 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)
size_t perf_event__fprintf_attr(union perf_event *event, FILE *fp)
{
- return perf_event_attr__fprintf(fp, &event->attr.attr, __desc_attr__fprintf, NULL);
+ return perf_event_attr__fprintf(fp, &event->attr.attr, __desc_attr__fprintf, NULL,
+ perf_env__pmus(host_env()));
}
int perf_event__process_attr(const struct perf_tool *tool __maybe_unused,
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index c8d64573e4c0..4e1205c1d3b2 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -388,14 +388,14 @@ static bool match_metric_or_groups(const char *metric_or_groups, const char *sou
return m && match_metric_or_groups(m + 1, sought);
}
-static bool match_pm_metric_or_groups(const struct pmu_metric *pm, const char *pmu,
- const char *metric_or_groups)
+static bool match_pm_metric_or_groups(struct perf_pmus *pmus, const struct pmu_metric *pm,
+ const char *pmu, const char *metric_or_groups)
{
const char *pm_pmu = pm->pmu ?: "cpu";
struct perf_pmu *perf_pmu = NULL;
if (pm->pmu)
- perf_pmu = perf_pmus__find(pm->pmu);
+ perf_pmu = perf_pmus__find(pmus, pm->pmu);
if (strcmp(pmu, "all") && strcmp(pm_pmu, pmu) &&
(perf_pmu && !perf_pmu__name_wildcard_match(perf_pmu, pmu)))
@@ -697,6 +697,7 @@ struct metricgroup_add_iter_data {
};
static int add_metric(struct list_head *metric_list,
+ struct perf_pmus *pmus,
const struct pmu_metric *pm,
const char *modifier,
bool metric_no_group,
@@ -739,6 +740,7 @@ static int metricgroup__find_metric_callback(const struct pmu_metric *pm,
* architecture perf is running upon.
*/
static int resolve_metric(struct list_head *metric_list,
+ struct perf_pmus *pmus,
struct perf_pmu *pmu,
const char *modifier,
bool metric_no_group,
@@ -793,7 +795,7 @@ static int resolve_metric(struct list_head *metric_list,
* context.
*/
for (i = 0; i < pending_cnt; i++) {
- ret = add_metric(metric_list, &pending[i].pm, modifier, metric_no_group,
+ ret = add_metric(metric_list, pmus, &pending[i].pm, modifier, metric_no_group,
metric_no_threshold, user_requested_cpu_list, system_wide,
fake_pmu, root_metric, visited, table);
if (ret)
@@ -807,6 +809,7 @@ static int resolve_metric(struct list_head *metric_list,
/**
* __add_metric - Add a metric to metric_list.
* @metric_list: The list the metric is added to.
+ * @pmus: The PMUs collection for resolving referenced metrics.
* @pm: The pmu_metric containing the metric to be added.
* @modifier: if non-null event modifiers like "u".
* @metric_no_group: Should events written to events be grouped "{}" or
@@ -826,6 +829,7 @@ static int resolve_metric(struct list_head *metric_list,
* architecture perf is running upon.
*/
static int __add_metric(struct list_head *metric_list,
+ struct perf_pmus *pmus,
const struct pmu_metric *pm,
const char *modifier,
bool metric_no_group,
@@ -927,11 +931,11 @@ static int __add_metric(struct list_head *metric_list,
struct perf_pmu *pmu;
if (pm->pmu && pm->pmu[0] != '\0')
- pmu = perf_pmus__find(pm->pmu);
+ pmu = perf_pmus__find(pmus, pm->pmu);
else
pmu = perf_pmus__scan_core(/*pmu=*/ NULL);
- ret = resolve_metric(metric_list, pmu, modifier, metric_no_group,
+ ret = resolve_metric(metric_list, pmus, pmu, modifier, metric_no_group,
metric_no_threshold, user_requested_cpu_list,
system_wide, fake_pmu, root_metric, &visited_node,
table);
@@ -947,6 +951,7 @@ static int __add_metric(struct list_head *metric_list,
}
static int add_metric(struct list_head *metric_list,
+ struct perf_pmus *pmus,
const struct pmu_metric *pm,
const char *modifier,
bool metric_no_group,
@@ -963,7 +968,7 @@ static int add_metric(struct list_head *metric_list,
pr_debug("metric expr %s for %s\n", pm->metric_expr, pm->metric_name);
if (!strstr(pm->metric_expr, "?")) {
- ret = __add_metric(metric_list, pm, modifier, metric_no_group,
+ ret = __add_metric(metric_list, pmus, pm, modifier, metric_no_group,
metric_no_threshold, 0, user_requested_cpu_list,
system_wide, fake_pmu, root_metric, visited, table);
} else {
@@ -977,7 +982,7 @@ static int add_metric(struct list_head *metric_list,
*/
for (j = 0; j < count && !ret; j++)
- ret = __add_metric(metric_list, pm, modifier, metric_no_group,
+ ret = __add_metric(metric_list, pmus, pm, modifier, metric_no_group,
metric_no_threshold, j, user_requested_cpu_list,
system_wide, fake_pmu, root_metric, visited, table);
}
@@ -1033,6 +1038,7 @@ static int default_metricgroup_cmp(void *priv __maybe_unused,
struct metricgroup__add_metric_data {
struct list_head *list;
+ struct perf_pmus *pmus;
const char *pmu;
const char *metric_name;
const char *modifier;
@@ -1051,14 +1057,15 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
struct metricgroup__add_metric_data *data = vdata;
int ret = 0;
- if (pm->metric_expr && match_pm_metric_or_groups(pm, data->pmu, data->metric_name)) {
+ if (pm->metric_expr && match_pm_metric_or_groups(data->pmus, pm, data->pmu,
+ data->metric_name)) {
bool metric_no_group = data->metric_no_group ||
match_metric_or_groups(pm->metricgroup_no_group, data->metric_name);
data->has_match = true;
- ret = add_metric(data->list, pm, data->modifier, metric_no_group,
+ ret = add_metric(data->list, data->pmus, pm, data->modifier, metric_no_group,
data->metric_no_threshold, data->user_requested_cpu_list,
- data->system_wide, data->fake_pmu, /*root_metric=*/NULL,
+ data->system_wide, data->fake_pmu, /*root_metric=*/NULL,
/*visited_metrics=*/NULL, table);
}
return ret;
@@ -1066,6 +1073,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
/**
* metricgroup__add_metric - Find and add a metric, or a metric group.
+ * @pmus: The PMUs collection for resolving PMU names and referenced metrics.
* @pmu: The PMU name to search for metrics on, or "all" for all PMUs.
* @metric_name: The name of the metric or metric group. For example, "IPC"
* could be the name of a metric and "TopDownL1" the name of a
@@ -1081,7 +1089,8 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
* @table: The table that is searched for metrics, most commonly the table for the
* architecture perf is running upon.
*/
-static int metricgroup__add_metric(const char *pmu, const char *metric_name, const char *modifier,
+static int metricgroup__add_metric(struct perf_pmus *pmus, const char *pmu,
+ const char *metric_name, const char *modifier,
bool metric_no_group, bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide, bool fake_pmu,
@@ -1092,6 +1101,7 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
int ret;
struct metricgroup__add_metric_data data = {
.list = &list,
+ .pmus = pmus,
.pmu = pmu,
.metric_name = metric_name,
.modifier = modifier,
@@ -1122,6 +1132,7 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
/**
* metricgroup__add_metric_list - Find and add metrics, or metric groups,
* specified in a list.
+ * @pmus: The PMUs collection for resolving PMU names and referenced metrics.
* @pmu: A pmu to restrict the metrics to, or "all" for all PMUS.
* @list: the list of metrics or metric groups. For example, "IPC,CPI,TopDownL1"
* would match the IPC and CPI metrics, and TopDownL1 would match all
@@ -1136,7 +1147,8 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
* @table: The table that is searched for metrics, most commonly the table for the
* architecture perf is running upon.
*/
-static int metricgroup__add_metric_list(const char *pmu, const char *list,
+static int metricgroup__add_metric_list(struct perf_pmus *pmus, const char *pmu,
+ const char *list,
bool metric_no_group,
bool metric_no_threshold,
const char *user_requested_cpu_list,
@@ -1157,7 +1169,7 @@ static int metricgroup__add_metric_list(const char *pmu, const char *list,
if (modifier)
*modifier++ = '\0';
- ret = metricgroup__add_metric(pmu, metric_name, modifier,
+ ret = metricgroup__add_metric(pmus, pmu, metric_name, modifier,
metric_no_group, metric_no_threshold,
user_requested_cpu_list,
system_wide, fake_pmu,
@@ -1410,6 +1422,7 @@ static int parse_groups(struct evlist *perf_evlist,
bool fake_pmu,
const struct pmu_metrics_table *table)
{
+ struct perf_pmus *pmus = perf_env__pmus(evlist__env(perf_evlist) ?: host_env());
struct evlist *combined_evlist = NULL;
LIST_HEAD(metric_list);
struct metric *m;
@@ -1417,7 +1430,7 @@ static int parse_groups(struct evlist *perf_evlist,
bool is_default = !strcmp(str, "Default");
int ret;
- ret = metricgroup__add_metric_list(pmu, str, metric_no_group, metric_no_threshold,
+ ret = metricgroup__add_metric_list(pmus, pmu, str, metric_no_group, metric_no_threshold,
user_requested_cpu_list,
system_wide, fake_pmu,
&metric_list, table);
@@ -1616,6 +1629,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
}
struct metricgroup__has_metric_data {
+ struct perf_pmus *pmus;
const char *pmu;
const char *metric_or_groups;
};
@@ -1626,13 +1640,15 @@ static int metricgroup__has_metric_or_groups_callback(const struct pmu_metric *p
{
struct metricgroup__has_metric_data *data = vdata;
- return match_pm_metric_or_groups(pm, data->pmu, data->metric_or_groups) ? 1 : 0;
+ return match_pm_metric_or_groups(data->pmus, pm, data->pmu, data->metric_or_groups) ? 1 : 0;
}
-bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups)
+bool metricgroup__has_metric_or_groups(struct perf_pmus *pmus, const char *pmu,
+ const char *metric_or_groups)
{
const struct pmu_metrics_table *table = pmu_metrics_table__find();
struct metricgroup__has_metric_data data = {
+ .pmus = pmus,
.pmu = pmu,
.metric_or_groups = metric_or_groups,
};
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
index 6a66f14dd01b..bc5d3d21f405 100644
--- a/tools/perf/util/metricgroup.h
+++ b/tools/perf/util/metricgroup.h
@@ -10,6 +10,7 @@
struct evlist;
struct evsel;
struct option;
+struct perf_pmus;
struct print_callbacks;
struct rblist;
struct cgroup;
@@ -86,7 +87,8 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
void *data);
-bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups);
+bool metricgroup__has_metric_or_groups(struct perf_pmus *pmus, const char *pmu,
+ const char *metric_or_groups);
unsigned int metricgroups__topdown_max_level(void);
int arch_get_runtimeparam(const struct pmu_metric *pm);
void metricgroup__rblist_init(struct rblist *metric_events);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index b56f0e2d1542..bb99588589f4 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -85,7 +85,7 @@ static char *get_config_name(const struct parse_events_terms *head_terms)
}
static struct perf_cpu_map *get_config_cpu(const struct parse_events_terms *head_terms,
- bool fake_pmu)
+ struct parse_events_state *parse_state)
{
struct parse_events_term *term;
struct perf_cpu_map *cpus = NULL;
@@ -102,7 +102,8 @@ static struct perf_cpu_map *get_config_cpu(const struct parse_events_terms *head
if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
term_cpus = perf_cpu_map__new_int(term->val.num);
} else {
- struct perf_pmu *pmu = perf_pmus__find(term->val.str);
+ struct perf_pmu *pmu = perf_pmus__find(parse_state->pmus,
+ term->val.str);
if (pmu) {
term_cpus = pmu->is_core && perf_cpu_map__is_empty(pmu->cpus)
@@ -110,7 +111,7 @@ static struct perf_cpu_map *get_config_cpu(const struct parse_events_terms *head
: perf_cpu_map__get(pmu->cpus);
} else {
term_cpus = perf_cpu_map__new(term->val.str);
- if (!term_cpus && fake_pmu) {
+ if (!term_cpus && parse_state->fake_pmu) {
/*
* Assume the PMU string makes sense on a different
* machine and fake a value with all online CPUs.
@@ -929,7 +930,7 @@ do { \
break;
}
assert(term->type_val == PARSE_EVENTS__TERM_TYPE_STR);
- if (perf_pmus__find(term->val.str) != NULL)
+ if (perf_pmus__find(parse_state->pmus, term->val.str) != NULL)
break;
map = perf_cpu_map__new(term->val.str);
@@ -1429,7 +1430,7 @@ static 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);
- cpus = get_config_cpu(head_config, parse_state->fake_pmu);
+ cpus = get_config_cpu(head_config, parse_state);
ret = __add_event(list, &parse_state->idx, &attr, /*init_attr*/true, name,
metric_id, parse_state->pmus, pmu, &config_terms,
first_wildcard_match, cpus,
@@ -1471,7 +1472,8 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
if (found_supported)
return 0;
}
- return __parse_events_add_numeric(parse_state, list, perf_pmus__find_by_type(type),
+ return __parse_events_add_numeric(parse_state, list,
+ perf_pmus__find_by_type(parse_state->pmus, type),
type, /*extended_type=*/0, config, head_config,
/*first_wildcard_match=*/NULL);
}
@@ -1592,7 +1594,7 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state,
return -EINVAL;
}
- term_cpu = get_config_cpu(&parsed_terms, parse_state->fake_pmu);
+ term_cpu = get_config_cpu(&parsed_terms, parse_state);
evsel = __add_event(list, &parse_state->idx, &attr, /*init_attr=*/true,
get_config_name(&parsed_terms),
get_config_metric_id(&parsed_terms), parse_state->pmus, pmu,
@@ -1730,7 +1732,7 @@ int parse_events_multi_pmu_add_or_add_pmu(struct parse_events_state *parse_state
INIT_LIST_HEAD(*listp);
/* Attempt to add to list assuming event_or_pmu is a PMU name. */
- pmu = perf_pmus__find(event_or_pmu);
+ pmu = perf_pmus__find(parse_state->pmus, event_or_pmu);
if (pmu && !parse_events_add_pmu(parse_state, *listp, pmu, const_parsed_terms,
first_wildcard_match))
return 0;
diff --git a/tools/perf/util/perf-regs-arch/perf_regs_x86.c b/tools/perf/util/perf-regs-arch/perf_regs_x86.c
index 2d80f119629a..920f17b89659 100644
--- a/tools/perf/util/perf-regs-arch/perf_regs_x86.c
+++ b/tools/perf/util/perf-regs-arch/perf_regs_x86.c
@@ -534,7 +534,7 @@ __support_simd_reg_class(uint64_t sample_type, uint16_t qwords,
}
if (perf_pmus__num_core_pmus(pmus) > 1) {
- __u64 type = perf_pmus__find_core_pmu()->type;
+ __u64 type = perf_pmus__find_core_pmu(pmus)->type;
attr.config |= type << PERF_PMU_TYPE_SHIFT;
}
diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c
index 2e8be9a357dc..7fd87c0e19f6 100644
--- a/tools/perf/util/perf_event_attr_fprintf.c
+++ b/tools/perf/util/perf_event_attr_fprintf.c
@@ -298,9 +298,10 @@ do { \
#define PRINT_ATTRf_bf(_f, _p) PRINT_ATTRn_bf(#_f, _f, _p, false)
int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
- attr__fprintf_f attr__fprintf, void *priv)
+ attr__fprintf_f attr__fprintf, void *priv,
+ struct perf_pmus *pmus)
{
- struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type);
+ struct perf_pmu *pmu = perf_pmus__find_by_type(pmus, attr->type);
/*
* size == 0 means ABI0 — the producer didn't set attr.size.
* perf_event__fprintf_attr() may pass the raw mmap'd event
@@ -328,7 +329,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
u32 extended_type = attr->config >> PERF_PMU_TYPE_SHIFT;
if (extended_type)
- pmu = perf_pmus__find_by_type(extended_type);
+ pmu = perf_pmus__find_by_type(pmus, extended_type);
}
PRINT_ATTRn("type", type, p_type_id, true);
diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c
index ad9bc481da70..c761e701a41d 100644
--- a/tools/perf/util/pfm.c
+++ b/tools/perf/util/pfm.c
@@ -6,6 +6,7 @@
*/
#include "util/cpumap.h"
#include "util/debug.h"
+#include "util/env.h"
#include "util/event.h"
#include "util/evlist.h"
#include "util/evsel.h"
@@ -35,6 +36,7 @@ int parse_libpfm_events_option(const struct option *opt, const char *str,
int unset __maybe_unused)
{
struct evlist *evlist = *(struct evlist **)opt->value;
+ struct perf_pmus *pmus = perf_env__pmus(host_env());
struct perf_event_attr attr;
struct perf_pmu *pmu;
struct evsel *evsel, *grp_leader = NULL;
@@ -84,7 +86,7 @@ int parse_libpfm_events_option(const struct option *opt, const char *str,
goto error;
}
- pmu = perf_pmus__find_by_type((unsigned int)attr.type);
+ pmu = perf_pmus__find_by_type(pmus, (unsigned int)attr.type);
evsel = parse_events__add_event(evlist__nr_entries(evlist),
&attr, q, /*metric_id=*/NULL,
pmu);
@@ -135,7 +137,7 @@ static bool is_libpfm_event_supported(const char *name, struct perf_cpu_map *cpu
if (ret != PFM_SUCCESS)
return false;
- pmu = perf_pmus__find_by_type((unsigned int)attr.type);
+ pmu = perf_pmus__find_by_type(perf_env__pmus(host_env()), (unsigned int)attr.type);
evsel = parse_events__add_event(0, &attr, name, /*metric_id=*/NULL, pmu);
if (evsel == NULL)
return false;
diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
index 472d62ccfc8f..4ad715783165 100644
--- a/tools/perf/util/pmus.c
+++ b/tools/perf/util/pmus.c
@@ -159,7 +159,7 @@ static struct perf_pmu *pmu_find(struct perf_pmus *pmus, const char *name)
return NULL;
}
-static struct perf_pmu *__perf_pmus__find(struct perf_pmus *pmus, const char *name)
+struct perf_pmu *perf_pmus__find(struct perf_pmus *pmus, const char *name)
{
struct perf_pmu *pmu;
int dirfd;
@@ -167,7 +167,7 @@ static struct perf_pmu *__perf_pmus__find(struct perf_pmus *pmus, const char *na
unsigned int to_read_pmus = 0;
if (!strcmp(name, "default_core"))
- return perf_pmus__find_core_pmu();
+ return perf_pmus__find_core_pmu(pmus);
/*
* Once PMU is loaded it stays in the list,
* so we keep us from multiple reading/parsing
@@ -216,11 +216,6 @@ static struct perf_pmu *__perf_pmus__find(struct perf_pmus *pmus, const char *na
return pmu_find(pmus, name);
}
-struct perf_pmu *perf_pmus__find(const char *name)
-{
- return __perf_pmus__find(perf_env__pmus(host_env()), name);
-}
-
static struct perf_pmu *perf_pmu__find2(struct perf_pmus *pmus, int dirfd, const char *name)
{
struct perf_pmu *pmu;
@@ -340,7 +335,7 @@ static struct perf_pmu *__perf_pmus__find_by_type(struct perf_pmus *pmus, unsign
return NULL;
}
-static struct perf_pmu *pmu_find_by_type(struct perf_pmus *pmus, unsigned int type)
+struct perf_pmu *perf_pmus__find_by_type(struct perf_pmus *pmus, unsigned int type)
{
unsigned int to_read_pmus;
struct perf_pmu *pmu = __perf_pmus__find_by_type(pmus, type);
@@ -363,11 +358,6 @@ static struct perf_pmu *pmu_find_by_type(struct perf_pmus *pmus, unsigned int ty
return pmu;
}
-struct perf_pmu *perf_pmus__find_by_type(unsigned int type)
-{
- return pmu_find_by_type(perf_env__pmus(host_env()), type);
-}
-
/*
* pmu iterator: If pmu is NULL, we start at the begin, otherwise return the
* next pmu. Returns NULL on end.
@@ -851,7 +841,7 @@ void perf_pmus__print_raw_pmu_events(struct perf_pmus *pmus,
bool perf_pmus__have_event(struct perf_pmus *pmus, const char *pname, const char *name)
{
- struct perf_pmu *pmu = __perf_pmus__find(pmus, pname);
+ struct perf_pmu *pmu = perf_pmus__find(pmus, pname);
return pmu && perf_pmu__have_event(pmu, name);
}
@@ -914,14 +904,14 @@ bool perf_pmus__host_supports_extended_type(void)
struct perf_pmu *perf_pmus__find_by_attr(struct perf_pmus *pmus,
const struct perf_event_attr *attr)
{
- struct perf_pmu *pmu = pmu_find_by_type(pmus, attr->type);
+ struct perf_pmu *pmu = perf_pmus__find_by_type(pmus, attr->type);
u32 type = attr->type;
bool legacy_core_type = type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE;
if (!pmu && legacy_core_type && perf_pmus__supports_extended_type(pmus)) {
type = attr->config >> PERF_PMU_TYPE_SHIFT;
- pmu = pmu_find_by_type(pmus, type);
+ pmu = perf_pmus__find_by_type(pmus, type);
}
if (!pmu && (legacy_core_type || type == PERF_TYPE_RAW)) {
/*
@@ -932,7 +922,7 @@ struct perf_pmu *perf_pmus__find_by_attr(struct perf_pmus *pmus,
* PERF_TYPE_RAW, assume the RAW events are going to be handled
* by the first core PMU.
*/
- pmu = pmu_scan_core(pmus, NULL);
+ pmu = perf_pmus__find_core_pmu(pmus);
}
return pmu;
}
@@ -951,9 +941,9 @@ struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
return pmu;
}
-struct perf_pmu *perf_pmus__find_core_pmu(void)
+struct perf_pmu *perf_pmus__find_core_pmu(struct perf_pmus *pmus)
{
- return perf_pmus__scan_core(NULL);
+ return pmu_scan_core(pmus, NULL);
}
struct perf_pmu *perf_pmus__add_test_pmu(struct perf_pmus *pmus,
diff --git a/tools/perf/util/pmus.h b/tools/perf/util/pmus.h
index 45f4bd8b6aa6..cd0c14f8e04b 100644
--- a/tools/perf/util/pmus.h
+++ b/tools/perf/util/pmus.h
@@ -75,8 +75,23 @@ void perf_pmus__init(struct perf_pmus *pmus);
*/
void perf_pmus__exit(struct perf_pmus *pmus);
-struct perf_pmu *perf_pmus__find(const char *name);
-struct perf_pmu *perf_pmus__find_by_type(unsigned int type);
+/**
+ * perf_pmus__find() - Find a PMU by name in @pmus.
+ * @pmus: The PMU collection to search.
+ * @name: Name of the PMU to look up.
+ *
+ * Return: Pointer to the matching struct perf_pmu, or NULL if not found.
+ */
+struct perf_pmu *perf_pmus__find(struct perf_pmus *pmus, const char *name);
+
+/**
+ * perf_pmus__find_by_type() - Find a PMU by its perf_event_attr type ID.
+ * @pmus: The PMU collection to search.
+ * @type: The PMU type identifier (e.g. PERF_TYPE_RAW or dynamic sysfs type).
+ *
+ * Return: Pointer to the matching struct perf_pmu, or NULL if not found.
+ */
+struct perf_pmu *perf_pmus__find_by_type(struct perf_pmus *pmus, unsigned int type);
/**
* perf_pmus__find_by_attr() - Find the PMU corresponding to @attr.
@@ -217,6 +232,12 @@ struct perf_pmu *perf_pmus__add_test_hwmon_pmu(struct perf_pmus *pmus,
* Return: Pointer to the fake struct perf_pmu.
*/
struct perf_pmu *perf_pmus__fake_pmu(void);
-struct perf_pmu *perf_pmus__find_core_pmu(void);
+/**
+ * perf_pmus__find_core_pmu() - Return the first core PMU in @pmus.
+ * @pmus: The PMU collection to search.
+ *
+ * Return: Pointer to the first core struct perf_pmu, or NULL if none exists.
+ */
+struct perf_pmu *perf_pmus__find_core_pmu(struct perf_pmus *pmus);
#endif /* __PMUS_H */
diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c
index aaf8838b2cb2..650dfcba794a 100644
--- a/tools/perf/util/s390-sample-raw.c
+++ b/tools/perf/util/s390-sample-raw.c
@@ -24,6 +24,7 @@
#include "color.h"
#include "debug.h"
+#include "env.h"
#include "evlist.h"
#include "hashmap.h"
#include "pmu.h"
@@ -352,8 +353,11 @@ void evlist__s390_sample_raw(struct evlist *evlist, union perf_event *event,
/* Display raw data on screen */
if (sample->evsel->core.attr.config == PERF_EVENT_CPUM_CF_DIAG) {
- if (!sample->evsel->pmu)
- sample->evsel->pmu = perf_pmus__find("cpum_cf");
+ if (!sample->evsel->pmu) {
+ struct perf_env *env = evsel__env(sample->evsel) ?: host_env();
+
+ sample->evsel->pmu = perf_pmus__find(perf_env__pmus(env), "cpum_cf");
+ }
if (!s390_cpumcfdg_testctr(sample))
pr_err("Invalid counter set data encountered\n");
else
@@ -375,8 +379,12 @@ void evlist__s390_sample_raw(struct evlist *evlist, union perf_event *event,
if (!s390_pai_all_test(sample)) {
pr_err("Invalid %s raw data encountered\n", pai_name);
} else {
- if (!sample->evsel->pmu)
- sample->evsel->pmu = perf_pmus__find_by_type(sample->evsel->core.attr.type);
+ if (!sample->evsel->pmu) {
+ struct perf_env *env = evsel__env(sample->evsel) ?: host_env();
+
+ sample->evsel->pmu = perf_pmus__find_by_type(perf_env__pmus(env),
+ sample->evsel->core.attr.type);
+ }
s390_pai_all_dump(sample);
}
}
--
2.56.0.385.gac671c819a-goog
next prev parent reply other threads:[~2026-11-03 23:45 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 23:44 [PATCH v1 00/41] perf: Per-env PMUs, recorded event metrics, and perf sysinfo Ian Rogers
2026-11-03 23:44 ` [PATCH v1 01/41] perf env: Make lazy perf_env initialization thread-safe Ian Rogers
2026-11-03 23:53 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 02/41] perf env: Add host_env() singleton Ian Rogers
2026-11-04 0:18 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 03/41] perf pmu: Add from_env parameter to perf_pmu__init() Ian Rogers
2026-11-04 0:31 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 04/41] perf pmus: Introduce struct perf_pmus and perf_env__pmus() Ian Rogers
2026-11-04 0:48 ` sashiko-bot
2026-11-03 23:44 ` Ian Rogers [this message]
2026-11-04 0:56 ` [PATCH v1 05/41] perf pmus: Pass struct perf_pmus to find helpers sashiko-bot
2026-11-03 23:44 ` [PATCH v1 06/41] perf pmus: Pass struct perf_pmus to scan helpers Ian Rogers
2026-11-04 1:01 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 07/41] perf pmu-events: Add e_machine to struct pmu_events_map Ian Rogers
2026-11-04 1:06 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 08/41] perf pmu-events: Pass e_machine to find_core_*_table() Ian Rogers
2026-11-04 1:14 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 09/41] perf header: Pass e_machine to strcmp_cpuid_str() Ian Rogers
2026-11-04 1:18 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 10/41] perf header: Support CPUID matching across all architectures Ian Rogers
2026-11-04 1:23 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 11/41] perf test: Make the CPUID matching test architecture independent Ian Rogers
2026-11-04 1:32 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 12/41] perf test: Add CPUID matching tests for other architectures Ian Rogers
2026-11-04 1:36 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 13/41] perf pmus: Add perf_pmus__read_from_env() Ian Rogers
2026-11-04 2:05 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 14/41] perf metricgroup: Pass struct perf_pmus to metricgroup__for_each_metric() Ian Rogers
2026-11-04 2:17 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 15/41] perf metricgroup: Move matching of metrics to recorded events from perf script Ian Rogers
2026-11-04 2:36 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 16/41] perf parse-events: Decode metric-id terms when adding events Ian Rogers
2026-11-04 2:44 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 17/41] perf evsel: Generalize metric_id to a set of metric_ids Ian Rogers
2026-11-04 3:17 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 18/41] perf pmu: Add perf_pmu__for_each_name_from_config() Ian Rogers
2026-11-04 3:23 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 19/41] perf metricgroup: Improve matching of metrics to recorded events Ian Rogers
2026-11-04 3:46 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 20/41] perf metricgroup: Add metricgroup__add_recorded_metrics() Ian Rogers
2026-11-04 4:10 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 21/41] perf script: Fix metrics computed from samples Ian Rogers
2026-11-04 4:16 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 22/41] perf script: Don't drop metric samples for CPUs missing from the evsel Ian Rogers
2026-11-04 4:22 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 23/41] perf stat report: Display metrics for recorded events Ian Rogers
2026-11-04 4:39 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 24/41] perf script: Display metrics for perf stat record data Ian Rogers
2026-11-04 4:47 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 25/41] perf test: Add stat record metrics test Ian Rogers
2026-11-04 5:01 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 26/41] perf pmus: Expose duplicate uncore PMU scanning helpers Ian Rogers
2026-11-04 5:08 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 27/41] perf mem-events: Expose PMU init and name formatting helpers Ian Rogers
2026-11-04 5:20 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 28/41] perf pmu: Add perf_pmu__probe() for basic open, counting, and sampling Ian Rogers
2026-11-04 5:39 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 29/41] perf pmu: Probe supported sample_type flags Ian Rogers
2026-11-04 5:49 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 30/41] perf pmu: Probe precise_ip levels Ian Rogers
2026-11-04 5:59 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 31/41] perf pmu: Probe privilege exclusion modifiers Ian Rogers
2026-11-04 6:04 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 32/41] perf pmu: Probe execution and AUX area features Ian Rogers
2026-11-04 6:19 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 33/41] perf pmu: Probe event group size limits Ian Rogers
2026-11-04 6:22 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 34/41] perf pmu: Probe user and interrupt sample register masks Ian Rogers
2026-11-04 6:44 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 35/41] perf pmu: Probe interrupt registers that require precise sampling Ian Rogers
2026-11-04 6:53 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 36/41] perf pmu: Probe memory profiling events and sample formats Ian Rogers
2026-11-04 7:04 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 37/41] perf pmu: Probe user-space mmap capabilities Ian Rogers
2026-11-04 7:27 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 38/41] perf pmu: Probe branch instruction skid Ian Rogers
2026-11-04 7:32 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 39/41] perf sysinfo: Add sysinfo subcommand Ian Rogers
2026-11-04 7:50 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 40/41] perf docs: Add perf-sysinfo man page Ian Rogers
2026-11-04 7:51 ` sashiko-bot
2026-11-03 23:44 ` [PATCH v1 41/41] perf test: Add perf sysinfo shell test Ian Rogers
2026-11-04 7:59 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103234502.1008382-6-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=atrajeev@linux.ibm.com \
--cc=dapeng1.mi@linux.intel.com \
--cc=james.clark@linaro.org \
--cc=john.garry@linux.dev \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=leo.yan@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=ravi.bangoria@amd.com \
--cc=sandipan.das@amd.com \
--cc=thomas.falcon@intel.com \
--cc=tmricht@linux.ibm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox