Messages in this thread | | | From | Oleksandr Natalenko <> | Subject | Re: [PATCH v10 3/7] cpufreq: amd-pstate: implement cpb_boost sysfs entry for boost control | Date | Wed, 08 May 2024 11:39:15 +0200 |
| |
Hello.
On středa 8. května 2024 9:21:08, SELČ Perry Yuan wrote: > From: Perry Yuan <Perry.Yuan@amd.com> > > With this new sysfs entry `cpb_boost`created, user can change CPU boost > state dynamically under `active`, `guided` and `passive` modes. > And the highest perf and frequency will also be updated as the boost > state changing. > > 0): check current boost state > cat /sys/devices/system/cpu/amd_pstate/cpb_boost > > 1): disable CPU boost > sudo bash -c "echo 0 > /sys/devices/system/cpu/amd_pstate/cpb_boost" > > 2): enable CPU boost > sudo bash -c "echo 1 > /sys/devices/system/cpu/amd_pstate/cpb_boost" > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=217931 > Link: https://bugzilla.kernel.org/show_bug.cgi?id=217618 > Signed-off-by: Perry Yuan <Perry.Yuan@amd.com> > --- > drivers/cpufreq/amd-pstate-ut.c | 2 +- > drivers/cpufreq/amd-pstate.c | 114 +++++++++++++++++++++++++++++++- > include/linux/amd-pstate.h | 1 + > 3 files changed, 115 insertions(+), 2 deletions(-) > > diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c > index f04ae67dda37..b3601b0e6dd3 100644 > --- a/drivers/cpufreq/amd-pstate-ut.c > +++ b/drivers/cpufreq/amd-pstate-ut.c > @@ -226,7 +226,7 @@ static void amd_pstate_ut_check_freq(u32 index) > goto skip_test; > } > > - if (cpudata->boost_supported) { > + if (amd_pstate_global_params.cpb_boost) { > if ((policy->max == cpudata->max_freq) || > (policy->max == cpudata->nominal_freq)) > amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index f7dab0f7b452..f81fd61dd2a9 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -686,8 +686,10 @@ static int amd_pstate_boost_init(struct amd_cpudata *cpudata) > } > > amd_pstate_global_params.cpb_supported = !(boost_val & MSR_K7_HWCR_CPB_DIS); > - if (amd_pstate_global_params.cpb_supported) > + if (amd_pstate_global_params.cpb_supported) { > current_pstate_driver->boost_enabled = true; > + cpudata->boost_state = true; > + } > > amd_pstate_global_params.cpb_boost = amd_pstate_global_params.cpb_supported; > > @@ -1293,6 +1295,114 @@ static ssize_t prefcore_show(struct device *dev, > return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore)); > } > > +static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on) > +{ > + struct amd_cpudata *cpudata = policy->driver_data; > + struct cppc_perf_ctrls perf_ctrls; > + u32 highest_perf, nominal_perf, nominal_freq, max_freq; > + int ret; > + > + if (!policy) { > + pr_err("policy is null\n"); > + return -ENODATA; > + } > + > + highest_perf = READ_ONCE(cpudata->highest_perf); > + nominal_perf = READ_ONCE(cpudata->nominal_perf); > + nominal_freq = READ_ONCE(cpudata->nominal_freq); > + max_freq = READ_ONCE(cpudata->max_freq); > + > + if (boot_cpu_has(X86_FEATURE_CPPC)) { > + u64 value = READ_ONCE(cpudata->cppc_req_cached); > + > + value &= ~GENMASK_ULL(7, 0); > + value |= on ? highest_perf : nominal_perf; > + WRITE_ONCE(cpudata->cppc_req_cached, value); > + > + wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); > + } else { > + perf_ctrls.max_perf = on ? highest_perf : nominal_perf; > + ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1); > + if (ret) { > + cpufreq_cpu_release(policy); > + pr_debug("failed to set energy perf value (%d)\n", ret); > + return ret; > + } > + } > + > + if (on) > + policy->cpuinfo.max_freq = max_freq; > + else > + policy->cpuinfo.max_freq = nominal_freq * 1000; > + > + policy->max = policy->cpuinfo.max_freq; > + > + if (cppc_state == AMD_PSTATE_PASSIVE) { > + ret = freq_qos_update_request(&cpudata->req[1], > + policy->cpuinfo.max_freq); > + } > + > + return ret; > +} > + > +static int amd_pstate_cpu_boost(int cpu, bool state) > +{ > + int ret; > + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); > + struct amd_cpudata *cpudata = policy->driver_data; > + > + if (!policy) { > + pr_err("policy is NULL\n"); > + ret = -ENODATA; > + goto err_exit; > + } > + > + ret = amd_pstate_cpu_boost_update(policy, state); > + refresh_frequency_limits(policy); > + cpudata->boost_state = !!state; > + > +err_exit: > + cpufreq_cpu_put(policy); > + return ret < 0 ? ret : 0; > +} > + > +static ssize_t cpb_boost_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + return sysfs_emit(buf, "%u\n", amd_pstate_global_params.cpb_boost); > +} > + > +static ssize_t cpb_boost_store(struct device *dev, struct device_attribute *b, > + const char *buf, size_t count) > +{ > + bool new_state; > + ssize_t ret; > + int cpu; > + > + if (!amd_pstate_global_params.cpb_supported) { > + pr_err("Boost mode is not supported by this processor or SBIOS\n"); > + return -EINVAL; > + } > + > + ret = kstrtobool(buf, &new_state); > + if (ret) > + return ret; > + > + mutex_lock(&amd_pstate_driver_lock); > + for_each_present_cpu(cpu) { > + ret = amd_pstate_cpu_boost(cpu, new_state); > + if (ret < 0) { > + pr_warn("failed to update cpu boost for CPU%d (%d)\n", cpu, ret);
Note ret is ssize_t, so %d should be %ld (or %z/%zd/%zi?) instead.
> + goto err_exit; > + } > + } > + amd_pstate_global_params.cpb_boost = !!new_state; > + > +err_exit: > + mutex_unlock(&amd_pstate_driver_lock); > + return ret < 0 ? ret : count; > +} > + > cpufreq_freq_attr_ro(amd_pstate_max_freq); > cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); > > @@ -1303,6 +1413,7 @@ cpufreq_freq_attr_rw(energy_performance_preference); > cpufreq_freq_attr_ro(energy_performance_available_preferences); > static DEVICE_ATTR_RW(status); > static DEVICE_ATTR_RO(prefcore); > +static DEVICE_ATTR_RW(cpb_boost); > > static struct freq_attr *amd_pstate_attr[] = { > &amd_pstate_max_freq, > @@ -1327,6 +1438,7 @@ static struct freq_attr *amd_pstate_epp_attr[] = { > static struct attribute *pstate_global_attributes[] = { > &dev_attr_status.attr, > &dev_attr_prefcore.attr, > + &dev_attr_cpb_boost.attr, > NULL > }; > > diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h > index 8ba5dd4d3405..56f616a5cd0f 100644 > --- a/include/linux/amd-pstate.h > +++ b/include/linux/amd-pstate.h > @@ -106,6 +106,7 @@ struct amd_cpudata { > u32 policy; > u64 cppc_cap1_cached; > bool suspended; > + bool boost_state; > }; > > /* >
-- Oleksandr Natalenko (post-factum)[unhandled content-type:application/pgp-signature] | |