diff mbox

intel_pstate: Force setting target pstate when required.

Message ID 1433083349-4039-1-git-send-email-dsmythies@telus.net (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Doug Smythies May 31, 2015, 2:42 p.m. UTC
During initialization and exit it is possible that the
target pstate might not actually be set. Furthermore,
the result can be that the driver and the processor
are out of synch and, under some conditions, the driver
might never send the processor the proper target pstate.

This patch adds a forced or unforced flag to the call to
intel_pstate_set_pstate. If forced, then specifically
bypass clamp checks and the do not send if it is the
same as last time check. If unforced, then, and as before,
do the current policy clamp checks, and do not do actual
send if the new target is the same as the old.

Signed-off-by: Doug Smythies <dsmythies@telus.net>
Reported-by: Marien Zwart <marien.zwart@gmail.com>
Reported-by: Alex Lochmann <alexander.lochmann@tu-dortmund.de>
Reported-by: Piotr Ko?aczkowski <pkolaczk@gmail.com>
Reported-by: Clemens Eisserer <linuxhippy@gmail.com>
Tested-by: Marien Zwart <marien.zwart@gmail.com>
Tested-by: Doug Smythies <dsmythies@telus.net>
---
 drivers/cpufreq/intel_pstate.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

Comments

Rafael J. Wysocki June 1, 2015, 10:02 a.m. UTC | #1
On Sunday, May 31, 2015 07:42:29 AM Doug Smythies wrote:
> During initialization and exit it is possible that the
> target pstate might not actually be set. Furthermore,
> the result can be that the driver and the processor
> are out of synch and, under some conditions, the driver
> might never send the processor the proper target pstate.
> 
> This patch adds a forced or unforced flag to the call to
> intel_pstate_set_pstate. If forced, then specifically
> bypass clamp checks and the do not send if it is the
> same as last time check. If unforced, then, and as before,
> do the current policy clamp checks, and do not do actual
> send if the new target is the same as the old.
> 
> Signed-off-by: Doug Smythies <dsmythies@telus.net>
> Reported-by: Marien Zwart <marien.zwart@gmail.com>
> Reported-by: Alex Lochmann <alexander.lochmann@tu-dortmund.de>
> Reported-by: Piotr Ko?aczkowski <pkolaczk@gmail.com>
> Reported-by: Clemens Eisserer <linuxhippy@gmail.com>
> Tested-by: Marien Zwart <marien.zwart@gmail.com>
> Tested-by: Doug Smythies <dsmythies@telus.net>
> ---
>  drivers/cpufreq/intel_pstate.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
> index 6414661..77b6edf 100644
> --- a/drivers/cpufreq/intel_pstate.c
> +++ b/drivers/cpufreq/intel_pstate.c
> @@ -33,6 +33,9 @@
>  #include <asm/cpu_device_id.h>
>  #include <asm/cpufeature.h>
>  
> +#define	FORCED		0
> +#define UNFORCED	1

Please use more descriptive names for these.

Like PSTATE_FORCE_EQUAL and PSTATE_SKIP_EQUAL or similar.

Or what's wrong with using bool for that, actually?

> +
>  #define BYT_RATIOS		0x66a
>  #define BYT_VIDS		0x66b
>  #define BYT_TURBO_RATIOS	0x66c
> @@ -704,19 +707,21 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
>  	*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
>  }
>  
> -static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
> +static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate, int forced)

I'd call the last arg "mode" ->

>  {
>  	int max_perf, min_perf;
>  
> -	update_turbo_state();
> +	if (forced != FORCED)

-> and then you have 

	if (mode != PSTATE_FORCE_EQUAL) {

> +	{

Move the brace to the if () line.

> +		update_turbo_state();
>  
> -	intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
> +		intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
>  
> -	pstate = clamp_t(int, pstate, min_perf, max_perf);
> -
> -	if (pstate == cpu->pstate.current_pstate)
> -		return;
> +		pstate = clamp_t(int, pstate, min_perf, max_perf);
>  
> +		if (pstate == cpu->pstate.current_pstate)
> +			return;
> +	}
>  	trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
>  
>  	cpu->pstate.current_pstate = pstate;
> @@ -733,7 +738,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
>  
>  	if (pstate_funcs.get_vid)
>  		pstate_funcs.get_vid(cpu);
> -	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
> +	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, (int) FORCED);

Decimal literals are int by default.

>  }
>  
>  static inline void intel_pstate_calc_busy(struct cpudata *cpu)
> @@ -844,7 +849,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
>  	ctl = pid_calc(pid, busy_scaled);
>  
>  	/* Negative values of ctl increase the pstate and vice versa */
> -	intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl);
> +	intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl, (int) UNFORCED);
>  }
>  
>  static void intel_hwp_timer_func(unsigned long __data)
> @@ -1007,7 +1012,7 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
>  	if (hwp_active)
>  		return;
>  
> -	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
> +	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, (int) FORCED);
>  }
>  
>  static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
>
diff mbox

Patch

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6414661..77b6edf 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -33,6 +33,9 @@ 
 #include <asm/cpu_device_id.h>
 #include <asm/cpufeature.h>
 
+#define	FORCED		0
+#define UNFORCED	1
+
 #define BYT_RATIOS		0x66a
 #define BYT_VIDS		0x66b
 #define BYT_TURBO_RATIOS	0x66c
@@ -704,19 +707,21 @@  static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
 	*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
 }
 
-static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate, int forced)
 {
 	int max_perf, min_perf;
 
-	update_turbo_state();
+	if (forced != FORCED)
+	{
+		update_turbo_state();
 
-	intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
+		intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
 
-	pstate = clamp_t(int, pstate, min_perf, max_perf);
-
-	if (pstate == cpu->pstate.current_pstate)
-		return;
+		pstate = clamp_t(int, pstate, min_perf, max_perf);
 
+		if (pstate == cpu->pstate.current_pstate)
+			return;
+	}
 	trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
 
 	cpu->pstate.current_pstate = pstate;
@@ -733,7 +738,7 @@  static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 
 	if (pstate_funcs.get_vid)
 		pstate_funcs.get_vid(cpu);
-	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
+	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, (int) FORCED);
 }
 
 static inline void intel_pstate_calc_busy(struct cpudata *cpu)
@@ -844,7 +849,7 @@  static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 	ctl = pid_calc(pid, busy_scaled);
 
 	/* Negative values of ctl increase the pstate and vice versa */
-	intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl);
+	intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl, (int) UNFORCED);
 }
 
 static void intel_hwp_timer_func(unsigned long __data)
@@ -1007,7 +1012,7 @@  static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
 	if (hwp_active)
 		return;
 
-	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
+	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, (int) FORCED);
 }
 
 static int intel_pstate_cpu_init(struct cpufreq_policy *policy)