| 
    
 [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  |