|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 10/18] xen/cpufreq: introduce a new amd cppc driver for cpufreq scaling
On 27.05.2025 10:48, Penny Zheng wrote:
> --- a/xen/arch/x86/acpi/cpufreq/amd-cppc.c
> +++ b/xen/arch/x86/acpi/cpufreq/amd-cppc.c
> @@ -14,7 +14,56 @@
> #include <xen/domain.h>
> #include <xen/init.h>
> #include <xen/param.h>
> +#include <xen/percpu.h>
> +#include <xen/xvmalloc.h>
> #include <acpi/cpufreq/cpufreq.h>
> +#include <asm/amd.h>
> +#include <asm/msr-index.h>
> +
> +#define amd_cppc_err(cpu, fmt, args...) \
> + printk(XENLOG_ERR "AMD_CPPC: CPU%u error: " fmt, cpu, ## args)
> +#define amd_cppc_warn(cpu, fmt, args...) \
> + printk(XENLOG_WARNING "AMD_CPPC: CPU%u warning: " fmt, cpu, ## args)
> +#define amd_cppc_verbose(cpu, fmt, args...) \
> +({ \
> + if ( cpufreq_verbose ) \
> + printk(XENLOG_DEBUG "AMD_CPPC: CPU%u " fmt, cpu, ## args); \
> +})
Nit: Much like in the file name, would you mind using AMD-CPPC in favor of
AMD_CPPC here, too?
> @@ -50,10 +99,323 @@ int __init amd_cppc_cmdline_parse(const char *s, const
> char *e)
> return 0;
> }
>
> +/*
> + * If CPPC lowest_freq and nominal_freq registers are exposed then we can
> + * use them to convert perf to freq and vice versa. The conversion is
> + * extrapolated as an linear function passing by the 2 points:
> + * - (Low perf, Low freq)
> + * - (Nominal perf, Nominal freq)
> + * Parameter freq is always in kHz.
> + */
> +static int amd_cppc_khz_to_perf(const struct amd_cppc_drv_data *data,
> + unsigned int freq, uint8_t *perf)
> +{
> + const struct xen_processor_cppc *cppc_data = data->cppc_data;
> + unsigned int mul, div;
> + int offset = 0, res;
> +
> + if ( cppc_data->cpc.lowest_mhz && cppc_data->cpc.nominal_mhz )
> + {
> + mul = data->caps.nominal_perf - data->caps.lowest_perf;
> + div = cppc_data->cpc.nominal_mhz - cppc_data->cpc.lowest_mhz;
What guarantees both of these values to be non-zero?
> + /*
> + * We don't need to convert to kHz for computing offset and can
> + * directly use nominal_mhz and lowest_mhz as the division
> + * will remove the frequency unit.
> + */
> + offset = data->caps.nominal_perf -
> + (mul * cppc_data->cpc.nominal_mhz) / div;
> + }
> + else
> + {
> + /* Read Processor Max Speed(MHz) as anchor point */
> + mul = data->caps.highest_perf;
> + div = this_cpu(pxfreq_mhz);
> + if ( !div )
> + return -EINVAL;
What's wrong about the function arguments in this case? (Same question again
on further uses of EINVAL below.)
> +static int cf_check amd_cppc_cpufreq_target(struct cpufreq_policy *policy,
> + unsigned int target_freq,
> + unsigned int relation)
> +{
> + unsigned int cpu = policy->cpu;
> + const struct amd_cppc_drv_data *data = per_cpu(amd_cppc_drv_data, cpu);
> + uint8_t des_perf;
> + int res;
> +
> + if ( unlikely(!target_freq) )
> + return 0;
> +
> + res = amd_cppc_khz_to_perf(data, target_freq, &des_perf);
> + if ( res )
> + return res;
> +
> + /*
> + * Setting with "lowest_nonlinear_perf" to ensure governoring
> + * performance in P-state range.
> + */
> + amd_cppc_write_request(policy->cpu, data->caps.lowest_nonlinear_perf,
> + des_perf, data->caps.highest_perf);
I fear I don't understand the comment, and hence it remains unclear to me
why lowest_nonlinear_perf is being used here.
> +static int cf_check amd_cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> + unsigned int cpu = policy->cpu;
> + struct amd_cppc_drv_data *data;
> +
> + data = xvzalloc(struct amd_cppc_drv_data);
> + if ( !data )
> + return -ENOMEM;
> +
> + data->cppc_data = &processor_pminfo[cpu]->cppc_data;
> +
> + per_cpu(amd_cppc_drv_data, cpu) = data;
> +
> + on_selected_cpus(cpumask_of(cpu), amd_cppc_init_msrs, policy, 1);
> +
> + /*
> + * The enable bit is sticky, as we need to enable it at the very first
> + * begining, before CPPC capability values sanity check.
> + * If error path takes effective, not only amd-cppc cpufreq core fails
Nit: "takes effect" or "is taken".
> + * to initialize, but also we could not fall back to legacy P-states
> + * driver, irrespective of the command line specifying a fallback option.
> + */
> + if ( data->err )
> + {
> + amd_cppc_err(cpu, "Could not initialize cpufreq cores in CPPC
> mode\n");
Why "cores" (plural)?
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |