102 lines
3.5 KiB
Diff
102 lines
3.5 KiB
Diff
|
From f1525664ff9da3241b3556594dc0b67506ae1ddd Mon Sep 17 00:00:00 2001
|
||
|
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
||
|
Date: Tue, 10 Sep 2024 14:25:05 +0530
|
||
|
Subject: perf/x86/rapl: Fix the energy-pkg event for AMD CPUs
|
||
|
|
||
|
After commit ("x86/cpu/topology: Add support for the AMD 0x80000026 leaf"),
|
||
|
on AMD processors that support extended CPUID leaf 0x80000026, the
|
||
|
topology_die_cpumask() and topology_logical_die_id() macros, no longer
|
||
|
return the package cpumask and package id, instead they return the CCD
|
||
|
(Core Complex Die) mask and id respectively. This leads to the energy-pkg
|
||
|
event scope to be modified to CCD instead of package.
|
||
|
|
||
|
So, change the PMU scope for AMD and Hygon back to package.
|
||
|
|
||
|
On a 12 CCD 1 Package AMD Zen4 Genoa machine:
|
||
|
|
||
|
Before:
|
||
|
$ cat /sys/devices/power/cpumask
|
||
|
0,8,16,24,32,40,48,56,64,72,80,88.
|
||
|
|
||
|
The expected cpumask here is supposed to be just "0", as it is a package
|
||
|
scope event, only one CPU will be collecting the event for all the CPUs in
|
||
|
the package.
|
||
|
|
||
|
After:
|
||
|
$ cat /sys/devices/power/cpumask
|
||
|
0
|
||
|
|
||
|
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
||
|
---
|
||
|
arch/x86/events/rapl.c | 35 ++++++++++++++++++++++++++++++++---
|
||
|
1 file changed, 32 insertions(+), 3 deletions(-)
|
||
|
|
||
|
--- a/arch/x86/events/rapl.c
|
||
|
+++ b/arch/x86/events/rapl.c
|
||
|
@@ -139,9 +139,32 @@ static unsigned int rapl_cntr_mask;
|
||
|
static u64 rapl_timer_ms;
|
||
|
static struct perf_msr *rapl_msrs;
|
||
|
|
||
|
+/*
|
||
|
+ * RAPL Package energy counter scope:
|
||
|
+ * 1. AMD/HYGON platforms have a per-PKG package energy counter
|
||
|
+ * 2. For Intel platforms
|
||
|
+ * 2.1. CLX-AP is multi-die and its RAPL MSRs are die-scope
|
||
|
+ * 2.2. Other Intel platforms are single die systems so the scope can be
|
||
|
+ * considered as either pkg-scope or die-scope, and we are considering
|
||
|
+ * them as die-scope.
|
||
|
+ */
|
||
|
+#define rapl_pmu_is_pkg_scope() \
|
||
|
+ (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || \
|
||
|
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
|
||
|
+
|
||
|
+/*
|
||
|
+ * Helper function to get the correct topology id according to the
|
||
|
+ * RAPL PMU scope.
|
||
|
+ */
|
||
|
+static inline unsigned int get_rapl_pmu_idx(int cpu)
|
||
|
+{
|
||
|
+ return rapl_pmu_is_pkg_scope() ? topology_logical_package_id(cpu) :
|
||
|
+ topology_logical_die_id(cpu);
|
||
|
+}
|
||
|
+
|
||
|
static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
|
||
|
{
|
||
|
- unsigned int rapl_pmu_idx = topology_logical_die_id(cpu);
|
||
|
+ unsigned int rapl_pmu_idx = get_rapl_pmu_idx(cpu);
|
||
|
|
||
|
/*
|
||
|
* The unsigned check also catches the '-1' return value for non
|
||
|
@@ -617,7 +640,7 @@ static void __init init_rapl_pmu(void)
|
||
|
pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
|
||
|
rapl_hrtimer_init(pmu);
|
||
|
|
||
|
- rapl_pmus->pmus[topology_logical_die_id(cpu)] = pmu;
|
||
|
+ rapl_pmus->pmus[get_rapl_pmu_idx(cpu)] = pmu;
|
||
|
}
|
||
|
|
||
|
cpus_read_unlock();
|
||
|
@@ -626,6 +649,12 @@ static void __init init_rapl_pmu(void)
|
||
|
static int __init init_rapl_pmus(void)
|
||
|
{
|
||
|
int nr_rapl_pmu = topology_max_packages() * topology_max_dies_per_package();
|
||
|
+ int rapl_pmu_scope = PERF_PMU_SCOPE_DIE;
|
||
|
+
|
||
|
+ if (rapl_pmu_is_pkg_scope()) {
|
||
|
+ nr_rapl_pmu = topology_max_packages();
|
||
|
+ rapl_pmu_scope = PERF_PMU_SCOPE_PKG;
|
||
|
+ }
|
||
|
|
||
|
rapl_pmus = kzalloc(struct_size(rapl_pmus, pmus, nr_rapl_pmu), GFP_KERNEL);
|
||
|
if (!rapl_pmus)
|
||
|
@@ -641,8 +670,8 @@ static int __init init_rapl_pmus(void)
|
||
|
rapl_pmus->pmu.start = rapl_pmu_event_start;
|
||
|
rapl_pmus->pmu.stop = rapl_pmu_event_stop;
|
||
|
rapl_pmus->pmu.read = rapl_pmu_event_read;
|
||
|
+ rapl_pmus->pmu.scope = rapl_pmu_scope;
|
||
|
rapl_pmus->pmu.module = THIS_MODULE;
|
||
|
- rapl_pmus->pmu.scope = PERF_PMU_SCOPE_DIE;
|
||
|
rapl_pmus->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
|
||
|
|
||
|
init_rapl_pmu();
|