summaryrefslogtreecommitdiff
path: root/tools/power/x86/x86_energy_perf_policy
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 00:29:34 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 00:29:34 +0300
commit9c70f046787505127f2f8bb60ad24bb3c8bfc61a (patch)
tree46a6df4909b071db9a067309e726841ba7823505 /tools/power/x86/x86_energy_perf_policy
parentae1c1a8fd9c3f504b390df26b4af8ef6bfde005e (diff)
parentf77f420d34754b8d08ac6ebf094ff7193023196a (diff)
downloadlinux-9c70f046787505127f2f8bb60ad24bb3c8bfc61a.tar.xz
Merge tag 'x86_misc_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc x86 updates from Borislav Petkov: "The main part of this branch is the ongoing fight against windmills in an attempt to have userspace tools not poke at naked MSRs. This round deals with MSR_IA32_ENERGY_PERF_BIAS and removes direct poking into it by our in-tree tools in favor of the proper "energy_perf_bias" sysfs interface which we already have. In addition, the msr.ko write filtering's error message points to a new summary page which contains the info we collected from helpful reporters about which userspace tools write MSRs: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/about along with the current status of their conversion. The rest is the usual small fixes and improvements" * tag 'x86_misc_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/msr: Add a pointer to an URL which contains further details x86/pci: Fix the function type for check_reserved_t selftests/x86: Add missing .note.GNU-stack sections selftests/x86/fsgsbase: Fix GS == 1, 2, and 3 tests x86/msr: Downgrade unrecognized MSR message x86/msr: Do not allow writes to MSR_IA32_ENERGY_PERF_BIAS tools/power/x86_energy_perf_policy: Read energy_perf_bias from sysfs tools/power/turbostat: Read energy_perf_bias from sysfs tools/power/cpupower: Read energy_perf_bias from sysfs MAINTAINERS: Cleanup SGI-related entries
Diffstat (limited to 'tools/power/x86/x86_energy_perf_policy')
-rw-r--r--tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c109
1 files changed, 99 insertions, 10 deletions
diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
index ff6c6661f075..5fd9e594079c 100644
--- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
+++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
@@ -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:
*/
@@ -721,6 +724,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)
@@ -798,17 +843,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;
@@ -1091,15 +1180,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) {