cpupower: Add EPP value change support
authorWyes Karny <wyes.karny@amd.com>
Mon, 19 Jun 2023 19:05:01 +0000 (19:05 +0000)
committerShuah Khan <skhan@linuxfoundation.org>
Tue, 18 Jul 2023 22:06:49 +0000 (16:06 -0600)
amd_pstate and intel_pstate active mode drivers support energy
performance preference feature. Through this user can convey it's
energy/performance preference to platform. Add this value change
capability to cpupower.

To change the EPP value use below command:
cpupower set --epp performance

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Wyes Karny <wyes.karny@amd.com>
Tested-by: Perry Yuan <Perry.Yuan@amd.com>
Acked-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
tools/power/cpupower/utils/cpupower-set.c
tools/power/cpupower/utils/helpers/helpers.h
tools/power/cpupower/utils/helpers/misc.c

index 180d5ba877e6048c7176e95aac07c1acd3b9cd9f..a789b123dbd4077c1669edfc7964642ca595bd44 100644 (file)
@@ -18,6 +18,7 @@
 
 static struct option set_opts[] = {
        {"perf-bias", required_argument, NULL, 'b'},
+       {"epp", required_argument, NULL, 'e'},
        { },
 };
 
@@ -37,11 +38,13 @@ int cmd_set(int argc, char **argv)
        union {
                struct {
                        int perf_bias:1;
+                       int epp:1;
                };
                int params;
        } params;
        int perf_bias = 0;
        int ret = 0;
+       char epp[30];
 
        ret = uname(&uts);
        if (!ret && (!strcmp(uts.machine, "ppc64le") ||
@@ -55,7 +58,7 @@ int cmd_set(int argc, char **argv)
 
        params.params = 0;
        /* parameter parsing */
-       while ((ret = getopt_long(argc, argv, "b:",
+       while ((ret = getopt_long(argc, argv, "b:e:",
                                                set_opts, NULL)) != -1) {
                switch (ret) {
                case 'b':
@@ -69,6 +72,15 @@ int cmd_set(int argc, char **argv)
                        }
                        params.perf_bias = 1;
                        break;
+               case 'e':
+                       if (params.epp)
+                               print_wrong_arg_exit();
+                       if (sscanf(optarg, "%29s", epp) != 1) {
+                               print_wrong_arg_exit();
+                               return -EINVAL;
+                       }
+                       params.epp = 1;
+                       break;
                default:
                        print_wrong_arg_exit();
                }
@@ -102,6 +114,15 @@ int cmd_set(int argc, char **argv)
                                break;
                        }
                }
+
+               if (params.epp) {
+                       ret = cpupower_set_epp(cpu, epp);
+                       if (ret) {
+                               fprintf(stderr,
+                                       "Error setting epp value on CPU %d\n", cpu);
+                               break;
+                       }
+               }
        }
        return ret;
 }
index 96e4bede078b0aa01f06affcf75d5d21ba07f4b3..5d998de2d29165b84b6913ff0e68a84b0e3322f2 100644 (file)
@@ -116,6 +116,8 @@ extern int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val);
 extern int cpupower_intel_get_perf_bias(unsigned int cpu);
 extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
 
+extern int cpupower_set_epp(unsigned int cpu, char *epp);
+
 /* Read/Write msr ****************************/
 
 /* PCI stuff ****************************/
@@ -173,6 +175,9 @@ static inline int cpupower_intel_get_perf_bias(unsigned int cpu)
 static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
 { return 0; };
 
+static inline int cpupower_set_epp(unsigned int cpu, char *epp)
+{ return -1; };
+
 /* Read/Write msr ****************************/
 
 static inline int cpufreq_has_boost_support(unsigned int cpu, int *support,
index 0c56fc77f93b5ec491e1b5f7d8c6ddfac04f91ce..583df38ab13cba597f0b62757ab7f8c16b32154a 100644 (file)
@@ -87,6 +87,25 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
        return 0;
 }
 
+int cpupower_set_epp(unsigned int cpu, char *epp)
+{
+       char path[SYSFS_PATH_MAX];
+       char linebuf[30] = {};
+
+       snprintf(path, sizeof(path),
+               PATH_TO_CPU "cpu%u/cpufreq/energy_performance_preference", cpu);
+
+       if (!is_valid_path(path))
+               return -1;
+
+       snprintf(linebuf, sizeof(linebuf), "%s", epp);
+
+       if (cpupower_write_sysfs(path, linebuf, 30) <= 0)
+               return -1;
+
+       return 0;
+}
+
 bool cpupower_amd_pstate_enabled(void)
 {
        char *driver = cpufreq_get_driver(0);