[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.