Tony Jones 9e65a7
From: Sandipan Das <sandipan.das@amd.com>
Tony Jones 9e65a7
Date: Thu, 19 May 2022 15:33:30 +0530
Tony Jones 9e65a7
Subject: perf/x86/amd/uncore: Use dynamic events array
Tony Jones 9e65a7
Git-commit: 39621c5808f5dda75d03dc4b2d4d2b13a5a1c34b
Tony Jones 9e65a7
Patch-mainline: v6.0-rc1
Tony Jones 700454
References: jsc#PED-1754 (PerfMonV2), jsc#PED-1752
Tony Jones 9e65a7
Tony Jones 9e65a7
If AMD Performance Monitoring Version 2 (PerfMonV2) is
Tony Jones 9e65a7
supported, the number of available counters for a given
Tony Jones 9e65a7
uncore PMU may not be fixed across families and models
Tony Jones 9e65a7
and has to be determined at runtime.
Tony Jones 9e65a7
Tony Jones 9e65a7
The per-cpu uncore PMU data currently uses a fixed-sized
Tony Jones 9e65a7
array for event information. Make it dynamic based on the
Tony Jones 9e65a7
number of available counters.
Tony Jones 9e65a7
Tony Jones 9e65a7
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Tony Jones 9e65a7
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tony Jones 9e65a7
Link: https://lore.kernel.org/r/21eea0cb6de9d14f78d52d1d62637ae02bc900f5.1652954372.git.sandipan.das@amd.com
Tony Jones 9e65a7
Tony Jones 9e65a7
Signed-off-by: Tony Jones <tonyj@suse.de>
Tony Jones 9e65a7
---
Tony Jones 9e65a7
 arch/x86/events/amd/uncore.c | 38 +++++++++++++++++++++++++++++++-------
Tony Jones 9e65a7
 1 file changed, 31 insertions(+), 7 deletions(-)
Tony Jones 9e65a7
Tony Jones 9e65a7
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
Tony Jones 9e65a7
index 0d04414b97d2..8dfcf93711ab 100644
Tony Jones 9e65a7
--- a/arch/x86/events/amd/uncore.c
Tony Jones 9e65a7
+++ b/arch/x86/events/amd/uncore.c
Tony Jones 9e65a7
@@ -21,7 +21,6 @@
Tony Jones 9e65a7
 #define NUM_COUNTERS_NB		4
Tony Jones 9e65a7
 #define NUM_COUNTERS_L2		4
Tony Jones 9e65a7
 #define NUM_COUNTERS_L3		6
Tony Jones 9e65a7
-#define MAX_COUNTERS		6
Tony Jones 9e65a7
 
Tony Jones 9e65a7
 #define RDPMC_BASE_NB		6
Tony Jones 9e65a7
 #define RDPMC_BASE_LLC		10
Tony Jones 9e65a7
@@ -46,7 +45,7 @@ struct amd_uncore {
Tony Jones 9e65a7
 	u32 msr_base;
Tony Jones 9e65a7
 	cpumask_t *active_mask;
Tony Jones 9e65a7
 	struct pmu *pmu;
Tony Jones 9e65a7
-	struct perf_event *events[MAX_COUNTERS];
Tony Jones 9e65a7
+	struct perf_event **events;
Tony Jones 9e65a7
 	struct hlist_node node;
Tony Jones 9e65a7
 };
Tony Jones 9e65a7
 
Tony Jones 9e65a7
@@ -370,11 +369,19 @@ static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
Tony Jones 9e65a7
 			cpu_to_node(cpu));
Tony Jones 9e65a7
 }
Tony Jones 9e65a7
 
Tony Jones 9e65a7
+static inline struct perf_event **
Tony Jones 9e65a7
+amd_uncore_events_alloc(unsigned int num, unsigned int cpu)
Tony Jones 9e65a7
+{
Tony Jones 9e65a7
+	return kzalloc_node(sizeof(struct perf_event *) * num, GFP_KERNEL,
Tony Jones 9e65a7
+			    cpu_to_node(cpu));
Tony Jones 9e65a7
+}
Tony Jones 9e65a7
+
Tony Jones 9e65a7
 static int amd_uncore_cpu_up_prepare(unsigned int cpu)
Tony Jones 9e65a7
 {
Tony Jones 9e65a7
-	struct amd_uncore *uncore_nb = NULL, *uncore_llc;
Tony Jones 9e65a7
+	struct amd_uncore *uncore_nb = NULL, *uncore_llc = NULL;
Tony Jones 9e65a7
 
Tony Jones 9e65a7
 	if (amd_uncore_nb) {
Tony Jones 9e65a7
+		*per_cpu_ptr(amd_uncore_nb, cpu) = NULL;
Tony Jones 9e65a7
 		uncore_nb = amd_uncore_alloc(cpu);
Tony Jones 9e65a7
 		if (!uncore_nb)
Tony Jones 9e65a7
 			goto fail;
Tony Jones 9e65a7
@@ -384,11 +391,15 @@ static int amd_uncore_cpu_up_prepare(unsigned int cpu)
Tony Jones 9e65a7
 		uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL;
Tony Jones 9e65a7
 		uncore_nb->active_mask = &amd_nb_active_mask;
Tony Jones 9e65a7
 		uncore_nb->pmu = &amd_nb_pmu;
Tony Jones 9e65a7
+		uncore_nb->events = amd_uncore_events_alloc(num_counters_nb, cpu);
Tony Jones 9e65a7
+		if (!uncore_nb->events)
Tony Jones 9e65a7
+			goto fail;
Tony Jones 9e65a7
 		uncore_nb->id = -1;
Tony Jones 9e65a7
 		*per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb;
Tony Jones 9e65a7
 	}
Tony Jones 9e65a7
 
Tony Jones 9e65a7
 	if (amd_uncore_llc) {
Tony Jones 9e65a7
+		*per_cpu_ptr(amd_uncore_llc, cpu) = NULL;
Tony Jones 9e65a7
 		uncore_llc = amd_uncore_alloc(cpu);
Tony Jones 9e65a7
 		if (!uncore_llc)
Tony Jones 9e65a7
 			goto fail;
Tony Jones 9e65a7
@@ -398,6 +409,9 @@ static int amd_uncore_cpu_up_prepare(unsigned int cpu)
Tony Jones 9e65a7
 		uncore_llc->msr_base = MSR_F16H_L2I_PERF_CTL;
Tony Jones 9e65a7
 		uncore_llc->active_mask = &amd_llc_active_mask;
Tony Jones 9e65a7
 		uncore_llc->pmu = &amd_llc_pmu;
Tony Jones 9e65a7
+		uncore_llc->events = amd_uncore_events_alloc(num_counters_llc, cpu);
Tony Jones 9e65a7
+		if (!uncore_llc->events)
Tony Jones 9e65a7
+			goto fail;
Tony Jones 9e65a7
 		uncore_llc->id = -1;
Tony Jones 9e65a7
 		*per_cpu_ptr(amd_uncore_llc, cpu) = uncore_llc;
Tony Jones 9e65a7
 	}
Tony Jones 9e65a7
@@ -405,9 +419,16 @@ static int amd_uncore_cpu_up_prepare(unsigned int cpu)
Tony Jones 9e65a7
 	return 0;
Tony Jones 9e65a7
 
Tony Jones 9e65a7
 fail:
Tony Jones 9e65a7
-	if (amd_uncore_nb)
Tony Jones 9e65a7
-		*per_cpu_ptr(amd_uncore_nb, cpu) = NULL;
Tony Jones 9e65a7
-	kfree(uncore_nb);
Tony Jones 9e65a7
+	if (uncore_nb) {
Tony Jones 9e65a7
+		kfree(uncore_nb->events);
Tony Jones 9e65a7
+		kfree(uncore_nb);
Tony Jones 9e65a7
+	}
Tony Jones 9e65a7
+
Tony Jones 9e65a7
+	if (uncore_llc) {
Tony Jones 9e65a7
+		kfree(uncore_llc->events);
Tony Jones 9e65a7
+		kfree(uncore_llc);
Tony Jones 9e65a7
+	}
Tony Jones 9e65a7
+
Tony Jones 9e65a7
 	return -ENOMEM;
Tony Jones 9e65a7
 }
Tony Jones 9e65a7
 
Tony Jones 9e65a7
@@ -540,8 +561,11 @@ static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
Tony Jones 9e65a7
 	if (cpu == uncore->cpu)
Tony Jones 9e65a7
 		cpumask_clear_cpu(cpu, uncore->active_mask);
Tony Jones 9e65a7
 
Tony Jones 9e65a7
-	if (!--uncore->refcnt)
Tony Jones 9e65a7
+	if (!--uncore->refcnt) {
Tony Jones 9e65a7
+		kfree(uncore->events);
Tony Jones 9e65a7
 		kfree(uncore);
Tony Jones 9e65a7
+	}
Tony Jones 9e65a7
+
Tony Jones 9e65a7
 	*per_cpu_ptr(uncores, cpu) = NULL;
Tony Jones 9e65a7
 }
Tony Jones 9e65a7
 
Tony Jones 9e65a7