[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 09/15] cpufreq: Export HWP parameters to userspace as CPPC
On 14.06.2023 20:02, Jason Andryuk wrote: > --- a/xen/arch/x86/acpi/cpufreq/hwp.c > +++ b/xen/arch/x86/acpi/cpufreq/hwp.c > @@ -537,6 +537,29 @@ static const struct cpufreq_driver __initconstrel > hwp_cpufreq_driver = > .update = hwp_cpufreq_update, > }; > > +int get_hwp_para(const unsigned int cpu, > + struct xen_cppc_para *cppc_para) > +{ > + const struct hwp_drv_data *data = per_cpu(hwp_drv_data, cpu); > + > + if ( data == NULL ) > + return -EINVAL; Maybe better -ENODATA in this case? > --- a/xen/drivers/acpi/pmstat.c > +++ b/xen/drivers/acpi/pmstat.c > @@ -251,48 +251,54 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op) > else > strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN); > > - if ( !(scaling_available_governors = > - xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) ) > - return -ENOMEM; > - if ( (ret = read_scaling_available_governors( > - scaling_available_governors, > - gov_num * CPUFREQ_NAME_LEN * sizeof(char))) ) > + if ( !strncasecmp(op->u.get_para.scaling_driver, XEN_HWP_DRIVER, > + CPUFREQ_NAME_LEN) ) Mind me asking why you think case-insensitive compare is appropriate here? > + ret = get_hwp_para(policy->cpu, &op->u.get_para.u.cppc_para); > + else > { > + if ( !(scaling_available_governors = > + xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) ) > + return -ENOMEM; > + if ( (ret = read_scaling_available_governors( > + scaling_available_governors, > + gov_num * CPUFREQ_NAME_LEN * sizeof(char))) ) I realize you only re-indent this, but since you need to touch it anyway, may I suggest to also switch to siezof(*scaling_available_governors)? > + { > + xfree(scaling_available_governors); > + return ret; > + } > + ret = copy_to_guest(op->u.get_para.scaling_available_governors, > + scaling_available_governors, gov_num * CPUFREQ_NAME_LEN); Similarly here: Please adjust indentation while you touch this code. > xfree(scaling_available_governors); > - return ret; > - } > - ret = copy_to_guest(op->u.get_para.scaling_available_governors, > - scaling_available_governors, gov_num * CPUFREQ_NAME_LEN); > - xfree(scaling_available_governors); > - if ( ret ) > - return ret; > + if ( ret ) > + return ret; > > - op->u.get_para.u.s.scaling_cur_freq = policy->cur; > - op->u.get_para.u.s.scaling_max_freq = policy->max; > - op->u.get_para.u.s.scaling_min_freq = policy->min; > + op->u.get_para.u.s.scaling_cur_freq = policy->cur; > + op->u.get_para.u.s.scaling_max_freq = policy->max; > + op->u.get_para.u.s.scaling_min_freq = policy->min; > > - if ( policy->governor->name[0] ) > - strlcpy(op->u.get_para.u.s.scaling_governor, > - policy->governor->name, CPUFREQ_NAME_LEN); > - else > - strlcpy(op->u.get_para.u.s.scaling_governor, "Unknown", > - CPUFREQ_NAME_LEN); > + if ( policy->governor->name[0] ) > + strlcpy(op->u.get_para.u.s.scaling_governor, > + policy->governor->name, CPUFREQ_NAME_LEN); > + else > + strlcpy(op->u.get_para.u.s.scaling_governor, "Unknown", > + CPUFREQ_NAME_LEN); > > - /* governor specific para */ > - if ( !strncasecmp(op->u.get_para.u.s.scaling_governor, > - "userspace", CPUFREQ_NAME_LEN) ) > - { > - op->u.get_para.u.s.u.userspace.scaling_setspeed = policy->cur; > - } > + /* governor specific para */ > + if ( !strncasecmp(op->u.get_para.u.s.scaling_governor, > + "userspace", CPUFREQ_NAME_LEN) ) > + { > + op->u.get_para.u.s.u.userspace.scaling_setspeed = policy->cur; > + } Would also be nice if you could get rid of the unnecessary braces here at this occasion. > --- a/xen/include/acpi/cpufreq/cpufreq.h > +++ b/xen/include/acpi/cpufreq/cpufreq.h > @@ -248,5 +248,7 @@ void intel_feature_detect(struct cpufreq_policy *policy); > > extern bool __initdata opt_cpufreq_hwp; > int hwp_cmdline_parse(const char *s); > +int get_hwp_para(const unsigned int cpu, I think we generally avoid const when it's not a pointed-to type. It's not useful at all in a declaration. > --- a/xen/include/public/sysctl.h > +++ b/xen/include/public/sysctl.h > @@ -296,6 +296,61 @@ struct xen_ondemand { > uint32_t up_threshold; > }; > > +struct xen_cppc_para { > + /* OUT */ > + /* activity_window supported if 1 */ > +#define XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW (1 << 0) I think 1 isn't very helpful, looking forward. Perhaps better "set" or "flag set"? > + uint32_t features; /* bit flags for features */ > + /* > + * See Intel SDM: HWP Performance Range and Dynamic Capabilities > + * > + * These four are 0-255 hardware-provided values. They "continuous, > + * abstract unit-less, performance" values. smaller numbers are slower > + * and larger ones are faster. > + */ > + uint32_t lowest; > + uint32_t lowest_nonlinear; /* most_efficient */ Why non_linear in the external interface when internally you use most_efficient (merely put in the comment here)? > + uint32_t nominal; /* guaranteed */ Similar question for the name choice here. > + uint32_t highest; > + /* > + * See Intel SDM: IA32_HWP_REQUEST MSR (Address: 774H Logical Processor > + * Scope) > + * > + * These are all hints, and the processor may deviate outside of them. > + * Values below are 0-255. > + * > + * minimum and maximum can be set to the above hardware values to > constrain > + * operation. The full range 0-255 is accepted and will be clipped by > + * hardware. > + */ > + uint32_t minimum; > + uint32_t maximum; > + /* > + * Set an explicit performance hint, disabling hardware selection. > + * 0 lets the hardware decide. > + */ > + uint32_t desired; "Set" kind of conflicts with all fields being marked as OUT above. I think the word can simply be dropped? Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |