aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2023-06-16 19:01:34 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2023-06-16 19:01:34 -0300
commit82fe2e45cdb00de4fa648050ae33bdadf9b3294a (patch)
tree454abe377728c1b52fcc5582564cc214b7dc96f0
parente2be06662c1f310b60a3929f3fc944809c067307 (diff)
downloadlinux-perf/core.tar.gz
perf pmus: Check if we can encode the PMU number in perf_event_attr.typetmp.perf/coreperf/core
In some architectures we can't encode the PMU number in perf_event_attr.type and thus can't just ask for the same event in multiple CPUs (and thus PMUs), that is what we want in hybrid systems but we can't when that encoding isn't understood by the kernel, such as in ARM64's big.LITTLE. If that is the case, fallback to the previous behaviour till we find a better solution to have consistent output accross architectures with hybrid CPU configurations. Co-developed-with: Ian Rogers <irogers@google.com> Cc: James Clark <james.clark@arm.com> Cc: John Garry <john.g.garry@oracle.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mike Leach <mike.leach@linaro.org> Cc: Sumanth Korikkar <sumanthk@linux.ibm.com> Cc: Suzuki K Poulose <suzuki.poulose@arm.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/linux-perf-users/ZIzYgImv61OGK1wA@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/pmus.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
index a2032c1b7644fb..d891d72c824ec3 100644
--- a/tools/perf/util/pmus.c
+++ b/tools/perf/util/pmus.c
@@ -4,6 +4,7 @@
#include <subcmd/pager.h>
#include <sys/types.h>
#include <dirent.h>
+#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
@@ -492,9 +493,35 @@ int perf_pmus__num_core_pmus(void)
return count;
}
+static bool __perf_pmus__supports_extended_type(void)
+{
+ struct perf_pmu *pmu = NULL;
+
+ if (perf_pmus__num_core_pmus() <= 1)
+ return false;
+
+ while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
+ if (!is_event_supported(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES | ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)))
+ return false;
+ }
+
+ return true;
+}
+
+static bool perf_pmus__do_support_extended_type;
+
+static void perf_pmus__init_supports_extended_type(void)
+{
+ perf_pmus__do_support_extended_type = __perf_pmus__supports_extended_type();
+}
+
bool perf_pmus__supports_extended_type(void)
{
- return perf_pmus__num_core_pmus() > 1;
+ static pthread_once_t extended_type_once = PTHREAD_ONCE_INIT;
+
+ pthread_once(&extended_type_once, perf_pmus__init_supports_extended_type);
+
+ return perf_pmus__do_support_extended_type;
}
struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)