Linux Perf Users
 help / color / mirror / Atom feed
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 +-
 tools/perf/util/header.c                      |  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
diff --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


  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