From acf3f432287638044e472501a1d5969abee15043 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 5 Dec 2024 16:28:45 -0600 Subject: cpufreq/amd-pstate: Check if CPPC request has changed before writing to the MSR or shared memory Move the common MSR field formatting code to msr_update_perf() from its callers. Ensure that the MSR write is necessary before flushing a write out. Also drop the comparison from the passive flow tracing. Signed-off-by: Mario Limonciello --- drivers/cpufreq/amd-pstate-trace.h | 7 +---- drivers/cpufreq/amd-pstate.c | 47 +++++++++++------------------- 2 files changed, 18 insertions(+), 36 deletions(-) --- a/drivers/cpufreq/amd-pstate-trace.h +++ b/drivers/cpufreq/amd-pstate-trace.h @@ -32,7 +32,6 @@ TRACE_EVENT(amd_pstate_perf, u64 aperf, u64 tsc, unsigned int cpu_id, - bool changed, bool fast_switch ), @@ -44,7 +43,6 @@ TRACE_EVENT(amd_pstate_perf, aperf, tsc, cpu_id, - changed, fast_switch ), @@ -57,7 +55,6 @@ TRACE_EVENT(amd_pstate_perf, __field(unsigned long long, aperf) __field(unsigned long long, tsc) __field(unsigned int, cpu_id) - __field(bool, changed) __field(bool, fast_switch) ), @@ -70,11 +67,10 @@ TRACE_EVENT(amd_pstate_perf, __entry->aperf = aperf; __entry->tsc = tsc; __entry->cpu_id = cpu_id; - __entry->changed = changed; __entry->fast_switch = fast_switch; ), - TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s", + TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u fast_switch=%s", (unsigned long)__entry->min_perf, (unsigned long)__entry->target_perf, (unsigned long)__entry->capacity, @@ -83,7 +79,6 @@ TRACE_EVENT(amd_pstate_perf, (unsigned long long)__entry->aperf, (unsigned long long)__entry->tsc, (unsigned int)__entry->cpu_id, - (__entry->changed) ? "true" : "false", (__entry->fast_switch) ? "true" : "false" ) ); --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -254,15 +254,26 @@ static s16 shmem_get_epp(struct amd_cpud static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf, u32 des_perf, u32 max_perf, u32 epp, bool fast_switch) { - u64 value; + u64 value, prev; + + value = prev = READ_ONCE(cpudata->cppc_req_cached); + + value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK | + AMD_PSTATE_DES_PERF_MASK | AMD_PSTATE_EPP_PERF_MASK); + value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf); + value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, des_perf); + value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf); + value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, epp); + + if (value == prev) + return 0; - value = READ_ONCE(cpudata->cppc_req_cached); if (fast_switch) { - wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached)); + wrmsrl(MSR_AMD_CPPC_REQ, value); return 0; } else { - int ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, - READ_ONCE(cpudata->cppc_req_cached)); + int ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); + if (ret) return ret; } @@ -558,9 +569,7 @@ static void amd_pstate_update(struct amd { unsigned long max_freq; struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu); - u64 prev = READ_ONCE(cpudata->cppc_req_cached); u32 nominal_perf = READ_ONCE(cpudata->nominal_perf); - u64 value = prev; des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); @@ -576,27 +585,14 @@ static void amd_pstate_update(struct amd if (!cpudata->boost_supported) max_perf = min_t(unsigned long, nominal_perf, max_perf); - value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK | - AMD_PSTATE_DES_PERF_MASK); - value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf); - value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, des_perf); - value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf); - if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) { trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq, cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc, - cpudata->cpu, (value != prev), fast_switch); + cpudata->cpu, fast_switch); } - if (value == prev) - goto cpufreq_policy_put; - - WRITE_ONCE(cpudata->cppc_req_cached, value); - amd_pstate_update_perf(cpudata, min_perf, des_perf, max_perf, 0, fast_switch); -cpufreq_policy_put: - cpufreq_cpu_put(policy); } @@ -1592,19 +1588,10 @@ static void amd_pstate_epp_cpu_exit(stru static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; - u64 value; u32 epp; amd_pstate_update_min_max_limit(policy); - value = READ_ONCE(cpudata->cppc_req_cached); - - value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK | - AMD_PSTATE_DES_PERF_MASK | AMD_PSTATE_EPP_PERF_MASK); - value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, cpudata->max_limit_perf); - value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, 0); - value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, cpudata->min_limit_perf); - if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) epp = 0; else