|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 13/19] xen/x86: implement amd-cppc-epp driver for CPPC in active mode
On 11.07.2025 05:51, Penny Zheng wrote:
> --- a/xen/arch/x86/acpi/cpufreq/amd-cppc.c
> +++ b/xen/arch/x86/acpi/cpufreq/amd-cppc.c
> @@ -67,7 +67,14 @@
> * max_perf.
> * Field des_perf conveys performance level Xen governor is requesting. And
> it
> * may be set to any performance value in the range [min_perf, max_perf],
> - * inclusive.
> + * inclusive. In active mode, desf_perf must be zero.
Nit (typo): des_perf
> @@ -259,11 +276,18 @@ static void cf_check amd_cppc_write_request_msrs(void
> *info)
> }
>
> static void amd_cppc_write_request(unsigned int cpu, uint8_t min_perf,
> - uint8_t des_perf, uint8_t max_perf)
> + uint8_t des_perf, uint8_t max_perf,
> + uint8_t epp)
> {
> struct amd_cppc_drv_data *data = per_cpu(amd_cppc_drv_data, cpu);
> uint64_t prev = data->req.raw;
>
> + if ( !opt_active_mode )
> + data->req.des_perf = des_perf;
> + else
> + data->req.des_perf = 0;
In amd_cppc_epp_set_policy() you pass 0 anyway. Why is this needed? With this
change dropped, opt_active_mode can become __initdata. (But of course you may
want to add an assertion instead, in which case the variable needs to stay
where it is at least in debug builds.)
> + data->req.epp = epp;
Ahead of this patch, aren't you mis-handling this field then, in that you
clear it (as you never read the MSR)?
> data->req.min_perf = min_perf;
> data->req.max_perf = max_perf;
> data->req.des_perf = des_perf;
Don't you need to delete this line with the addition above, or alternatively
change the above to
if ( opt_active_mode )
data->req.des_perf = 0;
?
> @@ -274,6 +298,14 @@ static void amd_cppc_write_request(unsigned int cpu,
> uint8_t min_perf,
> on_selected_cpus(cpumask_of(cpu), amd_cppc_write_request_msrs, data, 1);
> }
>
> +static void read_epp_init(void)
> +{
> + uint64_t val;
> +
> + rdmsrl(MSR_AMD_CPPC_REQ, val);
> + this_cpu(epp_init) = MASK_EXTR(val, AMD_CPPC_EPP_MASK);
> +}
I'm unconvinced this is worth a separate function.
> +static int cf_check amd_cppc_epp_set_policy(struct cpufreq_policy *policy)
> +{
> + const struct amd_cppc_drv_data *data = per_cpu(amd_cppc_drv_data,
> + policy->cpu);
> + uint8_t max_perf, min_perf, epp;
> +
> + /*
> + * On default, set min_perf with lowest_nonlinear_perf, and max_perf
> + * with the highest, to ensure performance scaling in P-states range.
> + */
> + max_perf = data->caps.highest_perf;
> + min_perf = data->caps.lowest_nonlinear_perf;
> +
> + /*
> + * In policy CPUFREQ_POLICY_PERFORMANCE, increase min_perf to
> + * highest_perf to achieve ultmost performance.
> + * In policy CPUFREQ_POLICY_POWERSAVE, decrease max_perf to
> + * lowest_nonlinear_perf to achieve ultmost power saving.
> + */
> + switch ( policy->policy )
> + {
> + case CPUFREQ_POLICY_PERFORMANCE:
> + /* Force the epp value to be zero for performance policy */
> + epp = CPPC_ENERGY_PERF_MAX_PERFORMANCE;
> + min_perf = data->caps.highest_perf;
Use the local variable you have, i.e. max_perf?
> + break;
> +
> + case CPUFREQ_POLICY_POWERSAVE:
> + /* Force the epp value to be 0xff for powersave policy */
> + epp = CPPC_ENERGY_PERF_MAX_POWERSAVE;
> + max_perf = data->caps.lowest_nonlinear_perf;
Use the local variable you have, i.e. min_perf?
> --- a/xen/arch/x86/include/asm/msr-index.h
> +++ b/xen/arch/x86/include/asm/msr-index.h
> @@ -245,6 +245,7 @@
> #define MSR_AMD_CPPC_ENABLE 0xc00102b1U
> #define AMD_CPPC_ENABLE (_AC(1, ULL) << 0)
> #define MSR_AMD_CPPC_REQ 0xc00102b3U
> +#define AMD_CPPC_EPP_MASK (_AC(0xff, ULL) << 24)
The reason I noticed the EPP issue in amd_cppc_write_request() is because
I wondered why you would need this, when you have the fields defined in
struct amd_cppc_drv_data.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |