diff mbox series

cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled cases.

Message ID 20200901030250.495928-1-currojerez@riseup.net (mailing list archive)
State Mainlined, archived
Headers show
Series cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled cases. | expand

Commit Message

Francisco Jerez Sept. 1, 2020, 3:02 a.m. UTC
This fixes the behavior of the scaling_max_freq and scaling_min_freq
sysfs files in systems which had turbo disabled by the BIOS.

Caleb noticed that the HWP is programmed to operate in the wrong
P-state range on his system when the CPUFREQ policy min/max frequency
is set via sysfs.  This seems to be because in his system
intel_pstate_get_hwp_max() is returning the maximum turbo P-state even
though turbo was disabled by the BIOS, which causes intel_pstate to
scale kHz frequencies incorrectly e.g. setting the maximum turbo
frequency whenever the maximum guaranteed frequency is requested via
sysfs.

Tested-by: Caleb Callaway <caleb.callaway@intel.com>
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
---
 drivers/cpufreq/intel_pstate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Srinivas Pandruvada Sept. 1, 2020, 3:48 p.m. UTC | #1
On Mon, 2020-08-31 at 20:02 -0700, Francisco Jerez wrote:
> This fixes the behavior of the scaling_max_freq and scaling_min_freq
> sysfs files in systems which had turbo disabled by the BIOS.
> 
> Caleb noticed that the HWP is programmed to operate in the wrong
> P-state range on his system when the CPUFREQ policy min/max frequency
> is set via sysfs.  This seems to be because in his system
> intel_pstate_get_hwp_max() is returning the maximum turbo P-state
> even
> though turbo was disabled by the BIOS, which causes intel_pstate to
> scale kHz frequencies incorrectly e.g. setting the maximum turbo
> frequency whenever the maximum guaranteed frequency is requested via
> sysfs.

When  turbo is disabled via MSR_IA32_MISC_ENABLE_TURBO_DISABLE (From
BIOS), then no matter what we write to HWP. max, the hardware will clip
to HWP_GUARANTEED_PERF.

But it looks like this is some issue on properly disabling turbo from
BIOS, since you observe turbo frequencies (via aperf, mperf) not just
sysfs display issue.



> 
> Tested-by: Caleb Callaway <caleb.callaway@intel.com>
> Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

> ---
>  drivers/cpufreq/intel_pstate.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/intel_pstate.c
> b/drivers/cpufreq/intel_pstate.c
> index e0220a6fbc69..7eb7b62bd5c4 100644
> --- a/drivers/cpufreq/intel_pstate.c
> +++ b/drivers/cpufreq/intel_pstate.c
> @@ -825,7 +825,7 @@ static void intel_pstate_get_hwp_max(unsigned int
> cpu, int *phy_max,
>  
>  	rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
>  	WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap);
> -	if (global.no_turbo)
> +	if (global.no_turbo || global.turbo_disabled)
>  		*current_max = HWP_GUARANTEED_PERF(cap);
>  	else
>  		*current_max = HWP_HIGHEST_PERF(cap);
Rafael J. Wysocki Sept. 1, 2020, 5:59 p.m. UTC | #2
On Tue, Sep 1, 2020 at 5:48 PM Srinivas Pandruvada
<srinivas.pandruvada@linux.intel.com> wrote:
>
> On Mon, 2020-08-31 at 20:02 -0700, Francisco Jerez wrote:
> > This fixes the behavior of the scaling_max_freq and scaling_min_freq
> > sysfs files in systems which had turbo disabled by the BIOS.
> >
> > Caleb noticed that the HWP is programmed to operate in the wrong
> > P-state range on his system when the CPUFREQ policy min/max frequency
> > is set via sysfs.  This seems to be because in his system
> > intel_pstate_get_hwp_max() is returning the maximum turbo P-state
> > even
> > though turbo was disabled by the BIOS, which causes intel_pstate to
> > scale kHz frequencies incorrectly e.g. setting the maximum turbo
> > frequency whenever the maximum guaranteed frequency is requested via
> > sysfs.
>
> When  turbo is disabled via MSR_IA32_MISC_ENABLE_TURBO_DISABLE (From
> BIOS), then no matter what we write to HWP. max, the hardware will clip
> to HWP_GUARANTEED_PERF.
>
> But it looks like this is some issue on properly disabling turbo from
> BIOS, since you observe turbo frequencies (via aperf, mperf) not just
> sysfs display issue.
>
>
>
> >
> > Tested-by: Caleb Callaway <caleb.callaway@intel.com>
> > Signed-off-by: Francisco Jerez <currojerez@riseup.net>
> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

Applied as 5.9-rc material with minor edits in the subject.

Thanks!

> > ---
> >  drivers/cpufreq/intel_pstate.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/cpufreq/intel_pstate.c
> > b/drivers/cpufreq/intel_pstate.c
> > index e0220a6fbc69..7eb7b62bd5c4 100644
> > --- a/drivers/cpufreq/intel_pstate.c
> > +++ b/drivers/cpufreq/intel_pstate.c
> > @@ -825,7 +825,7 @@ static void intel_pstate_get_hwp_max(unsigned int
> > cpu, int *phy_max,
> >
> >       rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
> >       WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap);
> > -     if (global.no_turbo)
> > +     if (global.no_turbo || global.turbo_disabled)
> >               *current_max = HWP_GUARANTEED_PERF(cap);
> >       else
> >               *current_max = HWP_HIGHEST_PERF(cap);
>
Francisco Jerez Sept. 1, 2020, 6:19 p.m. UTC | #3
Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> writes:

> On Mon, 2020-08-31 at 20:02 -0700, Francisco Jerez wrote:
>> This fixes the behavior of the scaling_max_freq and scaling_min_freq
>> sysfs files in systems which had turbo disabled by the BIOS.
>> 
>> Caleb noticed that the HWP is programmed to operate in the wrong
>> P-state range on his system when the CPUFREQ policy min/max frequency
>> is set via sysfs.  This seems to be because in his system
>> intel_pstate_get_hwp_max() is returning the maximum turbo P-state
>> even
>> though turbo was disabled by the BIOS, which causes intel_pstate to
>> scale kHz frequencies incorrectly e.g. setting the maximum turbo
>> frequency whenever the maximum guaranteed frequency is requested via
>> sysfs.
>
> When  turbo is disabled via MSR_IA32_MISC_ENABLE_TURBO_DISABLE (From
> BIOS), then no matter what we write to HWP. max, the hardware will clip
> to HWP_GUARANTEED_PERF.
>
> But it looks like this is some issue on properly disabling turbo from
> BIOS, since you observe turbo frequencies (via aperf, mperf) not just
> sysfs display issue.
>

Caleb should be able to confirm that, but my understanding is that his
system was still clocking up to the max turbo frequency despite turbo
being disabled in the BIOS and the maximum guaranteed frequency having
been specified in scaling_max_freq.

However there is a bug even in systems where the clipping you describe
is working correctly, the conversion from kHz frequency to P-state uses
a bogus scaling factor without this patch applied.

>
>
>> 
>> Tested-by: Caleb Callaway <caleb.callaway@intel.com>
>> Signed-off-by: Francisco Jerez <currojerez@riseup.net>
> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
>

Thanks!

>> ---
>>  drivers/cpufreq/intel_pstate.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/cpufreq/intel_pstate.c
>> b/drivers/cpufreq/intel_pstate.c
>> index e0220a6fbc69..7eb7b62bd5c4 100644
>> --- a/drivers/cpufreq/intel_pstate.c
>> +++ b/drivers/cpufreq/intel_pstate.c
>> @@ -825,7 +825,7 @@ static void intel_pstate_get_hwp_max(unsigned int
>> cpu, int *phy_max,
>>  
>>  	rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
>>  	WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap);
>> -	if (global.no_turbo)
>> +	if (global.no_turbo || global.turbo_disabled)
>>  		*current_max = HWP_GUARANTEED_PERF(cap);
>>  	else
>>  		*current_max = HWP_HIGHEST_PERF(cap);
Callaway, Caleb Sept. 1, 2020, 6:56 p.m. UTC | #4
Hi folks,

Thanks for working on this! It's possible my system is still clocking up to max turbo, but I didn't explicitly test this. My goal was to fix the CPU frequency at 2.8 GHz on a CFL-S platform using the following script:

	_cpufreq=<frequency in Khz>
	cpu_sysfs="/sys/devices/system/cpu/cpufreq"
	for cpu in $cpu_sysfs/*; do
		echo "Setting frequency for $cpu..."
		echo "performance" > $cpu/scaling_governor
		echo $_cpufreq > $cpu/scaling_max_freq
		echo $_cpufreq > $cpu/scaling_min_freq
	done

To get the desired fixed frequency, I had to set _cpufreq==2100000 when Turbo was disabled in the BIOS; with Turbo enabled, I had to use the value 2800000. I observed the result with:

	watch "cat /proc/cpuinfo | grep 'cpu MHz'"

With Francisco's patch, I could use the value 2800000 for both Turbo enabled and Turbo disabled.

I'm not well-acquainted with the moving parts here, but if there's an additional supporting experiment I can run, just let me know.

HTH,
-Caleb

-----Original Message-----
From: Francisco Jerez <currojerez@riseup.net> 
Sent: Tuesday, September 1, 2020 11:19 AM
To: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>; linux-pm@vger.kernel.org
Cc: Wysocki, Rafael J <rafael.j.wysocki@intel.com>; Callaway, Caleb <caleb.callaway@intel.com>
Subject: Re: [PATCH] cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled cases.

Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> writes:

> On Mon, 2020-08-31 at 20:02 -0700, Francisco Jerez wrote:
>> This fixes the behavior of the scaling_max_freq and scaling_min_freq 
>> sysfs files in systems which had turbo disabled by the BIOS.
>> 
>> Caleb noticed that the HWP is programmed to operate in the wrong 
>> P-state range on his system when the CPUFREQ policy min/max frequency 
>> is set via sysfs.  This seems to be because in his system
>> intel_pstate_get_hwp_max() is returning the maximum turbo P-state 
>> even though turbo was disabled by the BIOS, which causes intel_pstate 
>> to scale kHz frequencies incorrectly e.g. setting the maximum turbo 
>> frequency whenever the maximum guaranteed frequency is requested via 
>> sysfs.
>
> When  turbo is disabled via MSR_IA32_MISC_ENABLE_TURBO_DISABLE (From 
> BIOS), then no matter what we write to HWP. max, the hardware will 
> clip to HWP_GUARANTEED_PERF.
>
> But it looks like this is some issue on properly disabling turbo from 
> BIOS, since you observe turbo frequencies (via aperf, mperf) not just 
> sysfs display issue.
>

Caleb should be able to confirm that, but my understanding is that his system was still clocking up to the max turbo frequency despite turbo being disabled in the BIOS and the maximum guaranteed frequency having been specified in scaling_max_freq.

However there is a bug even in systems where the clipping you describe is working correctly, the conversion from kHz frequency to P-state uses a bogus scaling factor without this patch applied.

>
>
>> 
>> Tested-by: Caleb Callaway <caleb.callaway@intel.com>
>> Signed-off-by: Francisco Jerez <currojerez@riseup.net>
> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
>

Thanks!

>> ---
>>  drivers/cpufreq/intel_pstate.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/cpufreq/intel_pstate.c 
>> b/drivers/cpufreq/intel_pstate.c index e0220a6fbc69..7eb7b62bd5c4 
>> 100644
>> --- a/drivers/cpufreq/intel_pstate.c
>> +++ b/drivers/cpufreq/intel_pstate.c
>> @@ -825,7 +825,7 @@ static void intel_pstate_get_hwp_max(unsigned int 
>> cpu, int *phy_max,
>>  
>>  	rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
>>  	WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap);
>> -	if (global.no_turbo)
>> +	if (global.no_turbo || global.turbo_disabled)
>>  		*current_max = HWP_GUARANTEED_PERF(cap);
>>  	else
>>  		*current_max = HWP_HIGHEST_PERF(cap);
Srinivas Pandruvada Sept. 1, 2020, 7:30 p.m. UTC | #5
On Tue, 2020-09-01 at 18:56 +0000, Callaway, Caleb wrote:
> Hi folks,
> 
> Thanks for working on this! It's possible my system is still clocking
> up to max turbo, but I didn't explicitly test this.
This is unlikely that will clock to turbo. Better to test that.
But since the frequency limits can't be set correctly, the patch is
still valid.

Thanks,
Srinivas

>  My goal was to fix the CPU frequency at 2.8 GHz on a CFL-S platform
> using the following script:
> 
> 	_cpufreq=<frequency in Khz>
> 	cpu_sysfs="/sys/devices/system/cpu/cpufreq"
> 	for cpu in $cpu_sysfs/*; do
> 		echo "Setting frequency for $cpu..."
> 		echo "performance" > $cpu/scaling_governor
> 		echo $_cpufreq > $cpu/scaling_max_freq
> 		echo $_cpufreq > $cpu/scaling_min_freq
> 	done
> 
> To get the desired fixed frequency, I had to set _cpufreq==2100000
> when Turbo was disabled in the BIOS; with Turbo enabled, I had to use
> the value 2800000. I observed the result with:
> 
> 	watch "cat /proc/cpuinfo | grep 'cpu MHz'"
> 
> With Francisco's patch, I could use the value 2800000 for both Turbo
> enabled and Turbo disabled.
> 
> I'm not well-acquainted with the moving parts here, but if there's an
> additional supporting experiment I can run, just let me know.
> 
> HTH,
> -Caleb
> 
> -----Original Message-----
> From: Francisco Jerez <currojerez@riseup.net> 
> Sent: Tuesday, September 1, 2020 11:19 AM
> To: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>; 
> linux-pm@vger.kernel.org
> Cc: Wysocki, Rafael J <rafael.j.wysocki@intel.com>; Callaway, Caleb <
> caleb.callaway@intel.com>
> Subject: Re: [PATCH] cpufreq: intel_pstate: Fix
> intel_pstate_get_hwp_max() for turbo disabled cases.
> 
> Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> writes:
> 
> > On Mon, 2020-08-31 at 20:02 -0700, Francisco Jerez wrote:
> > > This fixes the behavior of the scaling_max_freq and
> > > scaling_min_freq 
> > > sysfs files in systems which had turbo disabled by the BIOS.
> > > 
> > > Caleb noticed that the HWP is programmed to operate in the wrong 
> > > P-state range on his system when the CPUFREQ policy min/max
> > > frequency 
> > > is set via sysfs.  This seems to be because in his system
> > > intel_pstate_get_hwp_max() is returning the maximum turbo P-
> > > state 
> > > even though turbo was disabled by the BIOS, which causes
> > > intel_pstate 
> > > to scale kHz frequencies incorrectly e.g. setting the maximum
> > > turbo 
> > > frequency whenever the maximum guaranteed frequency is requested
> > > via 
> > > sysfs.
> > 
> > When  turbo is disabled via MSR_IA32_MISC_ENABLE_TURBO_DISABLE
> > (From 
> > BIOS), then no matter what we write to HWP. max, the hardware will 
> > clip to HWP_GUARANTEED_PERF.
> > 
> > But it looks like this is some issue on properly disabling turbo
> > from 
> > BIOS, since you observe turbo frequencies (via aperf, mperf) not
> > just 
> > sysfs display issue.
> > 
> 
> Caleb should be able to confirm that, but my understanding is that
> his system was still clocking up to the max turbo frequency despite
> turbo being disabled in the BIOS and the maximum guaranteed frequency
> having been specified in scaling_max_freq.
> 
> However there is a bug even in systems where the clipping you
> describe is working correctly, the conversion from kHz frequency to
> P-state uses a bogus scaling factor without this patch applied.
> 
> > 
> > > Tested-by: Caleb Callaway <caleb.callaway@intel.com>
> > > Signed-off-by: Francisco Jerez <currojerez@riseup.net>
> > Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> > 
> 
> Thanks!
> 
> > > ---
> > >  drivers/cpufreq/intel_pstate.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/cpufreq/intel_pstate.c 
> > > b/drivers/cpufreq/intel_pstate.c index
> > > e0220a6fbc69..7eb7b62bd5c4 
> > > 100644
> > > --- a/drivers/cpufreq/intel_pstate.c
> > > +++ b/drivers/cpufreq/intel_pstate.c
> > > @@ -825,7 +825,7 @@ static void intel_pstate_get_hwp_max(unsigned
> > > int 
> > > cpu, int *phy_max,
> > >  
> > >  	rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
> > >  	WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap);
> > > -	if (global.no_turbo)
> > > +	if (global.no_turbo || global.turbo_disabled)
> > >  		*current_max = HWP_GUARANTEED_PERF(cap);
> > >  	else
> > >  		*current_max = HWP_HIGHEST_PERF(cap);
diff mbox series

Patch

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index e0220a6fbc69..7eb7b62bd5c4 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -825,7 +825,7 @@  static void intel_pstate_get_hwp_max(unsigned int cpu, int *phy_max,
 
 	rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
 	WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap);
-	if (global.no_turbo)
+	if (global.no_turbo || global.turbo_disabled)
 		*current_max = HWP_GUARANTEED_PERF(cap);
 	else
 		*current_max = HWP_HIGHEST_PERF(cap);