summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/thermal
diff options
context:
space:
mode:
authorZeng Chi <zengchi@kylinos.cn>2026-09-21 18:24:42 +0800
committerSean Christopherson <seanjc@google.com>2026-09-22 08:36:16 -0700
commit119e9db233ad0f4cbd4cfb9f9385a7bca378b37d (patch)
tree660d50d4139cb750fbde1ae3432452c20726c99d /tools/testing/selftests/thermal
downloadlinux-stable-119e9db233ad0f4cbd4cfb9f9385a7bca378b37d.tar.gz
linux-stable-119e9db233ad0f4cbd4cfb9f9385a7bca378b37d.zip
KVM: Don't pre-reserve xarray entries when storing empty/NULL attributesgrafted
Skip the xarray reservation loop when clearing all memory attributes, as storing NULL only erases the entry and never needs to allocate, so no reservation (and no cleanup of a failed one) is required in that case. Suggested-by: Sean Christopherson <seanjc@google.com> Cc: David Ballesteros <davimaba.v@proton.me> Signed-off-by: Zeng Chi <zengchi@kylinos.cn> Link: https://patch.msgid.link/20260921102442.1232375-1-zeng_chi911@163.com [sean: split to separate patch] Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'tools/testing/selftests/thermal')
-rw-r--r--tools/testing/selftests/thermal/intel/power_floor/.gitignore1
-rw-r--r--tools/testing/selftests/thermal/intel/power_floor/Makefile12
-rw-r--r--tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c108
-rw-r--r--tools/testing/selftests/thermal/intel/workload_hint/.gitignore1
-rw-r--r--tools/testing/selftests/thermal/intel/workload_hint/Makefile12
-rw-r--r--tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c187
6 files changed, 321 insertions, 0 deletions
diff --git a/tools/testing/selftests/thermal/intel/power_floor/.gitignore b/tools/testing/selftests/thermal/intel/power_floor/.gitignore
new file mode 100644
index 000000000..1b9a76406
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/power_floor/.gitignore
@@ -0,0 +1 @@
+power_floor_test
diff --git a/tools/testing/selftests/thermal/intel/power_floor/Makefile b/tools/testing/selftests/thermal/intel/power_floor/Makefile
new file mode 100644
index 000000000..07463c216
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/power_floor/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+ifndef CROSS_COMPILE
+ARCH ?= $(shell uname -m 2>/dev/null || echo not)
+override ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+TEST_GEN_PROGS := power_floor_test
+
+include ../../../lib.mk
+
+endif
+endif
diff --git a/tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c b/tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c
new file mode 100644
index 000000000..30cab5d42
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+
+#define POWER_FLOOR_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/power_limits/power_floor_enable"
+#define POWER_FLOOR_STATUS_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/power_limits/power_floor_status"
+
+void power_floor_exit(int signum)
+{
+ int fd;
+
+ /* Disable feature via sysfs knob */
+
+ fd = open(POWER_FLOOR_ENABLE_ATTRIBUTE, O_RDWR);
+ if (fd < 0) {
+ perror("Unable to open power floor enable file\n");
+ exit(1);
+ }
+
+ if (write(fd, "0\n", 2) < 0) {
+ perror("Can' disable power floor notifications\n");
+ exit(1);
+ }
+
+ printf("Disabled power floor notifications\n");
+
+ close(fd);
+}
+
+int main(int argc, char **argv)
+{
+ struct pollfd ufd;
+ char status_str[3];
+ int fd, ret;
+
+ if (signal(SIGINT, power_floor_exit) == SIG_IGN)
+ signal(SIGINT, SIG_IGN);
+ if (signal(SIGHUP, power_floor_exit) == SIG_IGN)
+ signal(SIGHUP, SIG_IGN);
+ if (signal(SIGTERM, power_floor_exit) == SIG_IGN)
+ signal(SIGTERM, SIG_IGN);
+
+ /* Enable feature via sysfs knob */
+ fd = open(POWER_FLOOR_ENABLE_ATTRIBUTE, O_RDWR);
+ if (fd < 0) {
+ perror("Unable to open power floor enable file\n");
+ exit(1);
+ }
+
+ if (write(fd, "1\n", 2) < 0) {
+ perror("Can't enable power floor notifications\n");
+ exit(1);
+ }
+
+ close(fd);
+
+ printf("Enabled power floor notifications\n");
+
+ while (1) {
+ fd = open(POWER_FLOOR_STATUS_ATTRIBUTE, O_RDONLY);
+ if (fd < 0) {
+ perror("Unable to power floor status file\n");
+ exit(1);
+ }
+
+ if ((lseek(fd, 0L, SEEK_SET)) < 0) {
+ fprintf(stderr, "Failed to set pointer to beginning\n");
+ exit(1);
+ }
+
+ if (read(fd, status_str, sizeof(status_str)) < 0) {
+ fprintf(stderr, "Failed to read from:%s\n",
+ POWER_FLOOR_STATUS_ATTRIBUTE);
+ exit(1);
+ }
+
+ ufd.fd = fd;
+ ufd.events = POLLPRI;
+
+ ret = poll(&ufd, 1, -1);
+ if (ret < 0) {
+ perror("poll error");
+ exit(1);
+ } else if (ret == 0) {
+ printf("Poll Timeout\n");
+ } else {
+ if ((lseek(fd, 0L, SEEK_SET)) < 0) {
+ fprintf(stderr, "Failed to set pointer to beginning\n");
+ exit(1);
+ }
+
+ if (read(fd, status_str, sizeof(status_str)) < 0)
+ exit(0);
+
+ printf("power floor status: %s\n", status_str);
+ }
+
+ close(fd);
+ }
+}
diff --git a/tools/testing/selftests/thermal/intel/workload_hint/.gitignore b/tools/testing/selftests/thermal/intel/workload_hint/.gitignore
new file mode 100644
index 000000000..d697b034a
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/workload_hint/.gitignore
@@ -0,0 +1 @@
+workload_hint_test
diff --git a/tools/testing/selftests/thermal/intel/workload_hint/Makefile b/tools/testing/selftests/thermal/intel/workload_hint/Makefile
new file mode 100644
index 000000000..49e3bc2b2
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/workload_hint/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+ifndef CROSS_COMPILE
+ARCH ?= $(shell uname -m 2>/dev/null || echo not)
+override ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+TEST_GEN_PROGS := workload_hint_test
+
+include ../../../lib.mk
+
+endif
+endif
diff --git a/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c b/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c
new file mode 100644
index 000000000..569d44f22
--- /dev/null
+++ b/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+
+#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay_ms"
+#define WORKLOAD_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enable"
+#define WORKLOAD_SLOW_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_slow_hint_enable"
+#define WORKLOAD_TYPE_INDEX_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_index"
+
+static const char * const workload_types[] = {
+ "idle",
+ "battery_life",
+ "sustained",
+ "bursty",
+ NULL
+};
+
+static int wlt_slow;
+static char *wlt_enable_attr;
+
+#define WORKLOAD_TYPE_MAX_INDEX 3
+
+void workload_hint_exit(int signum)
+{
+ int fd;
+
+ /* Disable feature via sysfs knob */
+
+ fd = open(wlt_enable_attr, O_RDWR);
+ if (fd < 0) {
+ perror("Unable to open workload type feature enable file");
+ exit(1);
+ }
+
+ if (write(fd, "0\n", 2) < 0) {
+ perror("Can't disable workload hints");
+ exit(1);
+ }
+
+ printf("Disabled workload type prediction\n");
+
+ close(fd);
+}
+
+static void update_delay(char *delay_str)
+{
+ int fd;
+
+ printf("Setting notification delay in ms to %s\n", delay_str);
+
+ fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE, O_RDWR);
+ if (fd < 0) {
+ perror("Unable to open workload notification delay");
+ exit(1);
+ }
+
+ if (write(fd, delay_str, strlen(delay_str)) < 0) {
+ perror("Can't set delay");
+ exit(1);
+ }
+
+ close(fd);
+}
+
+int main(int argc, char **argv)
+{
+ struct pollfd ufd;
+ char index_str[4];
+ int fd, ret, index;
+ char delay_str[64];
+ int delay = 0;
+
+ printf("Usage: workload_hint_test [notification delay in milli seconds][slow]\n");
+
+ if (argc > 1) {
+ int i;
+
+ for (i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "slow")) {
+ wlt_slow = 1;
+ continue;
+ }
+
+ ret = sscanf(argv[1], "%d", &delay);
+ if (ret < 0) {
+ printf("Invalid delay\n");
+ exit(1);
+ }
+
+ sprintf(delay_str, "%s\n", argv[1]);
+ update_delay(delay_str);
+ }
+ }
+
+ if (signal(SIGINT, workload_hint_exit) == SIG_IGN)
+ signal(SIGINT, SIG_IGN);
+ if (signal(SIGHUP, workload_hint_exit) == SIG_IGN)
+ signal(SIGHUP, SIG_IGN);
+ if (signal(SIGTERM, workload_hint_exit) == SIG_IGN)
+ signal(SIGTERM, SIG_IGN);
+
+ if (wlt_slow)
+ wlt_enable_attr = WORKLOAD_SLOW_ENABLE_ATTRIBUTE;
+ else
+ wlt_enable_attr = WORKLOAD_ENABLE_ATTRIBUTE;
+
+ /* Enable feature via sysfs knob */
+ fd = open(wlt_enable_attr, O_RDWR);
+ if (fd < 0) {
+ perror("Unable to open workload type feature enable file");
+ exit(1);
+ }
+
+ if (write(fd, "1\n", 2) < 0) {
+ perror("Can't enable workload hints");
+ exit(1);
+ }
+
+ close(fd);
+
+ printf("Enabled workload type prediction\n");
+
+ while (1) {
+ fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE, O_RDONLY);
+ if (fd < 0) {
+ perror("Unable to open workload type file");
+ exit(1);
+ }
+
+ if ((lseek(fd, 0L, SEEK_SET)) < 0) {
+ fprintf(stderr, "Failed to set pointer to beginning\n");
+ exit(1);
+ }
+
+ if (read(fd, index_str, sizeof(index_str)) < 0) {
+ fprintf(stderr, "Failed to read from:%s\n",
+ WORKLOAD_TYPE_INDEX_ATTRIBUTE);
+ exit(1);
+ }
+
+ ufd.fd = fd;
+ ufd.events = POLLPRI;
+
+ ret = poll(&ufd, 1, -1);
+ if (ret < 0) {
+ perror("poll error");
+ exit(1);
+ } else if (ret == 0) {
+ printf("Poll Timeout\n");
+ } else {
+ if ((lseek(fd, 0L, SEEK_SET)) < 0) {
+ fprintf(stderr, "Failed to set pointer to beginning\n");
+ exit(1);
+ }
+
+ if (read(fd, index_str, sizeof(index_str)) < 0)
+ exit(0);
+
+ ret = sscanf(index_str, "%d", &index);
+ if (ret < 0)
+ break;
+
+ if (wlt_slow) {
+ if (index & 0x10)
+ printf("workload type slow:%s\n", "power");
+ else
+ printf("workload type slow:%s\n", "performance");
+ }
+
+ index &= 0x0f;
+ if (index > WORKLOAD_TYPE_MAX_INDEX)
+ printf("Invalid workload type index\n");
+ else
+ printf("workload type:%s\n", workload_types[index]);
+ }
+
+ close(fd);
+ }
+}