diff mbox

[v3,6/6] cpufreq: intel_pstate: Avoid calculation for max/min

Message ID 1443567248-27134-7-git-send-email-srinivas.pandruvada@linux.intel.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

srinivas pandruvada Sept. 29, 2015, 10:54 p.m. UTC
When requested from cpufreq to set policy, look into _pss and get
control values, instead of using max/min perf calculations. These
calculation misses next control state in boundary conditions.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 drivers/cpufreq/intel_pstate.c | 50 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 5 deletions(-)

Comments

Kristen Carlson Accardi Oct. 13, 2015, 8:41 p.m. UTC | #1
On Tue, 29 Sep 2015 15:54:08 -0700
Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> wrote:

> When requested from cpufreq to set policy, look into _pss and get
> control values, instead of using max/min perf calculations. These
> calculation misses next control state in boundary conditions.
> 
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

Acked-by: Kristen Carlson Accardi <kristen@linux.intel.com>

> ---
>  drivers/cpufreq/intel_pstate.c | 50 +++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
> index 869f074..49a16ff 100644
> --- a/drivers/cpufreq/intel_pstate.c
> +++ b/drivers/cpufreq/intel_pstate.c
> @@ -166,6 +166,8 @@ struct perf_limits {
>  	int max_sysfs_pct;
>  	int min_policy_pct;
>  	int min_sysfs_pct;
> +	int max_perf_ctl;
> +	int min_perf_ctl;
>  };
>  
>  static struct perf_limits limits = {
> @@ -179,6 +181,8 @@ static struct perf_limits limits = {
>  	.max_sysfs_pct = 100,
>  	.min_policy_pct = 0,
>  	.min_sysfs_pct = 0,
> +	.max_perf_ctl = 0,
> +	.min_perf_ctl = 0,
>  };
>  
>  #if IS_ENABLED(CONFIG_ACPI)
> @@ -980,12 +984,23 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
>  	 * policy, or by cpu specific default values determined through
>  	 * experimentation.
>  	 */
> -	max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
> -	*max = clamp_t(int, max_perf_adj,
> -			cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
> +	if (limits.max_perf_ctl && limits.max_sysfs_pct >=
> +						limits.max_policy_pct) {
> +		*max = limits.max_perf_ctl;
> +	} else {
> +		max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf),
> +					limits.max_perf));
> +		*max = clamp_t(int, max_perf_adj, cpu->pstate.min_pstate,
> +			       cpu->pstate.turbo_pstate);
> +	}
>  
> -	min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
> -	*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
> +	if (limits.min_perf_ctl) {
> +		*min = limits.min_perf_ctl;
> +	} else {
> +		min_perf = fp_toint(mul_fp(int_tofp(max_perf),
> +				    limits.min_perf));
> +		*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
> +	}
>  }
>  
>  static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate, bool force)
> @@ -1272,6 +1287,12 @@ static unsigned int intel_pstate_get(unsigned int cpu_num)
>  
>  static int intel_pstate_set_policy(struct cpufreq_policy *policy)
>  {
> +#if IS_ENABLED(CONFIG_ACPI)
> +	struct cpudata *cpu;
> +	int i;
> +#endif
> +	pr_debug("intel_pstate: %s max %u policy->max %u\n", __func__,
> +		 policy->cpuinfo.max_freq, policy->max);
>  	if (!policy->cpuinfo.max_freq)
>  		return -ENODEV;
>  
> @@ -1284,6 +1305,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
>  		limits.max_perf_pct = 100;
>  		limits.max_perf = int_tofp(1);
>  		limits.no_turbo = 0;
> +		limits.max_perf_ctl = 0;
> +		limits.min_perf_ctl = 0;
>  		return 0;
>  	}
>  
> @@ -1304,6 +1327,23 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
>  	limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
>  	limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
>  
> +#if IS_ENABLED(CONFIG_ACPI)
> +	cpu = all_cpu_data[policy->cpu];
> +	for (i = 0; i < cpu->acpi_perf_data.state_count; i++) {
> +		int control;
> +
> +		control = convert_to_native_pstate_format(cpu, i);
> +		if (control * cpu->pstate.scaling == policy->max)
> +			limits.max_perf_ctl = control;
> +		if (control * cpu->pstate.scaling == policy->min)
> +			limits.min_perf_ctl = control;
> +	}
> +
> +	pr_debug("intel_pstate: max %u policy_max %u perf_ctl [0x%x-0x%x]\n",
> +		 policy->cpuinfo.max_freq, policy->max, limits.min_perf_ctl,
> +		 limits.max_perf_ctl);
> +#endif
> +
>  	if (hwp_active)
>  		intel_pstate_hwp_set();
>  

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 869f074..49a16ff 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -166,6 +166,8 @@  struct perf_limits {
 	int max_sysfs_pct;
 	int min_policy_pct;
 	int min_sysfs_pct;
+	int max_perf_ctl;
+	int min_perf_ctl;
 };
 
 static struct perf_limits limits = {
@@ -179,6 +181,8 @@  static struct perf_limits limits = {
 	.max_sysfs_pct = 100,
 	.min_policy_pct = 0,
 	.min_sysfs_pct = 0,
+	.max_perf_ctl = 0,
+	.min_perf_ctl = 0,
 };
 
 #if IS_ENABLED(CONFIG_ACPI)
@@ -980,12 +984,23 @@  static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
 	 * policy, or by cpu specific default values determined through
 	 * experimentation.
 	 */
-	max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
-	*max = clamp_t(int, max_perf_adj,
-			cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
+	if (limits.max_perf_ctl && limits.max_sysfs_pct >=
+						limits.max_policy_pct) {
+		*max = limits.max_perf_ctl;
+	} else {
+		max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf),
+					limits.max_perf));
+		*max = clamp_t(int, max_perf_adj, cpu->pstate.min_pstate,
+			       cpu->pstate.turbo_pstate);
+	}
 
-	min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
-	*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
+	if (limits.min_perf_ctl) {
+		*min = limits.min_perf_ctl;
+	} else {
+		min_perf = fp_toint(mul_fp(int_tofp(max_perf),
+				    limits.min_perf));
+		*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
+	}
 }
 
 static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate, bool force)
@@ -1272,6 +1287,12 @@  static unsigned int intel_pstate_get(unsigned int cpu_num)
 
 static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 {
+#if IS_ENABLED(CONFIG_ACPI)
+	struct cpudata *cpu;
+	int i;
+#endif
+	pr_debug("intel_pstate: %s max %u policy->max %u\n", __func__,
+		 policy->cpuinfo.max_freq, policy->max);
 	if (!policy->cpuinfo.max_freq)
 		return -ENODEV;
 
@@ -1284,6 +1305,8 @@  static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 		limits.max_perf_pct = 100;
 		limits.max_perf = int_tofp(1);
 		limits.no_turbo = 0;
+		limits.max_perf_ctl = 0;
+		limits.min_perf_ctl = 0;
 		return 0;
 	}
 
@@ -1304,6 +1327,23 @@  static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 	limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
 	limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
 
+#if IS_ENABLED(CONFIG_ACPI)
+	cpu = all_cpu_data[policy->cpu];
+	for (i = 0; i < cpu->acpi_perf_data.state_count; i++) {
+		int control;
+
+		control = convert_to_native_pstate_format(cpu, i);
+		if (control * cpu->pstate.scaling == policy->max)
+			limits.max_perf_ctl = control;
+		if (control * cpu->pstate.scaling == policy->min)
+			limits.min_perf_ctl = control;
+	}
+
+	pr_debug("intel_pstate: max %u policy_max %u perf_ctl [0x%x-0x%x]\n",
+		 policy->cpuinfo.max_freq, policy->max, limits.min_perf_ctl,
+		 limits.max_perf_ctl);
+#endif
+
 	if (hwp_active)
 		intel_pstate_hwp_set();