|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 8/9] x86/intel_pstate: support the use of intel_pstate in pmstat.c
>>> On 14.09.15 at 04:32, <wei.w.wang@xxxxxxxxx> wrote:
> --- a/tools/libxc/xc_pm.c
> +++ b/tools/libxc/xc_pm.c
> @@ -260,13 +260,14 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
> }
> else
> {
> - user_para->cpuinfo_cur_freq = sys_para->cpuinfo_cur_freq;
> - user_para->cpuinfo_max_freq = sys_para->cpuinfo_max_freq;
> - user_para->cpuinfo_min_freq = sys_para->cpuinfo_min_freq;
> - user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
> - user_para->scaling_max_freq = sys_para->scaling_max_freq;
> - user_para->scaling_min_freq = sys_para->scaling_min_freq;
> - user_para->turbo_enabled = sys_para->turbo_enabled;
> + user_para->cpuinfo_cur_freq = sys_para->cpuinfo_cur_freq;
> + user_para->cpuinfo_max_freq = sys_para->cpuinfo_max_freq;
> + user_para->cpuinfo_min_freq = sys_para->cpuinfo_min_freq;
> + user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
> + user_para->scaling_max.pct = sys_para->scaling_max_perf;
> + user_para->scaling_min.pct = sys_para->scaling_min_perf;
> + user_para->scaling_turbo_pct = sys_para->scaling_turbo_pct;
> + user_para->turbo_enabled = sys_para->turbo_enabled;
You fail to communicate perf_alias here. How will the caller know?
It's also odd that you initialize .pct fields from _perf ones - can't the
naming and layout be arranged to match as much as possible?
> --- a/xen/drivers/acpi/pmstat.c
> +++ b/xen/drivers/acpi/pmstat.c
> @@ -191,7 +191,9 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
> uint32_t ret = 0;
> const struct processor_pminfo *pmpt;
> struct cpufreq_policy *policy;
> - uint32_t gov_num = 0;
> + struct perf_limits *limits;
> + struct internal_governor *internal_gov;
> + uint32_t cur_gov, gov_num = 0;
> uint32_t *affected_cpus;
> uint32_t *scaling_available_frequencies;
> char *scaling_available_governors;
> @@ -200,13 +202,21 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
>
> pmpt = processor_pminfo[op->cpuid];
> policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
> + limits = &policy->limits;
> + internal_gov = policy->internal_gov;
> + cur_gov = internal_gov ? internal_gov->cur_gov : 0;
Bad literal 0 (see the uses of cur_gov below).
> if ( !pmpt || !pmpt->perf.states ||
> - !policy || !policy->governor )
> + !policy || (!policy->governor && !policy->internal_gov) )
Either you think you need the local variable internal_gov - then use
it everywhere, or drop it.
> return -EINVAL;
>
> - list_for_each(pos, &cpufreq_governor_list)
> - gov_num++;
> + if ( internal_gov )
> + gov_num = internal_gov->gov_num;
Since you don't need cur_gov ahead of this, please limit the number
of conditionals by moving its initialization here.
> op->u.get_para.cpuinfo_cur_freq =
> cpufreq_driver->get ? cpufreq_driver->get(op->cpuid) : policy->cur;
> op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
> op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
> op->u.get_para.scaling_cur_freq = policy->cur;
> - op->u.get_para.scaling_max_freq = policy->max;
> - op->u.get_para.scaling_min_freq = policy->min;
> + if ( internal_gov )
> + {
> + op->u.get_para.scaling_max_perf = limits->max_perf_pct;
> + op->u.get_para.scaling_min_perf = limits->min_perf_pct;
> + op->u.get_para.scaling_turbo_pct = limits->turbo_pct;
> + }
> + else
> + {
> + op->u.get_para.scaling_max_perf = policy->max;
> + op->u.get_para.scaling_min_perf = policy->min;
> + }
>
> if ( cpufreq_driver->name[0] )
> + {
> strlcpy(op->u.get_para.scaling_driver,
> cpufreq_driver->name, CPUFREQ_NAME_LEN);
> + if ( !strncmp(cpufreq_driver->name,
> + "intel_pstate", CPUFREQ_NAME_LEN) )
> + op->u.get_para.perf_alias = PERCENTAGE;
> + else
> + op->u.get_para.perf_alias = FREQUENCY;
This should be done together with the other things in the if/else
right above.
> @@ -299,16 +357,36 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
> static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
> {
> struct cpufreq_policy new_policy, *old_policy;
> + struct internal_governor *internal_gov;
>
> old_policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
> if ( !old_policy )
> return -EINVAL;
> + internal_gov = old_policy->internal_gov;
>
> memcpy(&new_policy, old_policy, sizeof(struct cpufreq_policy));
>
> - new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
> - if (new_policy.governor == NULL)
> - return -EINVAL;
> + if ( internal_gov && internal_gov->cur_gov )
> + {
> + if ( !strnicmp(op->u.set_gov.scaling_governor,
> + "performance", CPUFREQ_NAME_LEN) )
> + internal_gov->cur_gov = INTERNAL_GOV_PERFORMANCE;
> + else if ( !strnicmp(op->u.set_gov.scaling_governor,
> + "powersave", CPUFREQ_NAME_LEN) )
> + internal_gov->cur_gov = INTERNAL_GOV_POWERSAVE;
> + else if ( !strnicmp(op->u.set_gov.scaling_governor,
> + "userspace", CPUFREQ_NAME_LEN) )
> + internal_gov->cur_gov = INTERNAL_GOV_USERSPACE;
> + else if ( !strnicmp(op->u.set_gov.scaling_governor,
> + "ondemand", CPUFREQ_NAME_LEN) )
> + internal_gov->cur_gov = INTERNAL_GOV_ONDEMAND;
Wouldn't this better be done by the internal governor's code, so
it can also for itself decide which of the kinds it may not want to
support?
> @@ -340,6 +423,9 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
> {
> struct cpufreq_policy new_policy;
>
> + if ( !policy->governor || internal_gov )
Hard tab.
> @@ -347,10 +433,43 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
> break;
> }
>
> + case SCALING_MAX_PCT:
> + {
> + struct cpufreq_policy new_policy;
> + struct perf_limits *limits = &new_policy.limits;
> +
> + if ( policy->governor || !internal_gov )
> + return -EINVAL;
> +
> + new_policy = *policy;
> + limits->max_perf_pct = clamp_t(uint32_t, op->u.set_para.ctrl_value,
> + limits->min_policy_pct, limits->max_policy_pct);
Afaict all three values are of the same type - why clamp_t() then
instead of clamp()?
> --- a/xen/include/public/sysctl.h
> +++ b/xen/include/public/sysctl.h
> @@ -297,11 +297,28 @@ typedef struct xen_ondemand xen_ondemand_t;
> * same as sysfs file name of native linux
> */
> #define CPUFREQ_NAME_LEN 16
> +
> +enum perf_alias {
xen_ prefix missing.
> + FREQUENCY = 0,
> + PERCENTAGE = 1
> +};
> +
> struct xen_get_cpufreq_para {
> /* IN/OUT variable */
> uint32_t cpu_num;
> uint32_t freq_num;
> uint32_t gov_num;
> + int32_t turbo_enabled;
> +
> + uint32_t cpuinfo_cur_freq;
> + uint32_t cpuinfo_max_freq;
> + uint32_t cpuinfo_min_freq;
> + uint32_t scaling_cur_freq;
> +
> + uint32_t scaling_turbo_pct;
> + uint32_t scaling_max_perf;
> + uint32_t scaling_min_perf;
> + enum perf_alias perf_alias;
>
> /* for all governors */
> /* OUT variable */
> @@ -309,23 +326,13 @@ struct xen_get_cpufreq_para {
> XEN_GUEST_HANDLE_64(uint32) scaling_available_frequencies;
> XEN_GUEST_HANDLE_64(char) scaling_available_governors;
> char scaling_driver[CPUFREQ_NAME_LEN];
> -
> - uint32_t cpuinfo_cur_freq;
> - uint32_t cpuinfo_max_freq;
> - uint32_t cpuinfo_min_freq;
> - uint32_t scaling_cur_freq;
> -
> char scaling_governor[CPUFREQ_NAME_LEN];
> - uint32_t scaling_max_freq;
> - uint32_t scaling_min_freq;
>
> /* for specific governor */
> union {
> struct xen_userspace userspace;
> struct xen_ondemand ondemand;
> } u;
> -
> - int32_t turbo_enabled;
> };
Is all of this re-arrangement really needed? Also can't turbo_enabled
and scaling_turbo_pct be combined into a single field?
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |