Message ID | 20220814164421.330891-1-Perry.Yuan@amd.com |
---|---|
State | Superseded |
Headers | show |
Series | cpufreq: amd_pstate: Fix initial highest_perf value | expand |
On Sun, Aug 14, 2022 at 6:57 PM Perry Yuan <Perry.Yuan@amd.com> wrote: > > To avoid some new AMD processors use wrong highest perf when amd pstate > driver loaded, this fix will query the highest perf from MSR register > MSR_AMD_CPPC_CAP1 and cppc_acpi interface firstly, then compare with the > highest perf value got by calling amd_get_highest_perf() function. > > The lower value will be the correct highest perf we need to use. > Otherwise the CPU max MHz will be incorrect if the > amd_get_highest_perf() did not cover the new process family and model ID. > > Like this lscpu info, the max frequency is incorrect. > > Vendor ID: AuthenticAMD > Socket(s): 1 > Stepping: 2 > CPU max MHz: 5410.0000 > CPU min MHz: 400.0000 > BogoMIPS: 5600.54 > > Fixes: 3743d55b289c2 (x86, sched: Fix the AMD CPPC maximum performance value on certain AMD Ryzen generations) > Signed-off-by: Perry Yuan <Perry.Yuan@amd.com> This needs to be reviewed by the AMD P-state driver maintainer. > --- > drivers/cpufreq/amd-pstate.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index 9f4375f7ab46..f778ab37e436 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -354,6 +354,7 @@ static inline int amd_pstate_enable(bool enable) > static int pstate_init_perf(struct amd_cpudata *cpudata) > { > u64 cap1; > + u32 highest_perf; > > int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1, > &cap1); > @@ -365,7 +366,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) > * > * CPPC entry doesn't indicate the highest performance in some ASICs. > */ > - WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); > + highest_perf = amd_get_highest_perf(); > + if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) > + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); > + > + WRITE_ONCE(cpudata->highest_perf, highest_perf); > > WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); > WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); > @@ -377,12 +382,17 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) > static int cppc_init_perf(struct amd_cpudata *cpudata) > { > struct cppc_perf_caps cppc_perf; > + u32 highest_perf; > > int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); > if (ret) > return ret; > > - WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); > + highest_perf = amd_get_highest_perf(); > + if (highest_perf > cppc_perf.highest_perf) > + highest_perf = cppc_perf.nominal_perf; > + > + WRITE_ONCE(cpudata->highest_perf, highest_perf); > > WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); > WRITE_ONCE(cpudata->lowest_nonlinear_perf, > -- > 2.34.1 >
[AMD Official Use Only - General] Hi Rafael, > -----Original Message----- > From: Rafael J. Wysocki <rafael@kernel.org> > Sent: Thursday, August 25, 2022 7:59 PM > To: Yuan, Perry <Perry.Yuan@amd.com> > Cc: Rafael Wysocki <rafael.j.wysocki@intel.com>; Huang, Ray > <Ray.Huang@amd.com>; Viresh Kumar <viresh.kumar@linaro.org>; Sharma, > Deepak <Deepak.Sharma@amd.com>; Limonciello, Mario > <Mario.Limonciello@amd.com>; Fontenot, Nathan > <Nathan.Fontenot@amd.com>; Deucher, Alexander > <Alexander.Deucher@amd.com>; Su, Jinzhou (Joe) <Jinzhou.Su@amd.com>; > Huang, Shimmer <Shimmer.Huang@amd.com>; Du, Xiaojian > <Xiaojian.Du@amd.com>; Meng, Li (Jassmine) <Li.Meng@amd.com>; Linux > PM <linux-pm@vger.kernel.org>; Linux Kernel Mailing List <linux- > kernel@vger.kernel.org> > Subject: Re: [PATCH] cpufreq: amd_pstate: Fix initial highest_perf value > > [CAUTION: External Email] > > On Sun, Aug 14, 2022 at 6:57 PM Perry Yuan <Perry.Yuan@amd.com> wrote: > > > > To avoid some new AMD processors use wrong highest perf when amd > > pstate driver loaded, this fix will query the highest perf from MSR > > register > > MSR_AMD_CPPC_CAP1 and cppc_acpi interface firstly, then compare with > > the highest perf value got by calling amd_get_highest_perf() function. > > > > The lower value will be the correct highest perf we need to use. > > Otherwise the CPU max MHz will be incorrect if the > > amd_get_highest_perf() did not cover the new process family and model > ID. > > > > Like this lscpu info, the max frequency is incorrect. > > > > Vendor ID: AuthenticAMD > > Socket(s): 1 > > Stepping: 2 > > CPU max MHz: 5410.0000 > > CPU min MHz: 400.0000 > > BogoMIPS: 5600.54 > > > > Fixes: 3743d55b289c2 (x86, sched: Fix the AMD CPPC maximum > performance > > value on certain AMD Ryzen generations) > > Signed-off-by: Perry Yuan <Perry.Yuan@amd.com> > > This needs to be reviewed by the AMD P-state driver maintainer. There is one small change for this patch , will send V2 for further review. Perry. > > > --- > > drivers/cpufreq/amd-pstate.c | 14 ++++++++++++-- > > 1 file changed, 12 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/cpufreq/amd-pstate.c > > b/drivers/cpufreq/amd-pstate.c index 9f4375f7ab46..f778ab37e436 100644 > > --- a/drivers/cpufreq/amd-pstate.c > > +++ b/drivers/cpufreq/amd-pstate.c > > @@ -354,6 +354,7 @@ static inline int amd_pstate_enable(bool enable) > > static int pstate_init_perf(struct amd_cpudata *cpudata) { > > u64 cap1; > > + u32 highest_perf; > > > > int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1, > > &cap1); @@ -365,7 +366,11 @@ > > static int pstate_init_perf(struct amd_cpudata *cpudata) > > * > > * CPPC entry doesn't indicate the highest performance in some ASICs. > > */ > > - WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); > > + highest_perf = amd_get_highest_perf(); > > + if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) > > + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); > > + > > + WRITE_ONCE(cpudata->highest_perf, highest_perf); > > > > WRITE_ONCE(cpudata->nominal_perf, > AMD_CPPC_NOMINAL_PERF(cap1)); > > WRITE_ONCE(cpudata->lowest_nonlinear_perf, > > AMD_CPPC_LOWNONLIN_PERF(cap1)); @@ -377,12 +382,17 @@ static int > > pstate_init_perf(struct amd_cpudata *cpudata) static int > > cppc_init_perf(struct amd_cpudata *cpudata) { > > struct cppc_perf_caps cppc_perf; > > + u32 highest_perf; > > > > int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); > > if (ret) > > return ret; > > > > - WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); > > + highest_perf = amd_get_highest_perf(); > > + if (highest_perf > cppc_perf.highest_perf) > > + highest_perf = cppc_perf.nominal_perf; > > + > > + WRITE_ONCE(cpudata->highest_perf, highest_perf); > > > > WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); > > WRITE_ONCE(cpudata->lowest_nonlinear_perf, > > -- > > 2.34.1 > >
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 9f4375f7ab46..f778ab37e436 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -354,6 +354,7 @@ static inline int amd_pstate_enable(bool enable) static int pstate_init_perf(struct amd_cpudata *cpudata) { u64 cap1; + u32 highest_perf; int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1, &cap1); @@ -365,7 +366,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) * * CPPC entry doesn't indicate the highest performance in some ASICs. */ - WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); + highest_perf = amd_get_highest_perf(); + if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); + + WRITE_ONCE(cpudata->highest_perf, highest_perf); WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); @@ -377,12 +382,17 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) static int cppc_init_perf(struct amd_cpudata *cpudata) { struct cppc_perf_caps cppc_perf; + u32 highest_perf; int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); if (ret) return ret; - WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); + highest_perf = amd_get_highest_perf(); + if (highest_perf > cppc_perf.highest_perf) + highest_perf = cppc_perf.nominal_perf; + + WRITE_ONCE(cpudata->highest_perf, highest_perf); WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); WRITE_ONCE(cpudata->lowest_nonlinear_perf,
To avoid some new AMD processors use wrong highest perf when amd pstate driver loaded, this fix will query the highest perf from MSR register MSR_AMD_CPPC_CAP1 and cppc_acpi interface firstly, then compare with the highest perf value got by calling amd_get_highest_perf() function. The lower value will be the correct highest perf we need to use. Otherwise the CPU max MHz will be incorrect if the amd_get_highest_perf() did not cover the new process family and model ID. Like this lscpu info, the max frequency is incorrect. Vendor ID: AuthenticAMD Socket(s): 1 Stepping: 2 CPU max MHz: 5410.0000 CPU min MHz: 400.0000 BogoMIPS: 5600.54 Fixes: 3743d55b289c2 (x86, sched: Fix the AMD CPPC maximum performance value on certain AMD Ryzen generations) Signed-off-by: Perry Yuan <Perry.Yuan@amd.com> --- drivers/cpufreq/amd-pstate.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)