[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 10/14 RESEND] xen: Add SET_CPUFREQ_HWP xen_sysctl_pm_op
On 01.05.2023 21:30, Jason Andryuk wrote: > @@ -531,6 +533,100 @@ int get_hwp_para(const struct cpufreq_policy *policy, > return 0; > } > > +int set_hwp_para(struct cpufreq_policy *policy, > + struct xen_set_hwp_para *set_hwp) const? > +{ > + unsigned int cpu = policy->cpu; > + struct hwp_drv_data *data = per_cpu(hwp_drv_data, cpu); > + > + if ( data == NULL ) > + return -EINVAL; > + > + /* Validate all parameters first */ > + if ( set_hwp->set_params & ~XEN_SYSCTL_HWP_SET_PARAM_MASK ) > + return -EINVAL; > + > + if ( set_hwp->activity_window & ~XEN_SYSCTL_HWP_ACT_WINDOW_MASK ) > + return -EINVAL; Below you limit checks to when the respective control bit is set. I think you want the same here. > + if ( !feature_hwp_energy_perf && > + (set_hwp->set_params & XEN_SYSCTL_HWP_SET_ENERGY_PERF) && > + set_hwp->energy_perf > IA32_ENERGY_BIAS_MAX_POWERSAVE ) > + return -EINVAL; > + > + if ( (set_hwp->set_params & XEN_SYSCTL_HWP_SET_DESIRED) && > + set_hwp->desired != 0 && > + (set_hwp->desired < data->hw.lowest || > + set_hwp->desired > data->hw.highest) ) > + return -EINVAL; > + > + /* > + * minimum & maximum are not validated as hardware doesn't seem to care > + * and the SDM says CPUs will clip internally. > + */ > + > + /* Apply presets */ > + switch ( set_hwp->set_params & XEN_SYSCTL_HWP_SET_PRESET_MASK ) > + { > + case XEN_SYSCTL_HWP_SET_PRESET_POWERSAVE: > + data->minimum = data->hw.lowest; > + data->maximum = data->hw.lowest; > + data->activity_window = 0; > + if ( feature_hwp_energy_perf ) > + data->energy_perf = HWP_ENERGY_PERF_MAX_POWERSAVE; > + else > + data->energy_perf = IA32_ENERGY_BIAS_MAX_POWERSAVE; > + data->desired = 0; > + break; > + > + case XEN_SYSCTL_HWP_SET_PRESET_PERFORMANCE: > + data->minimum = data->hw.highest; > + data->maximum = data->hw.highest; > + data->activity_window = 0; > + data->energy_perf = HWP_ENERGY_PERF_MAX_PERFORMANCE; > + data->desired = 0; > + break; > + > + case XEN_SYSCTL_HWP_SET_PRESET_BALANCE: > + data->minimum = data->hw.lowest; > + data->maximum = data->hw.highest; > + data->activity_window = 0; > + if ( feature_hwp_energy_perf ) > + data->energy_perf = HWP_ENERGY_PERF_BALANCE; > + else > + data->energy_perf = IA32_ENERGY_BIAS_BALANCE; > + data->desired = 0; > + break; > + > + case XEN_SYSCTL_HWP_SET_PRESET_NONE: > + break; > + > + default: > + return -EINVAL; > + } So presets set all the values for which the individual item control bits are clear. That's not exactly what I would have expected, and it took me reading the code several times until I realized that you write life per- CPU data fields here, not fields of some intermediate variable. I think this could do with saying explicitly in the public header (if indeed the intended model). > + /* Further customize presets if needed */ > + if ( set_hwp->set_params & XEN_SYSCTL_HWP_SET_MINIMUM ) > + data->minimum = set_hwp->minimum; > + > + if ( set_hwp->set_params & XEN_SYSCTL_HWP_SET_MAXIMUM ) > + data->maximum = set_hwp->maximum; > + > + if ( set_hwp->set_params & XEN_SYSCTL_HWP_SET_ENERGY_PERF ) > + data->energy_perf = set_hwp->energy_perf; > + > + if ( set_hwp->set_params & XEN_SYSCTL_HWP_SET_DESIRED ) > + data->desired = set_hwp->desired; > + > + if ( set_hwp->set_params & XEN_SYSCTL_HWP_SET_ACT_WINDOW ) > + data->activity_window = set_hwp->activity_window & > + XEN_SYSCTL_HWP_ACT_WINDOW_MASK; > + > + hwp_cpufreq_target(policy, 0, 0); > + > + return 0; I don't think you should assume here that hwp_cpufreq_target() will only ever return 0. Plus by returning its return value here you allow the compiler to tail-call optimize this code. > --- a/xen/drivers/acpi/pmstat.c > +++ b/xen/drivers/acpi/pmstat.c > @@ -398,6 +398,20 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op) > return ret; > } > > +static int set_cpufreq_hwp(struct xen_sysctl_pm_op *op) const? > --- a/xen/include/public/sysctl.h > +++ b/xen/include/public/sysctl.h > @@ -317,6 +317,34 @@ struct xen_hwp_para { > uint8_t energy_perf; > }; > > +/* set multiple values simultaneously when set_args bit is set */ What "set_args bit" does this comment refer to? > +struct xen_set_hwp_para { > +#define XEN_SYSCTL_HWP_SET_DESIRED (1U << 0) > +#define XEN_SYSCTL_HWP_SET_ENERGY_PERF (1U << 1) > +#define XEN_SYSCTL_HWP_SET_ACT_WINDOW (1U << 2) > +#define XEN_SYSCTL_HWP_SET_MINIMUM (1U << 3) > +#define XEN_SYSCTL_HWP_SET_MAXIMUM (1U << 4) > +#define XEN_SYSCTL_HWP_SET_PRESET_MASK 0xf000 > +#define XEN_SYSCTL_HWP_SET_PRESET_NONE 0x0000 > +#define XEN_SYSCTL_HWP_SET_PRESET_BALANCE 0x1000 > +#define XEN_SYSCTL_HWP_SET_PRESET_POWERSAVE 0x2000 > +#define XEN_SYSCTL_HWP_SET_PRESET_PERFORMANCE 0x3000 > +#define XEN_SYSCTL_HWP_SET_PARAM_MASK ( \ > + XEN_SYSCTL_HWP_SET_PRESET_MASK | \ > + XEN_SYSCTL_HWP_SET_DESIRED | \ > + XEN_SYSCTL_HWP_SET_ENERGY_PERF | \ > + XEN_SYSCTL_HWP_SET_ACT_WINDOW | \ > + XEN_SYSCTL_HWP_SET_MINIMUM | \ > + XEN_SYSCTL_HWP_SET_MAXIMUM ) > + uint16_t set_params; /* bitflags for valid values */ > +#define XEN_SYSCTL_HWP_ACT_WINDOW_MASK 0x03ff > + uint16_t activity_window; /* See comment in struct xen_hwp_para */ > + uint8_t minimum; > + uint8_t maximum; > + uint8_t desired; > + uint8_t energy_perf; /* 0-255 or 0-15 depending on HW support */ Instead of (or in addition to) the "HW support" reference, could this gain a reference to the "get para" bit determining which range to use? Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |