Blob Blame History Raw
From: Giovanni Gherdovich <ggherdovich@suse.cz>
Date: Tue, 17 Dec 2019 10:36:31 +0100
Subject: cpufreq, intel_pstate: Ramp up frequency faster when utilisation reaches setpoint
Patch-mainline: Never, upstream favours power consumption over performance
References: bsc#1068680

SLE carried an out-of-tree patch for intel-pstate PID policy to decrease
the setpoint at which the CPU frequency was increased. This was necessary as
low-utilisation workloads would often be stuck at the lowest frequency and
hurt overall throughput. setpoint does not exist for the load-based policy
so this patch introduces equivalent logic to obey the setpoint used by PID.

Signed-off-by: Mel Gorman <mgorman@suse.de>
Signed-off-by: Giovanni Gherdovich <ggherdovich@suse.cz>
---
 drivers/cpufreq/intel_pstate.c |   29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -37,6 +37,8 @@
 #define INTEL_CPUFREQ_TRANSITION_LATENCY	20000
 #define INTEL_CPUFREQ_TRANSITION_DELAY		500
 
+#define CPUFREQ_SERVER_UTIL_THRESHOLD		10
+
 #ifdef CONFIG_ACPI
 #include <acpi/processor.h>
 #include <acpi/cppc_acpi.h>
@@ -178,6 +180,9 @@ struct vid_data {
  *			P-state capacity.
  * @max_perf_pct:	Maximum capacity limit in percent of the maximum turbo
  *			P-state capacity.
+ * @vanilla_policy:	If set to true, avoid the optimization that makes
+ *			frequency ramp up faster after utilisation reaches a
+ *			given threshold.
  */
 struct global_params {
 	bool no_turbo;
@@ -185,6 +190,7 @@ struct global_params {
 	bool turbo_disabled_mf;
 	int max_perf_pct;
 	int min_perf_pct;
+	bool vanilla_policy;
 };
 
 /**
@@ -1708,7 +1714,7 @@ static inline int32_t get_target_pstate(
 {
 	struct sample *sample = &cpu->sample;
 	int32_t busy_frac, boost;
-	int target, avg_pstate;
+	int target, avg_pstate, max_target;
 
 	busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift,
 			   sample->tsc);
@@ -1721,10 +1727,10 @@ static inline int32_t get_target_pstate(
 
 	sample->busy_scaled = busy_frac * 100;
 
-	target = global.no_turbo || global.turbo_disabled ?
+	max_target = global.no_turbo || global.turbo_disabled ?
 			cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
-	target += target >> 2;
-	target = mul_fp(target, busy_frac);
+	max_target += max_target >> 2;
+	target = mul_fp(max_target, busy_frac);
 	if (target < cpu->pstate.min_pstate)
 		target = cpu->pstate.min_pstate;
 
@@ -1739,6 +1745,19 @@ static inline int32_t get_target_pstate(
 	if (avg_pstate > target)
 		target += (avg_pstate - target) >> 1;
 
+	/*
+	 * If the policy is the Server Enterprise policy then ramp up faster
+	 * once utilisation hits CPUFREQ_SERVER_DEFAULT_SETPOINT similar to
+	 * the setpoint for the PID policy.
+	 */
+	if (sample->busy_scaled >= CPUFREQ_SERVER_UTIL_THRESHOLD &&
+	    !global.vanilla_policy) {
+		int delta = max(0, max_target - target);
+
+		target += delta >> 1;
+		target = min(max_target, target);
+	}
+
 	return target;
 }
 
@@ -2720,6 +2739,8 @@ static int __init intel_pstate_setup(cha
 		hwp_only = 1;
 	if (!strcmp(str, "per_cpu_perf_limits"))
 		per_cpu_limits = true;
+	if (!strcmp(str, "vanilla_policy"))
+		global.vanilla_policy = true;
 
 #ifdef CONFIG_ACPI
 	if (!strcmp(str, "support_acpi_ppc"))