]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cpufreq/amd-pstate: Cache CPPC request in shared mem case too
authorMario Limonciello <mario.limonciello@amd.com>
Mon, 9 Dec 2024 17:54:32 +0000 (11:54 -0600)
committerMario Limonciello <mario.limonciello@amd.com>
Thu, 6 Mar 2025 19:01:25 +0000 (13:01 -0600)
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.

This adds symmetry into the code and potentially avoids extra writes.

Reviewed-by: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
drivers/cpufreq/amd-pstate.c

index 5c439b14caae385805ae1d844eb1cb2f1f965b23..06bf0d888be6b0da3949282753e31292dc66ccc8 100644 (file)
@@ -496,6 +496,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);
@@ -504,11 +506,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)