Determine asymmetric packing priorities by reading CPPC's
highest_perf so it can be read by arch code later to enable
asympacking if the difference between the minimum and
maximum highest_perf is small (<5%).
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
---
drivers/base/arch_topology.c | 40 ++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 8c5e47c28d9a..c80c782e5eb2 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -321,8 +321,47 @@ void __weak freq_inv_set_max_ratio(int cpu, u64 max_rate)
{
}
+void __weak arch_topology_init_cppc_asym(void)
+{
+}
+
#ifdef CONFIG_ACPI_CPPC_LIB
#include <acpi/cppc_acpi.h>
+#include <linux/limits.h>
+
+/**
+ * topology_init_cppc_asym_packing() - Detect CPPC-based asymmetric packing
+ * @priority_var: Per-CPU variable to store CPU priorities
+ *
+ * Query CPPC highest_perf for all CPUs and determine if asymmetric packing
+ * should be enabled based on minor performance differences (~5% threshold).
+ *
+ * Return: true if asympacking should be enabled, false otherwise
+ */
+bool topology_init_cppc_asym_packing(int __percpu *priority_var)
+{
+ struct cppc_perf_caps perf_caps;
+ u32 max_perf = 0, min_perf = U32_MAX;
+ int cpu;
+
+ if (!acpi_cpc_valid())
+ return false;
+
+ for_each_possible_cpu(cpu) {
+ if (cppc_get_perf_caps(cpu, &perf_caps))
+ return false;
+ if (perf_caps.highest_perf < perf_caps.nominal_perf ||
+ perf_caps.highest_perf < perf_caps.lowest_perf)
+ return false;
+
+ *per_cpu_ptr(priority_var, cpu) = perf_caps.highest_perf;
+ max_perf = max(max_perf, perf_caps.highest_perf);
+ min_perf = min(min_perf, perf_caps.highest_perf);
+ }
+
+ return (max_perf != min_perf) && !capacity_greater(max_perf, min_perf);
+}
+EXPORT_SYMBOL_GPL(topology_init_cppc_asym_packing);
static inline void topology_init_cpu_capacity_cppc(void)
{
@@ -369,6 +408,7 @@ static inline void topology_init_cpu_capacity_cppc(void)
cpu, topology_get_cpu_scale(cpu));
}
+ arch_topology_init_cppc_asym();
schedule_work(&update_topology_flags_work);
pr_debug("cpu_capacity: cpu_capacity initialization done\n");
--
2.34.1