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 Lifeng,

On 12/9/24 09:40, zhenglifeng (A) wrote:
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;
+}

Also I tested the logic and it was working correctly for me.

+
+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?

Autonomous selection is not the most common case for the CPPC cpufreq drivers,
so these new files might bring questions to people currently using it.

On the other side, making these files visible only when 'auto_select' is enabled
will require additional logic in the code (while the current implementation is
quite clear).

I think Rafael or Viresh should take the decision. So it might be better to
directly ping them,

Regards,
Pierre



------

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