Re: [PATCH 0/2] intel_pstate: fix turbo not being used after a processor is rebooted

From: Rafael J. Wysocki
Date: Tue Dec 27 2022 - 12:14:16 EST


On Tuesday, December 27, 2022 6:02:50 PM CET Rafael J. Wysocki wrote:
> On Tue, Dec 27, 2022 at 5:40 PM srinivas pandruvada
> <srinivas.pandruvada@xxxxxxxxxxxxxxx> wrote:
> >
> > On Tue, 2022-12-27 at 16:38 +0100, Pratyush Yadav wrote:
> > > Hi Srinivas,
> > >
> > > On Sat, Dec 24 2022, srinivas pandruvada wrote:
> > >
> > > > On Fri, 2022-12-23 at 10:10 -0800, srinivas pandruvada wrote:
> > > > > Hi Pratyush,
> > > > >
> > > > > On Thu, 2022-12-22 at 11:39 +0100, Pratyush Yadav wrote:
> > > > > >
> > > > > > Hi Srinivas,
> > > > > >
> > > > > > On Wed, Dec 21 2022, srinivas pandruvada wrote:
> > > > > > > On Wed, 2022-12-21 at 16:52 +0100, Pratyush Yadav wrote:
> > > > > > > > When a processor is brought offline and online again, it is
> > > > > > > > unable to
> > > > > > > > use Turbo mode because the _PSS table does not contain the
> > > > > > > > whole
> > > > > > > > turbo
> > > > > > > > frequency range, but only +1 MHz above the max non-turbo
> > > > > > > > frequency.
> > > > > > > > This
> > > > > > > > causes problems when ACPI processor driver tries to set
> > > > > > > > frequency
> > > > > > > > constraints. See patch 2 for more details.
> > > > > > > >
> > > > > I can reproduce on a Broadwell server platform. But not on a
> > > > > client
> > > > > system with acpi_ppc usage.
> > > > >
> > > > > Need to check what change broke this.
> > > >
> > > > When PPC limits enforcement changed to PM QOS, this broke.
> > > > Previously
> > > > acpi_processor_get_platform_limit() was not enforcing any limits.
> > > > It
> > > > was just setting variable. So any update done after
> > > > acpi_register_performance_state() call to pr->performance-
> > > > > states[ppc].core_frequency, was effective.
> > > >
> > > > We don't really need to call
> > > > ret = freq_qos_update_request(&pr->perflib_req,
> > > > pr->performance->states[ppc].core_frequency
> > > > *
> > > > 1000);
> > > >
> > > > if the PPC is not changed. When PPC is changed, this gets called
> > > > again,
> > > > so then we can call the above function to update cpufreq limit.
> > > >
> > > > The below change fixed for me.
> > >
> > > Right.
> > I think, this is the only change you require to fix this. In addition
> > set pr->performance_platform_limit = 0 in
> > acpi_processor_unregister_performance().
>
> Not really, because if the limit is set to a lower frequency and then
> reset to _PSS[0], it needs to be set back to "no limit".
>
> I'll send a patch for that in a while.

This has not been tested beyond compilation, so please be careful.

---
drivers/acpi/processor_perflib.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/acpi/processor_perflib.c
===================================================================
--- linux-pm.orig/drivers/acpi/processor_perflib.c
+++ linux-pm/drivers/acpi/processor_perflib.c
@@ -53,6 +53,8 @@ static int acpi_processor_get_platform_l
{
acpi_status status = 0;
unsigned long long ppc = 0;
+ s32 qos_value;
+ int index;
int ret;

if (!pr)
@@ -72,17 +74,30 @@ static int acpi_processor_get_platform_l
}
}

+ index = ppc;
+
+ if (pr->performance_platform_limit == index ||
+ ppc >= pr->performance->state_count)
+ return 0;
+
pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
- (int)ppc, ppc ? "" : "not");
+ index, index ? "is" : "is not");

- pr->performance_platform_limit = (int)ppc;
+ pr->performance_platform_limit = index;

- if (ppc >= pr->performance->state_count ||
- unlikely(!freq_qos_request_active(&pr->perflib_req)))
+ if (unlikely(!freq_qos_request_active(&pr->perflib_req)))
return 0;

- ret = freq_qos_update_request(&pr->perflib_req,
- pr->performance->states[ppc].core_frequency * 1000);
+ /*
+ * If _PPC returns 0, it means that all of the available states can be
+ * used ("no limit").
+ */
+ if (index == 0)
+ qos_value = FREQ_QOS_MAX_DEFAULT_VALUE;
+ else
+ qos_value = pr->performance->states[index].core_frequency * 1000;
+
+ ret = freq_qos_update_request(&pr->perflib_req, qos_value);
if (ret < 0) {
pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n",
pr->id, ret);