Message ID | 20220909164534.71864-1-Perry.Yuan@amd.com |
---|---|
Headers | show |
Series | Implement AMD Pstate EPP Driver | expand |
On 9/9/22 11:45, Perry Yuan wrote: > The patch adds online and offline driver callback to support to allow cpu cores go > offline and help to restore the previous working states when core goes > back online later for EPP driver mode. > > Signed-off-by: Perry Yuan <Perry.Yuan@amd.com> > --- > drivers/cpufreq/amd-pstate.c | 93 +++++++++++++++++++++++++++++++++++- > 1 file changed, 92 insertions(+), 1 deletion(-) > > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index e71b06e20050..e63fed39f90c 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -111,7 +111,8 @@ struct amd_aperf_mperf { > * @cppc_cap1_cached: Cached value of the last CPPC Capabilities MSR > * @update_util: Cpufreq utility callback information > * @sample: the stored performance sample > - > + * @suspended: Whether or not the driver has been suspended. > + * > * The amd_cpudata is key private data for each CPU thread in AMD P-State, and > * represents all the attributes and goals that AMD P-State requests at runtime. > */ > @@ -151,6 +152,7 @@ struct amd_cpudata { > u64 cppc_cap1_cached; > struct update_util_data update_util; > struct amd_aperf_mperf sample; > + bool suspended; > }; > > /** > @@ -1387,6 +1389,93 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) > return 0; > } > > +static void amd_pstate_epp_reenable(struct amd_cpudata * cpudata) > +{ > + struct cppc_perf_ctrls perf_ctrls; > + u64 value, max_perf; > + int ret; > + > + ret = amd_pstate_enable(true); > + if (ret) > + pr_err("failed to enable amd pstate during resume, return %d\n", ret); > + > + value = READ_ONCE(cpudata->cppc_req_cached); > + max_perf = READ_ONCE(cpudata->highest_perf); > + > + if (boot_cpu_has(X86_FEATURE_CPPC)) { > + wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); > + } else { > + perf_ctrls.max_perf = max_perf; > + perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached); > + cppc_set_perf(cpudata->cpu, &perf_ctrls); > + } > +} > + > +static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy) > +{ > + struct amd_cpudata *cpudata = all_cpu_data[policy->cpu]; > + > + pr_debug("AMD CPU Core %d going online\n", cpudata->cpu); > + > + if (epp_enabled) { > + amd_pstate_epp_reenable(cpudata); > + cpudata->suspended = false; You've added the suspended flag to indicate when a cpu is online/offline but I don't see any place in the offline code where you set suspended to true. > + } > + > + return 0; > +} > + > +static void amd_pstate_epp_offline(struct cpufreq_policy *policy) > +{ > + struct amd_cpudata *cpudata = all_cpu_data[policy->cpu]; > + struct cppc_perf_ctrls perf_ctrls; > + int min_perf; > + u64 value; > + > + min_perf = READ_ONCE(cpudata->lowest_perf); > + value = READ_ONCE(cpudata->cppc_req_cached); > + > + mutex_lock(&amd_pstate_limits_lock); > + if (boot_cpu_has(X86_FEATURE_CPPC)) { > + cpudata->epp_policy = CPUFREQ_POLICY_UNKNOWN; > + > + /* Set max perf same as min perf */ > + value &= ~AMD_CPPC_MAX_PERF(~0L); > + value |= AMD_CPPC_MAX_PERF(min_perf); > + value &= ~AMD_CPPC_MIN_PERF(~0L); > + value |= AMD_CPPC_MIN_PERF(min_perf); > + wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); Some odd indentation here, looks like you may have a mix of tabs and spaces. Did you run checkpatch? -Nathan > + } else { > + perf_ctrls.desired_perf = 0; > + perf_ctrls.max_perf = min_perf; > + perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(AMD_CPPC_EPP_POWERSAVE); > + cppc_set_perf(cpudata->cpu, &perf_ctrls); > + } > + mutex_unlock(&amd_pstate_limits_lock); > +} > + > +static int amd_pstate_cpu_offline(struct cpufreq_policy *policy) > +{ > + struct amd_cpudata *cpudata = all_cpu_data[policy->cpu]; > + > + pr_debug("AMD CPU Core %d going offline\n", cpudata->cpu); > + > + if (cpudata->suspended) > + return 0; > + > + if (epp_enabled) > + amd_pstate_epp_offline(policy); > + > + return 0; > +} > + > +static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) > +{ > + amd_pstate_clear_update_util_hook(policy->cpu); > + > + return amd_pstate_cpu_offline(policy); > +} > + > static void amd_pstate_verify_cpu_policy(struct amd_cpudata *cpudata, > struct cpufreq_policy_data *policy) > { > @@ -1421,6 +1510,8 @@ static struct cpufreq_driver amd_pstate_epp_driver = { > .init = amd_pstate_epp_cpu_init, > .exit = amd_pstate_epp_cpu_exit, > .update_limits = amd_pstate_epp_update_limits, > + .offline = amd_pstate_epp_cpu_offline, > + .online = amd_pstate_epp_cpu_online, > .name = "amd_pstate_epp", > .attr = amd_pstate_epp_attr, > };