|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v1 02/11] xen/x86: introduce new sub-hypercall to get CPPC data
On 03.12.2024 09:11, Penny Zheng wrote:
> In order to provide backward compatibility with existing governors
> that represent performance as frequencies, like ondemand, the _CPC
> table can optionally provide processor frequency range values, Lowest
> frequency and Norminal frequency, to let OS use Lowest Frequency/
> Performance and Nominal Frequency/Performance as anchor points to
> create linear mapping of CPPC abstract performance to CPU frequency.
>
> As Xen is uncapable of parsing the ACPI dynamic table, this commit
> introduces a new sub-hypercall to get required CPPC data from
> dom0 kernel.
"get" as used both here and in the title is, to me, something an entity
does actively. Xen is entirely passive here, though. (Reading the title
I was first assuming this is about a sub-op to get certain data out of
Xen.)
> --- a/xen/arch/x86/platform_hypercall.c
> +++ b/xen/arch/x86/platform_hypercall.c
> @@ -572,6 +572,12 @@ ret_t do_platform_op(
> break;
> }
>
> + case XEN_PM_CPPC:
> + {
> + ret = set_cppc_pminfo(op->u.set_pminfo.id,
> &op->u.set_pminfo.u.cppc_data);
> + }
> + break;
No such unnecessary figure braces please, which - once dropped - will
also call for "break" to be indented one level deeper.
> --- a/xen/arch/x86/x86_64/cpufreq.c
> +++ b/xen/arch/x86/x86_64/cpufreq.c
> @@ -54,3 +54,21 @@ int compat_set_px_pminfo(uint32_t acpi_id,
>
> return set_px_pminfo(acpi_id, xen_perf);
> }
> +
> +int compat_set_cppc_pminfo(uint32_t acpi_id,
> + struct compat_processor_cppc *cppc_data)
> +{
> + struct xen_processor_cppc *xen_cppc;
> + unsigned long xlat_page_current;
> +
> + xlat_malloc_init(xlat_page_current);
> +
> + xen_cppc = xlat_malloc_array(xlat_page_current,
> + struct xen_processor_cppc, 1);
> + if ( unlikely(xen_cppc == NULL) )
> + return -EFAULT;
> +
> + XLAT_processor_cppc(xen_cppc, cppc_data);
> +
> + return set_cppc_pminfo(acpi_id, xen_cppc);
> +}
Why's this needed? The structure - for now at least - consists of only
uint32_t-s, and hence has identical layout for compat callers.
> --- a/xen/drivers/cpufreq/cpufreq.c
> +++ b/xen/drivers/cpufreq/cpufreq.c
> @@ -458,6 +458,56 @@ static void print_PPC(unsigned int platform_limit)
> printk("\t_PPC: %d\n", platform_limit);
> }
>
> +static void print_CPPC(struct xen_processor_cppc *cppc_data)
Pointer-to-const?
> +{
> + printk("\t_CPC: highest_perf=%u, lowest_perf=%u, "
> + "nominal_perf=%u, lowest_nonlinear_perf=%u, "
> + "nominal_freq=%uMhz, lowest_freq=%uMhz\n",
> + cppc_data->highest_perf, cppc_data->lowest_perf,
> + cppc_data->nominal_perf, cppc_data->lowest_nonlinear_perf,
> + cppc_data->nominal_freq, cppc_data->lowest_freq);
> +}
> +
> +int set_cppc_pminfo(uint32_t acpi_id, struct xen_processor_cppc *cppc_data)
Pointer-to-const?
> +{
> + int ret = 0, cpuid;
> + struct processor_pminfo *pm_info;
> +
> + cpuid = get_cpu_id(acpi_id);
> + if ( cpuid < 0 || !cppc_data )
> + {
> + ret = -EINVAL;
> + goto out;
> + }
> + if ( cpufreq_verbose )
> + printk("Set CPU acpi_id(%d) cpuid(%d) CPPC State info:\n",
> + acpi_id, cpuid);
> +
> + pm_info = processor_pminfo[cpuid];
> + if ( !pm_info )
> + {
> + pm_info = xzalloc(struct processor_pminfo);
Please be aware that new code is supposed to be using xvmalloc().
> + if ( !pm_info )
> + {
> + ret = -ENOMEM;
> + goto out;
> + }
> + processor_pminfo[cpuid] = pm_info;
> + }
> + pm_info->acpi_id = acpi_id;
> + pm_info->id = cpuid;
> +
> + memcpy ((void *)&pm_info->cppc_data,
> + (void *)cppc_data,
> + sizeof(struct xen_processor_cppc));
What use are these casts? Also please no blank before the opening parenthesis
of a function call, and please sizeof(*cppc_data). Yet then - why memcpy() in
the first place? This can be a (type safe) structure assignment, can't it?
> --- a/xen/include/public/platform.h
> +++ b/xen/include/public/platform.h
> @@ -363,6 +363,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
> #define XEN_PM_PX 1
> #define XEN_PM_TX 2
> #define XEN_PM_PDC 3
> +#define XEN_PM_CPPC 4
>
> /* Px sub info type */
> #define XEN_PX_PCT 1
> @@ -432,6 +433,15 @@ struct xen_processor_px {
> typedef struct xen_processor_px xen_processor_px_t;
> DEFINE_XEN_GUEST_HANDLE(xen_processor_px_t);
>
> +struct xen_processor_cppc {
> + uint32_t highest_perf;
> + uint32_t nominal_perf;
> + uint32_t lowest_perf;
> + uint32_t lowest_nonlinear_perf;
> + uint32_t lowest_freq;
> + uint32_t nominal_freq;
> +};
_CPC contains a lot more data. Please clarify on what basis this subset was
chosen. (Keeping the chosen fields in the order _CPC has them might also be
a good idea.)
> --- a/xen/include/xlat.lst
> +++ b/xen/include/xlat.lst
> @@ -166,6 +166,7 @@
> ! processor_cx platform.h
> ! processor_flags platform.h
> ! processor_performance platform.h
> +! processor_cppc platform.h
> ! processor_power platform.h
> ? processor_px platform.h
> ! psd_package platform.h
Please obey to alphabetic sorting. As per an earlier comment I also expect
this wants to be using '?' in place of '!'.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |