Re: [PATCH 3/3] cpufreq: CPPC: Support for autonomous selection in cppc_cpufreq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Pierre,

On 2024/12/6 22:23, Pierre Gondois wrote:
> Hello Lifeng,
> 
> On 11/14/24 09:48, Lifeng Zheng wrote:
>> Add sysfs interfaces for CPPC autonomous selection in the cppc_cpufreq
>> driver.
>>
>> Signed-off-by: Lifeng Zheng <zhenglifeng1@xxxxxxxxxx>
>> ---
>>   .../ABI/testing/sysfs-devices-system-cpu      |  54 +++++++
>>   drivers/cpufreq/cppc_cpufreq.c                | 141 ++++++++++++++++++
>>   2 files changed, 195 insertions(+)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> index 206079d3bd5b..ba7b8ea613e5 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
>> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> @@ -268,6 +268,60 @@ Description:    Discover CPUs in the same CPU frequency coordination domain
>>           This file is only present if the acpi-cpufreq or the cppc-cpufreq
>>           drivers are in use.
>>   +What:        /sys/devices/system/cpu/cpuX/cpufreq/auto_select
>> +Date:        October 2024
>> +Contact:    linux-pm@xxxxxxxxxxxxxxx
>> +Description:    Autonomous selection enable
>> +
>> +        Read/write interface to control autonomous selection enable
>> +            Read returns autonomous selection status:
>> +                0: autonomous selection is disabled
>> +                1: autonomous selection is enabled
>> +
>> +            Write '1' to enable autonomous selection.
>> +            Write '0' to disable autonomous selection.
>> +
>> +        This file only presents if the cppc-cpufreq driver is in use.
>> +
>> +What:        /sys/devices/system/cpu/cpuX/cpufreq/auto_act_window
>> +Date:        October 2024
>> +Contact:    linux-pm@xxxxxxxxxxxxxxx
>> +Description:    Autonomous activity window
>> +
>> +        This file indicates a moving utilization sensitivity window to
>> +        the platform's autonomous selection policy.
>> +
>> +        Read/write an integer represents autonomous activity window (in
>> +        microseconds) from/to this file. The max value to write is
>> +        1270000000 but the max significand is 127. This means that if 128
>> +        is written to this file, 127 will be stored. If the value is
>> +        greater than 130, only the first two digits will be saved as
>> +        significand.
>> +
>> +        Writing a zero value to this file enable the platform to
>> +        determine an appropriate Activity Window depending on the workload.
>> +
>> +        Writing to this file only has meaning when Autonomous Selection is
>> +        enabled.
>> +
>> +        This file only presents if the cppc-cpufreq driver is in use.
>> +
>> +What:        /sys/devices/system/cpu/cpuX/cpufreq/energy_perf
>> +Date:        October 2024
>> +Contact:    linux-pm@xxxxxxxxxxxxxxx
>> +Description:    Energy performance preference
>> +
>> +        Read/write an 8-bit integer from/to this file. This file
>> +        represents a range of values from 0 (performance preference) to
>> +        0xFF (energy efficiency preference) that influences the rate of
>> +        performance increase/decrease and the result of the hardware's
>> +        energy efficiency and performance optimization policies.
>> +
>> +        Writing to this file only has meaning when Autonomous Selection is
>> +        enabled.
>> +
>> +        This file only presents if the cppc-cpufreq driver is in use.
>> +
>>     What:        /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
>>   Date:        August 2008
>> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
>> index 2b8708475ac7..b435e1751d0d 100644
>> --- a/drivers/cpufreq/cppc_cpufreq.c
>> +++ b/drivers/cpufreq/cppc_cpufreq.c
>> @@ -792,10 +792,151 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
>>         return cpufreq_show_cpus(cpu_data->shared_cpu_map, buf);
>>   }
>> +
>> +static ssize_t show_auto_select(struct cpufreq_policy *policy, char *buf)
>> +{
>> +    u64 val;
>> +    int ret;
>> +
>> +    ret = cppc_get_auto_sel(policy->cpu, &val);
>> +
>> +    /* show "<unsupported>" when this register is not supported by cpc */
>> +    if (ret == -EOPNOTSUPP)
>> +        return sysfs_emit(buf, "%s\n", "<unsupported>");
>> +
>> +    if (ret)
>> +        return ret;
>> +
>> +    return sysfs_emit(buf, "%lld\n", val);
>> +}
>> +
>> +static ssize_t store_auto_select(struct cpufreq_policy *policy,
>> +                 const char *buf, size_t count)
>> +{
>> +    unsigned long val;
>> +    int ret;
>> +
>> +    ret = kstrtoul(buf, 0, &val);
>> +    if (ret)
>> +        return ret;
>> +
>> +    if (val > 1)
>> +        return -EINVAL;
>> +
>> +    ret = cppc_set_auto_sel(policy->cpu, val);
>> +    if (ret)
>> +        return ret;
>> +
>> +    return count;
>> +}
>> +
>> +#define AUTO_ACT_WINDOW_SIG_BIT_SIZE    (7)
>> +#define AUTO_ACT_WINDOW_EXP_BIT_SIZE    (3)
>> +#define AUTO_ACT_WINDOW_MAX_SIG    ((1 << AUTO_ACT_WINDOW_SIG_BIT_SIZE) - 1)
>> +#define AUTO_ACT_WINDOW_MAX_EXP    ((1 << AUTO_ACT_WINDOW_EXP_BIT_SIZE) - 1)
>> +/* AUTO_ACT_WINDOW_MAX_SIG is 127, so 128 and 129 will decay to 127 when writing */
>> +#define AUTO_ACT_WINDOW_SIG_CARRY_THRESH 129
> 
> Maybe this would be better to place these macros in include/acpi/cppc_acpi.h
> (with a CPPC_XXX prefix)

Will move them, Thanks.

> 
>> +
>> +static ssize_t show_auto_act_window(struct cpufreq_policy *policy, char *buf)
>> +{
>> +    int sig, exp;
>> +    u64 val;
>> +    int ret;
>> +
>> +    ret = cppc_get_auto_act_window(policy->cpu, &val);
>> +
>> +    /* show "<unsupported>" when this register is not supported by cpc */
>> +    if (ret == -EOPNOTSUPP)
>> +        return sysfs_emit(buf, "%s\n", "<unsupported>");
>> +
>> +    if (ret)
>> +        return ret;
>> +
>> +    sig = val & AUTO_ACT_WINDOW_MAX_SIG;
>> +    exp = (val >> AUTO_ACT_WINDOW_SIG_BIT_SIZE) & AUTO_ACT_WINDOW_MAX_EXP;
>> +
>> +    return sysfs_emit(buf, "%lld\n", sig * int_pow(10, exp));
>> +}
>> +
>> +static ssize_t store_auto_act_window(struct cpufreq_policy *policy,
>> +                     const char *buf, size_t count)
>> +{
>> +    unsigned long usec;
>> +    int digits = 0;
>> +    int ret;
>> +
>> +    ret = kstrtoul(buf, 0, &usec);
>> +    if (ret)
>> +        return ret;
>> +
>> +    if (usec > AUTO_ACT_WINDOW_MAX_SIG * int_pow(10, AUTO_ACT_WINDOW_MAX_EXP))
>> +        return -EINVAL;
>> +
>> +    while (usec > AUTO_ACT_WINDOW_SIG_CARRY_THRESH) {
>> +        usec /= 10;
>> +        digits += 1;
>> +    }
>> +
>> +    if (usec > AUTO_ACT_WINDOW_MAX_SIG)
>> +        usec = AUTO_ACT_WINDOW_MAX_SIG;
>> +
>> +    ret = cppc_set_auto_act_window(policy->cpu,
>> +                       (digits << AUTO_ACT_WINDOW_SIG_BIT_SIZE) + usec);
>> +    if (ret)
>> +        return ret;
>> +
>> +    return count;
>> +}
>> +
>> +static ssize_t show_energy_perf(struct cpufreq_policy *policy, char *buf)
>> +{
>> +    u64 val;
>> +    int ret;
>> +
>> +    ret = cppc_get_epp_perf(policy->cpu, &val);
>> +
>> +    /* show "<unsupported>" when this register is not supported by cpc */
>> +    if (ret == -EOPNOTSUPP)
>> +        return sysfs_emit(buf, "%s\n", "<unsupported>");
>> +
>> +    if (ret)
>> +        return ret;
>> +
>> +    return sysfs_emit(buf, "%lld\n", val);
>> +}
>> +
>> +#define ENERGY_PERF_MAX    (0xFF)
> 
> Same comment to move to include/acpi/cppc_acpi.h
> 
>> +
>> +static ssize_t store_energy_perf(struct cpufreq_policy *policy,
>> +                 const char *buf, size_t count)
>> +{
>> +    unsigned long val;
>> +    int ret;
>> +
>> +    ret = kstrtoul(buf, 0, &val);
>> +    if (ret)
>> +        return ret;
>> +
>> +    if (val > ENERGY_PERF_MAX)
>> +        return -EINVAL;
>> +
>> +    ret = cppc_set_epp(policy->cpu, val);
>> +    if (ret)
>> +        return ret;
>> +
>> +    return count;
>> +}
>> +
>>   cpufreq_freq_attr_ro(freqdomain_cpus);
>> +cpufreq_freq_attr_rw(auto_select);
>> +cpufreq_freq_attr_rw(auto_act_window);
>> +cpufreq_freq_attr_rw(energy_perf);
> 
> It might be better from a user PoV to hide the following entries:
> - auto_act_window
> - energy_perf
> if auto_select is not available or disabled.

Users might like to modify the value of auto_act_window and energy_perf
before turning on auto_select. So I think it is freer for users to read and
write them no matter what auto_select is. What do you think?

> 
> ------
> 
> Also just for reference, in ACPI 6.5, s8.4.6.1.2.3 Desired Performance Register
> """
> When Autonomous Selection is enabled, it is not necessary for OSPM to assess processor workload performance
> demand and convey a corresponding performance delivery request to the platform via the Desired Register. If the
> Desired Performance Register exists, OSPM may provide an explicit performance requirement hint to the platform by
> writing a non-zero value.
> """
> 
> So it seems it still makes sense to have cpufreq requesting a certain performance
> level even though autonomous selection is enabled.

We did struggle with this. This solves our doubts. Thanks!

> 





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux