[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 15/15] xen/xenpm: Adapt SET/GET_CPUFREQ_CPPC xen_sysctl_pm_op for amd-cppc driver
On 14.04.2025 09:40, Penny Zheng wrote: > Introduce helper set_amd_cppc_para and get_amd_cppc_para to > SET/GET CPPC-related para for amd-cppc/amd-cppc-epp driver. > > Signed-off-by: Penny Zheng <Penny.Zheng@xxxxxxx> > --- > v1 -> v2: > - Give the variable des_perf an initializer of 0 > - Use the strncmp()s directly in the if() > --- > v3 -> v4 > - refactor comments > - remove double blank lines > - replace amd_cppc_in_use flag with XEN_PROCESSOR_PM_CPPC > --- > xen/arch/x86/acpi/cpufreq/amd-cppc.c | 121 +++++++++++++++++++++++++++ > xen/drivers/acpi/pmstat.c | 22 ++++- > xen/include/acpi/cpufreq/cpufreq.h | 4 + > 3 files changed, 143 insertions(+), 4 deletions(-) Along the lines of the remark on an earlier patch: Where's the "xenpm" change here, that the subject prefix kind of makes one expect? Doesn't that want to be "cpufreq:" instead? > --- a/xen/arch/x86/acpi/cpufreq/amd-cppc.c > +++ b/xen/arch/x86/acpi/cpufreq/amd-cppc.c > @@ -540,6 +540,127 @@ static int cf_check amd_cppc_epp_set_policy(struct > cpufreq_policy *policy) > return 0; > } > > +int get_amd_cppc_para(unsigned int cpu, > + struct xen_cppc_para *cppc_para) > +{ > + const struct amd_cppc_drv_data *data = per_cpu(amd_cppc_drv_data, cpu); > + > + if ( data == NULL ) > + return -ENODATA; > + > + cppc_para->features = 0; What's the purpose of the field when you store literal 0 into it? > + cppc_para->lowest = data->caps.lowest_perf; > + cppc_para->lowest_nonlinear = data->caps.lowest_nonlinear_perf; > + cppc_para->nominal = data->caps.nominal_perf; > + cppc_para->highest = data->caps.highest_perf; > + cppc_para->minimum = data->req.min_perf; > + cppc_para->maximum = data->req.max_perf; > + cppc_para->desired = data->req.des_perf; > + cppc_para->energy_perf = data->req.epp; > + > + return 0; > +} > + > +int set_amd_cppc_para(const struct cpufreq_policy *policy, > + const struct xen_set_cppc_para *set_cppc) > +{ > + unsigned int cpu = policy->cpu; > + struct amd_cppc_drv_data *data = per_cpu(amd_cppc_drv_data, cpu); > + uint8_t max_perf, min_perf, des_perf = 0, epp; > + > + if ( data == NULL ) > + return -ENOENT; > + > + /* Validate all parameters - Disallow reserved bits. */ > + if ( set_cppc->minimum > UINT8_MAX || set_cppc->maximum > UINT8_MAX || > + set_cppc->desired > UINT8_MAX || set_cppc->energy_perf > UINT8_MAX ) > + return -EINVAL; Where is what the latter half of the comment says? > + /* Only allow values if params bit is set. */ > + if ( (!(set_cppc->set_params & XEN_SYSCTL_CPPC_SET_DESIRED) && > + set_cppc->desired) || > + (!(set_cppc->set_params & XEN_SYSCTL_CPPC_SET_MINIMUM) && > + set_cppc->minimum) || > + (!(set_cppc->set_params & XEN_SYSCTL_CPPC_SET_MAXIMUM) && > + set_cppc->maximum) || > + (!(set_cppc->set_params & XEN_SYSCTL_CPPC_SET_ENERGY_PERF) && > + set_cppc->energy_perf) ) > + return -EINVAL; > + > + /* Activity window not supported in MSR */ > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_ACT_WINDOW ) > + return -EOPNOTSUPP; > + > + /* Return if there is nothing to do. */ > + if ( set_cppc->set_params == 0 ) > + return 0; > + > + epp = per_cpu(epp_init, cpu); > + /* > + * Apply presets: > + * XEN_SYSCTL_CPPC_SET_DESIRED reflects whether desired perf is set, > which > + * is also the flag to distiguish between passive mode and active mode. > + * When it is set, CPPC in passive mode, only > + * XEN_SYSCTL_CPPC_SET_PRESET_NONE could be chosen, where min_perf = > + * lowest_nonlinear_perf to ensures performance in P-state range. > + * when it is not set, CPPC in active mode, three different profile > + * XEN_SYSCTL_CPPC_SET_PRESET_POWERSAVE/PERFORMANCE/BALANCE are provided, > + * where min_perf = lowest_perf having T-state range of performance. > + */ I fear I'm struggling to parse some of this, making it difficult to suggest possible adjustments (as I can't derive what is meant to be said). Plus where's the term T-state coming from all of the sudden? > + switch ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_PRESET_MASK ) > + { > + case XEN_SYSCTL_CPPC_SET_PRESET_POWERSAVE: > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_DESIRED ) > + return -EINVAL; > + min_perf = data->caps.lowest_perf; > + /* Lower max frequency to nominal */ > + max_perf = data->caps.nominal_perf; This combination is still not really in line with ... > + epp = CPPC_ENERGY_PERF_MAX_POWERSAVE; > + break; > + > + case XEN_SYSCTL_CPPC_SET_PRESET_PERFORMANCE: > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_DESIRED ) > + return -EINVAL; > + /* Increase idle frequency to highest */ > + min_perf = data->caps.highest_perf; > + max_perf = data->caps.highest_perf; ... this. If "performance" means "always highest", why would "powersave" not mean "always lowest"? > + epp = CPPC_ENERGY_PERF_MAX_PERFORMANCE; > + break; > + > + case XEN_SYSCTL_CPPC_SET_PRESET_BALANCE: > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_DESIRED ) > + return -EINVAL; > + min_perf = data->caps.lowest_perf; > + max_perf = data->caps.highest_perf; > + epp = CPPC_ENERGY_PERF_BALANCE; > + break; > + > + case XEN_SYSCTL_CPPC_SET_PRESET_NONE: > + min_perf = data->caps.lowest_nonlinear_perf; As before: What's the significance of using the non-linear value here? I asked to add comments for anything that's potentially unexpected to the reader, but here there's still none. > + max_perf = data->caps.highest_perf; > + break; > + > + default: > + return -EINVAL; > + } > + > + /* Further customize presets if needed */ > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_MINIMUM ) > + min_perf = set_cppc->minimum; > + > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_MAXIMUM ) > + max_perf = set_cppc->maximum; > + > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_ENERGY_PERF ) > + epp = set_cppc->energy_perf; > + > + if ( set_cppc->set_params & XEN_SYSCTL_CPPC_SET_DESIRED ) > + des_perf = set_cppc->desired; > + > + amd_cppc_write_request(cpu, min_perf, des_perf, max_perf, epp); > + return 0; > +} Nit (as before): Blank line please ahead of the main "return" of a function. > --- a/xen/drivers/acpi/pmstat.c > +++ b/xen/drivers/acpi/pmstat.c > @@ -257,7 +257,18 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op) > !strncmp(op->u.get_para.scaling_driver, XEN_HWP_DRIVER_NAME, > CPUFREQ_NAME_LEN) ) > ret = get_hwp_para(policy->cpu, &op->u.get_para.u.cppc_para); > - else > + else if ( !strncmp(op->u.get_para.scaling_driver, > + XEN_AMD_CPPC_DRIVER_NAME, > + CPUFREQ_NAME_LEN) || > + !strncmp(op->u.get_para.scaling_driver, > + XEN_AMD_CPPC_EPP_DRIVER_NAME, > + CPUFREQ_NAME_LEN) ) How about using e.g. strstr(..., XEN_AMD_CPPC_DRIVER_NAME) here? (It's odd anyway that we need to resort to string comparisons here.) > + ret = get_amd_cppc_para(policy->cpu, &op->u.get_para.u.cppc_para); > + > + if ( strncmp(op->u.get_para.scaling_driver, XEN_HWP_DRIVER_NAME, > + CPUFREQ_NAME_LEN) && > + strncmp(op->u.get_para.scaling_driver, XEN_AMD_CPPC_EPP_DRIVER_NAME, > + CPUFREQ_NAME_LEN) ) > { > if ( !(scaling_available_governors = > xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) ) Isn't it the non-EPP driver which is governor-independent? Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |