Message ID | 20250206215659.3350066-9-superm1@kernel.org (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Mario Limonciello |
Headers | show |
Series | amd-pstate cleanups | expand |
On 2/7/2025 3:26 AM, Mario Limonciello wrote: > From: Mario Limonciello <mario.limonciello@amd.com> > > In order to prevent a potential write for shmem_update_perf() > cache the request into the cppc_req_cached variable normally only > used for the MSR case. Looks good to me, Reviewed-by: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com> Thanks, Dhananjay > > This adds symmetry into the code and potentially avoids extra writes. > > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > --- > drivers/cpufreq/amd-pstate.c | 22 +++++++++++++++++++++- > 1 file changed, 21 insertions(+), 1 deletion(-) > > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index cd96443fc117f..2aa3d5be2efe5 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -502,6 +502,8 @@ static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf, > u8 des_perf, u8 max_perf, u8 epp, bool fast_switch) > { > struct cppc_perf_ctrls perf_ctrls; > + u64 value, prev; > + int ret; > > if (cppc_state == AMD_PSTATE_ACTIVE) { > int ret = shmem_set_epp(cpudata, epp); > @@ -510,11 +512,29 @@ static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf, > return ret; > } > > + value = prev = READ_ONCE(cpudata->cppc_req_cached); > + > + value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK | > + AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK); > + value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf); > + value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf); > + value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf); > + value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp); > + > + if (value == prev) > + return 0; > + > perf_ctrls.max_perf = max_perf; > perf_ctrls.min_perf = min_perf; > perf_ctrls.desired_perf = des_perf; > > - return cppc_set_perf(cpudata->cpu, &perf_ctrls); > + ret = cppc_set_perf(cpudata->cpu, &perf_ctrls); > + if (ret) > + return ret; > + > + WRITE_ONCE(cpudata->cppc_req_cached, value); > + > + return 0; > } > > static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index cd96443fc117f..2aa3d5be2efe5 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -502,6 +502,8 @@ static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf, u8 des_perf, u8 max_perf, u8 epp, bool fast_switch) { struct cppc_perf_ctrls perf_ctrls; + u64 value, prev; + int ret; if (cppc_state == AMD_PSTATE_ACTIVE) { int ret = shmem_set_epp(cpudata, epp); @@ -510,11 +512,29 @@ static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf, return ret; } + value = prev = READ_ONCE(cpudata->cppc_req_cached); + + value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK | + AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK); + value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf); + value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf); + value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf); + value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp); + + if (value == prev) + return 0; + perf_ctrls.max_perf = max_perf; perf_ctrls.min_perf = min_perf; perf_ctrls.desired_perf = des_perf; - return cppc_set_perf(cpudata->cpu, &perf_ctrls); + ret = cppc_set_perf(cpudata->cpu, &perf_ctrls); + if (ret) + return ret; + + WRITE_ONCE(cpudata->cppc_req_cached, value); + + return 0; } static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)