tools/power/x86_energy_perf_policy: Read energy_perf_bias from sysfs
authorBorislav Petkov <bp@suse.de>
Thu, 15 Oct 2020 12:58:48 +0000 (14:58 +0200)
committerBorislav Petkov <bp@suse.de>
Mon, 16 Nov 2020 16:43:28 +0000 (17:43 +0100)
... and stop poking at the MSR directly.

Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20201029190259.3476-4-bp@alien8.de
tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c

index 3fe1eed..ad6aed1 100644 (file)
@@ -91,6 +91,9 @@ unsigned int has_hwp_request_pkg;     /* IA32_HWP_REQUEST_PKG */
 
 unsigned int bdx_highest_ratio;
 
+#define PATH_TO_CPU "/sys/devices/system/cpu/"
+#define SYSFS_PATH_MAX 255
+
 /*
  * maintain compatibility with original implementation, but don't document it:
  */
@@ -668,6 +671,48 @@ int put_msr(int cpu, int offset, unsigned long long new_msr)
        return 0;
 }
 
+static unsigned int read_sysfs(const char *path, char *buf, size_t buflen)
+{
+       ssize_t numread;
+       int fd;
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return 0;
+
+       numread = read(fd, buf, buflen - 1);
+       if (numread < 1) {
+               close(fd);
+               return 0;
+       }
+
+       buf[numread] = '\0';
+       close(fd);
+
+       return (unsigned int) numread;
+}
+
+static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
+{
+       ssize_t numwritten;
+       int fd;
+
+       fd = open(path, O_WRONLY);
+       if (fd == -1)
+               return 0;
+
+       numwritten = write(fd, buf, buflen - 1);
+       if (numwritten < 1) {
+               perror("write failed\n");
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+
+       return (unsigned int) numwritten;
+}
+
 void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
 {
        if (cpu != -1)
@@ -745,17 +790,61 @@ void write_hwp_request(int cpu, struct msr_hwp_request *hwp_req, unsigned int ms
        put_msr(cpu, msr_offset, msr);
 }
 
+static int get_epb(int cpu)
+{
+       char path[SYSFS_PATH_MAX];
+       char linebuf[3];
+       char *endp;
+       long val;
+
+       if (!has_epb)
+               return -1;
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu);
+
+       if (!read_sysfs(path, linebuf, 3))
+               return -1;
+
+       val = strtol(linebuf, &endp, 0);
+       if (endp == linebuf || errno == ERANGE)
+               return -1;
+
+       return (int)val;
+}
+
+static int set_epb(int cpu, int val)
+{
+       char path[SYSFS_PATH_MAX];
+       char linebuf[3];
+       char *endp;
+       int ret;
+
+       if (!has_epb)
+               return -1;
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu);
+       snprintf(linebuf, sizeof(linebuf), "%d", val);
+
+       ret = write_sysfs(path, linebuf, 3);
+       if (ret <= 0)
+               return -1;
+
+       val = strtol(linebuf, &endp, 0);
+       if (endp == linebuf || errno == ERANGE)
+               return -1;
+
+       return (int)val;
+}
+
 int print_cpu_msrs(int cpu)
 {
-       unsigned long long msr;
        struct msr_hwp_request req;
        struct msr_hwp_cap cap;
+       int epb;
 
-       if (has_epb) {
-               get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr);
-
-               printf("cpu%d: EPB %u\n", cpu, (unsigned int) msr);
-       }
+       epb = get_epb(cpu);
+       if (epb >= 0)
+               printf("cpu%d: EPB %u\n", cpu, (unsigned int) epb);
 
        if (!has_hwp)
                return 0;
@@ -1038,15 +1127,15 @@ int enable_hwp_on_cpu(int cpu)
 int update_cpu_msrs(int cpu)
 {
        unsigned long long msr;
-
+       int epb;
 
        if (update_epb) {
-               get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr);
-               put_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, new_epb);
+               epb = get_epb(cpu);
+               set_epb(cpu, new_epb);
 
                if (verbose)
                        printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n",
-                               cpu, (unsigned int) msr, (unsigned int) new_epb);
+                               cpu, epb, (unsigned int) new_epb);
        }
 
        if (update_turbo) {