public inbox for linux-pm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/13] Power Utilities update for Linux-7.1
@ 2026-04-25 18:42 Len Brown
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
  0 siblings, 1 reply; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

These patches update Linux with the latest turbostat
and x86_energy_perf_policy utilities.

tools/power x86_energy_perf_policy: v2026.04.25

	Since v2025.11.22:

	Initial SoC Slider support

tools/power turbostat: v2026.04.21

	Since v2026.02.14

	Display HT siblings in cpu# order.
	Add Module-ID column.
	Print Core-ID and APIC-ID in hex.
	Fix misc bugs.

Please let me know if you seen any troubles with them.

thanks!
Len Brown
Intel Open Source Technology Center

[PATCH 01/13] tools/power/x86: Add SOC slider and platform profile
[PATCH 02/13] tools/power turbostat: Fix AMD RAPL regression on big
[PATCH 03/13] tools/power turbostat: Fix unrecognized option '-P'
[PATCH 04/13] tools/power turbostat: Fix --cpu-set 0 regression on HT
[PATCH 05/13] tools/power turbostat: Fix --cpu-set 1 regression on HT
[PATCH 06/13] tools/power turbostat: Cleanup print helper functions
[PATCH 07/13] tools/power turbostat: Print core_id and apic_id in hex
[PATCH 08/13] tools/power turbostat: Show module_id column
[PATCH 09/13] tools/power turbostat: Process HT siblings in CPU order
[PATCH 10/13] tools/power turbostat: v2026.04.21
[PATCH 11/13] tools/power x86_energy_perf_policy: Enhances SoC Slider
[PATCH 12/13] tools/power x86_energy_perf_policy.8: Document SoC
[PATCH 13/13] tools/power x86_energy_perf_policy: Version 2026.04.25


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support
  2026-04-25 18:42 [PATCH 0/13] Power Utilities update for Linux-7.1 Len Brown
@ 2026-04-25 18:42 ` Len Brown
  2026-04-25 18:42   ` [PATCH 02/13] tools/power turbostat: Fix AMD RAPL regression on big systems Len Brown
                     ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>

Add support for reading and writing SOC slider parameters and
platform profile via sysfs in x86_energy_perf_policy.

New command-line options:
  --soc-slider-balance <value>
  --soc-slider-offset <value>
  --platform-profile <name>

These options allow control of the processor thermal SOC
slider balance and offset through the
processor_thermal_soc_slider module, as well as the
platform profile class interface.

When no update flags are set, the tool now also prints
the current SOC slider and platform profile values
alongside existing MSR output.

Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 .../x86_energy_perf_policy.c                  | 132 +++++++++++++++++-
 1 file changed, 130 insertions(+), 2 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 ac37132207a4..1f330c82d7c1 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
@@ -92,8 +92,18 @@ unsigned int has_hwp_request_pkg;	/* IA32_HWP_REQUEST_PKG */
 
 unsigned int bdx_highest_ratio;
 
+unsigned char update_soc_slider_balance;
+unsigned char update_soc_slider_offset;
+unsigned char update_platform_profile;
+int soc_slider_balance;
+int soc_slider_offset;
+char platform_profile[64];
+
 #define PATH_TO_CPU "/sys/devices/system/cpu/"
 #define SYSFS_PATH_MAX 255
+#define PATH_SOC_SLIDER_BALANCE "/sys/module/processor_thermal_soc_slider/parameters/slider_balance"
+#define PATH_SOC_SLIDER_OFFSET "/sys/module/processor_thermal_soc_slider/parameters/slider_offset"
+#define PATH_PLATFORM_PROFILE "/sys/class/platform-profile/platform-profile-0/profile"
 
 static int use_android_msr_path;
 
@@ -106,6 +116,7 @@ void usage(void)
 	fprintf(stderr, "scope: --cpu cpu-list [--hwp-use-pkg #] | --pkg pkg-list\n");
 	fprintf(stderr, "field: --all | --epb | --hwp-epp | --hwp-min | --hwp-max | --hwp-desired\n");
 	fprintf(stderr, "other: --hwp-enable | --turbo-enable (0 | 1) | --help | --force\n");
+	fprintf(stderr, "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>\n");
 	fprintf(stderr,
 		"value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
 	fprintf(stderr, "--hwp-window usec\n");
@@ -518,6 +529,23 @@ void for_packages(unsigned long long pkg_set, int (func)(int))
 	}
 }
 
+static int parse_cmdline_int(const char *s, int *out)
+{
+	char *endp;
+	long val;
+
+	val = strtol(s, &endp, 0);
+	if (endp == s || errno == ERANGE)
+		return -1;
+	if (*endp != '\0')
+		return -1;
+	if (val < INT_MIN || val > INT_MAX)
+		return -1;
+
+	*out = (int)val;
+	return 0;
+}
+
 void print_version(void)
 {
 	printf("x86_energy_perf_policy 2025.11.22 Len Brown <lenb@kernel.org>\n");
@@ -546,12 +574,15 @@ void cmdline(int argc, char **argv)
 		{"hwp-use-pkg",	required_argument,	0, 'u'},
 		{"version",	no_argument,		0, 'v'},
 		{"hwp-window",	required_argument,	0, 'w'},
+		{"soc-slider-balance", required_argument, 0, 'S'},
+		{"soc-slider-offset",  required_argument, 0, 'O'},
+		{"platform-profile",   required_argument, 0, 'F'},
 		{0,		0,			0, 0 }
 	};
 
 	progname = argv[0];
 
-	while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw:",
+	while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw::S:O:F:",
 				long_options, &option_index)) != -1) {
 		switch (opt) {
 		case 'a':
@@ -579,12 +610,23 @@ void cmdline(int argc, char **argv)
 		case 'D':
 			req_update.hwp_desired = parse_cmdline_hwp_desired(parse_optarg_string(optarg));
 			break;
+		case 'F':
+			if (strlen(optarg) >= sizeof(platform_profile))
+				errx(1, "--platform-profile: value too long");
+			strcpy(platform_profile, optarg);
+			update_platform_profile = 1;
+			break;
 		case 'm':
 			req_update.hwp_min = parse_cmdline_hwp_min(parse_optarg_string(optarg));
 			break;
 		case 'M':
 			req_update.hwp_max = parse_cmdline_hwp_max(parse_optarg_string(optarg));
 			break;
+		case 'O':
+			if (parse_cmdline_int(optarg, &soc_slider_offset))
+				errx(1, "--soc-slider-offset: invalid value");
+			update_soc_slider_offset = 1;
+			break;
 		case 'p':
 			parse_cmdline_pkg(optarg);
 			break;
@@ -594,6 +636,11 @@ void cmdline(int argc, char **argv)
 		case 'r':
 			/* v1 used -r to specify read-only mode, now the default */
 			break;
+		case 'S':
+			if (parse_cmdline_int(optarg, &soc_slider_balance))
+				errx(1, "--soc-slider-balance: invalid value");
+			update_soc_slider_balance = 1;
+			break;
 		case 't':
 			turbo_update_value = parse_cmdline_turbo(parse_optarg_string(optarg));
 			break;
@@ -777,6 +824,31 @@ static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
 	return (unsigned int) numwritten;
 }
 
+static int sysfs_read_string(const char *path, char *buf, size_t buflen)
+{
+	unsigned int len;
+	size_t n;
+
+	len = read_sysfs(path, buf, buflen);
+	if (!len)
+		return -1;
+
+	n = strcspn(buf, "\n");
+	buf[n] = '\0';
+	return 0;
+}
+
+static int sysfs_write_string(const char *path, const char *buf)
+{
+	char tmp[128];
+	int len;
+
+	len = snprintf(tmp, sizeof(tmp), "%s\n", buf);
+	if (len < 0 || len >= (int)sizeof(tmp))
+		return -1;
+	return write_sysfs(path, tmp, (size_t)len + 1) ? 0 : -1;
+}
+
 void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
 {
 	if (cpu != -1)
@@ -900,6 +972,55 @@ static int set_epb_sysfs(int cpu, int val)
 	return (int)val;
 }
 
+static int soc_slider_available(void)
+{
+	if (access(PATH_SOC_SLIDER_BALANCE, R_OK) &&
+			access(PATH_SOC_SLIDER_OFFSET, R_OK) &&
+			access(PATH_PLATFORM_PROFILE, R_OK))
+		return 0;
+
+	return 1;
+}
+
+static void print_soc_slider(void)
+{
+	char buf[64];
+
+	if (!soc_slider_available())
+		return;
+
+	if (sysfs_read_string(PATH_SOC_SLIDER_BALANCE, buf, sizeof(buf)) == 0)
+		printf("soc-slider-balance: %s\n", buf);
+	if (sysfs_read_string(PATH_SOC_SLIDER_OFFSET, buf, sizeof(buf)) == 0)
+		printf("soc-slider-offset: %s\n", buf);
+	if (sysfs_read_string(PATH_PLATFORM_PROFILE, buf, sizeof(buf)) == 0)
+		printf("platform-profile: %s\n", buf);
+}
+
+static int update_soc_slider(void)
+{
+	char tmp[32];
+
+	if (update_soc_slider_balance) {
+		snprintf(tmp, sizeof(tmp), "%d", soc_slider_balance);
+		if (sysfs_write_string(PATH_SOC_SLIDER_BALANCE, tmp))
+			err(1, "soc-slider-balance write failed");
+	}
+
+	if (update_soc_slider_offset) {
+		snprintf(tmp, sizeof(tmp), "%d", soc_slider_offset);
+		if (sysfs_write_string(PATH_SOC_SLIDER_OFFSET, tmp))
+			err(1, "soc-slider-offset write failed");
+	}
+
+	if (update_platform_profile) {
+		if (sysfs_write_string(PATH_PLATFORM_PROFILE, platform_profile))
+			err(1, "platform-profile write failed");
+	}
+
+	return 0;
+}
+
 int print_cpu_msrs(int cpu)
 {
 	struct msr_hwp_request req;
@@ -1604,10 +1725,14 @@ int main(int argc, char **argv)
 		return -EINVAL;
 
 	/* display information only, no updates to settings */
-	if (!update_epb && !update_turbo && !hwp_update_enabled()) {
+	if (!update_epb && !update_turbo && !hwp_update_enabled() &&
+	    !update_soc_slider_balance && !update_soc_slider_offset &&
+	    !update_platform_profile) {
 		if (cpu_selected_set)
 			for_all_cpus_in_set(cpu_setsize, cpu_selected_set, print_cpu_msrs);
 
+		print_soc_slider();
+
 		if (has_hwp_request_pkg) {
 			if (pkg_selected_set == 0)
 				pkg_selected_set = pkg_present_set;
@@ -1628,5 +1753,8 @@ int main(int argc, char **argv)
 	} else if (pkg_selected_set)
 		for_packages(pkg_selected_set, update_hwp_request_pkg_msr);
 
+	if (update_soc_slider_balance || update_soc_slider_offset || update_platform_profile)
+		update_soc_slider();
+
 	return 0;
 }
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/13] tools/power turbostat: Fix AMD RAPL regression on big systems
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 03/13] tools/power turbostat: Fix unrecognized option '-P' Len Brown
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

turbostat.c:8688: rapl_perf_init: Assertion `next_domain < num_domains' failed.

The initial fix for this regression was incomplete, as it did not
handle multi-package systems with sparse core ids.

Fixes: ef0e60083f76 ("tools/power turbostat: Fix AMD RAPL regression")
Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index e9e8ef72395a..bea574d7aa68 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -5155,7 +5155,7 @@ static inline int get_rapl_num_domains(void)
 	if (!platform->has_per_core_rapl)
 		return topo.num_packages;
 
-	return topo.num_cores;
+	return GLOBAL_CORE_ID(topo.max_core_id, topo.num_packages) + 1;
 }
 
 static inline int get_rapl_domain_id(int cpu)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/13] tools/power turbostat: Fix unrecognized option '-P'
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
  2026-04-25 18:42   ` [PATCH 02/13] tools/power turbostat: Fix AMD RAPL regression on big systems Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 04/13] tools/power turbostat: Fix --cpu-set 0 regression on HT systems Len Brown
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: David Arcari <darcari@redhat.com>

The '-P' short option (shorthand for --no-perf) is not present in the
optstring of the second call to getopt_long_only(). This results in
the "unrecognized option" error when the tool reaches the main parsing
loop.

Add 'P' to the second getopt_long_only() call to ensure it is
consistently recognized.

Fixes: a0e86c90b83c ("tools/power turbostat: Add --no-perf option")
Signed-off-by: David Arcari <darcari@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index bea574d7aa68..d6b4fd17c5f3 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -11449,7 +11449,7 @@ void cmdline(int argc, char **argv)
 	}
 	optind = 0;
 
-	while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMST:v", long_options, &option_index)) != -1) {
+	while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMPST:v", long_options, &option_index)) != -1) {
 		switch (opt) {
 		case 'a':
 			parse_add_command(optarg);
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/13] tools/power turbostat: Fix --cpu-set 0 regression on HT systems
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
  2026-04-25 18:42   ` [PATCH 02/13] tools/power turbostat: Fix AMD RAPL regression on big systems Len Brown
  2026-04-25 18:42   ` [PATCH 03/13] tools/power turbostat: Fix unrecognized option '-P' Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 05/13] tools/power turbostat: Fix --cpu-set 1 " Len Brown
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

"turbostat --cpu-set 0" appears to hang if cpu0 has an HT sibling.

This is because the initialization code recognizes that it does not
have to open perf files for the HT sibling, but the HT support
in the collection code sees the HT sibling and tries to read
from an uninitialized file descriptor, 0 (standard input).

Access HT siblings only when they are in the allowed set.

Fixes: a2b4d0f8bf07 ("tools/power turbostat: Favor cpu# over core#")
Signed-off-by: Len Brown <len.brown@intel.com>
Reported-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index d6b4fd17c5f3..7f61f07ceb31 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2427,11 +2427,17 @@ char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec";
 
 int cpu_is_not_present(int cpu)
 {
+	if (cpu < 0)
+		return 1;
+
 	return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
 }
 
 int cpu_is_not_allowed(int cpu)
 {
+	if (cpu < 0)
+		return 1;
+
 	return !CPU_ISSET_S(cpu, cpu_allowed_setsize, cpu_allowed_set);
 }
 
@@ -2473,9 +2479,12 @@ int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pk
 		int i;
 
 		for (i = MAX_HT_ID; i > 0; --i) {	/* ht_id 0 is self */
-			if (cpus[cpu].ht_sibling_cpu_id[i] <= 0)
+			int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
+
+			if (cpu_is_not_allowed(sibling_cpu_id))
 				continue;
-			t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]];
+
+			t = &thread_base[sibling_cpu_id];
 
 			retval |= func(t, c, p);
 		}
@@ -6252,10 +6261,13 @@ int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
 		int i;
 
 		for (i = MAX_HT_ID; i > 0; --i) {	/* ht_id 0 is self */
-			if (cpus[cpu].ht_sibling_cpu_id[i] <= 0)
+			int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
+
+			if (cpu_is_not_allowed(sibling_cpu_id))
 				continue;
-			t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]];
-			t2 = &thread_base2[cpus[cpu].ht_sibling_cpu_id[i]];
+
+			t = &thread_base[sibling_cpu_id];
+			t2 = &thread_base2[sibling_cpu_id];
 
 			retval |= func(t, c, p, t2, c2, p2);
 		}
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/13] tools/power turbostat: Fix --cpu-set 1 regression on HT systems
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (2 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 04/13] tools/power turbostat: Fix --cpu-set 0 regression on HT systems Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 06/13] tools/power turbostat: Cleanup print helper functions Len Brown
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

When the "--cpu-set" option limits turbostat to run on
a higher numbered HT sibling, it exits upon dividing by zero.

This is because the HT support handles higher numbered siblings
at the same time as lower numbered siblings.  But when that lower
number sibling is dis-allowed, the higher numbered sibling is
never processed.  The result is a time delta of 0, which results
in a divide by 0 for any of the "per-second" metrics.

Enhance the HT enumeration code to record all siblings (up to SMT4).
Consult this complete HT sibling list to determine when
to process an HT sibling, and when to skip it.

Fixes: a2b4d0f8bf07 ("tools/power turbostat: Favor cpu# over core#")
Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 70 +++++++++++++++++++++------
 1 file changed, 55 insertions(+), 15 deletions(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 7f61f07ceb31..e609272ed80b 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2449,6 +2449,22 @@ int cpu_is_not_allowed(int cpu)
 
 #define PER_THREAD_PARAMS  struct thread_data *t, struct core_data *c, struct pkg_data *p
 
+int has_allowed_lower_ht_sibling(int cpu)
+{
+	int i;
+
+	for (i = 0; i <= cpus[cpu].ht_id; ++i) {
+		int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
+
+		if (sibling_cpu_id == cpu)
+			return 0;
+
+		if (!cpu_is_not_allowed(sibling_cpu_id))
+			return 1;
+	}
+	return 0;
+}
+
 int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *),
 		 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
 {
@@ -2466,7 +2482,7 @@ int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pk
 		if (cpu_is_not_allowed(cpu))
 			continue;
 
-		if (cpus[cpu].ht_id > 0)	/* skip HT sibling */
+		if (has_allowed_lower_ht_sibling(cpu))	/* skip HT sibling */
 			continue;
 
 		t = &thread_base[cpu];
@@ -2475,12 +2491,18 @@ int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pk
 
 		retval |= func(t, c, p);
 
-		/* Handle HT sibling now */
+		/* Handle other HT siblings now */
 		int i;
 
-		for (i = MAX_HT_ID; i > 0; --i) {	/* ht_id 0 is self */
+		for (i = 0; i <= MAX_HT_ID; ++i) {
 			int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
 
+			if (sibling_cpu_id < 0)
+				break;
+
+			if (sibling_cpu_id == cpu)
+				continue;
+
 			if (cpu_is_not_allowed(sibling_cpu_id))
 				continue;
 
@@ -6178,11 +6200,11 @@ int set_thread_siblings(struct cpu_topology *thiscpu)
 	int cpu = thiscpu->cpu_id;
 	int offset = topo.max_cpu_num + 1;
 	size_t size;
-	int thread_id = 0;
+	int ht_id = 0;
 
 	thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
 	if (thiscpu->ht_id < 0)
-		thiscpu->ht_id = thread_id++;
+		thiscpu->ht_id = 0;	/* first CPU in core */
 	if (!thiscpu->put_ids)
 		return -1;
 
@@ -6206,13 +6228,9 @@ int set_thread_siblings(struct cpu_topology *thiscpu)
 				sib_core = get_core_id(so);
 				if (sib_core == thiscpu->core_id) {
 					CPU_SET_S(so, size, thiscpu->put_ids);
-					if ((so != cpu) && (cpus[so].ht_id < 0)) {
-						cpus[so].ht_id = thread_id;
-						cpus[cpu].ht_sibling_cpu_id[thread_id] = so;
-						if (debug)
-							fprintf(stderr, "%s: cpu%d.ht_sibling_cpu_id[%d] = %d\n", __func__, cpu, thread_id, so);
-						thread_id += 1;
-					}
+					cpus[so].ht_id = ht_id;
+					cpus[cpu].ht_sibling_cpu_id[ht_id] = so;
+					ht_id += 1;
 				}
 			}
 		}
@@ -6245,7 +6263,7 @@ int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
 		if (cpu_is_not_allowed(cpu))
 			continue;
 
-		if (cpus[cpu].ht_id > 0)	/* skip HT sibling */
+		if (has_allowed_lower_ht_sibling(cpu))	/* skip HT sibling */
 			continue;
 
 		t = &thread_base[cpu];
@@ -6260,9 +6278,15 @@ int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
 		/* Handle HT sibling now */
 		int i;
 
-		for (i = MAX_HT_ID; i > 0; --i) {	/* ht_id 0 is self */
+		for (i = 0; i <= MAX_HT_ID; ++i) {
 			int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
 
+			if (sibling_cpu_id < 0)
+				break;
+
+			if (sibling_cpu_id == cpu)
+				continue;
+
 			if (cpu_is_not_allowed(sibling_cpu_id))
 				continue;
 
@@ -9517,6 +9541,8 @@ void topology_probe(bool startup)
 	cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 	CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
 	for_all_proc_cpus(mark_cpu_present);
+	if (debug)
+		print_cpu_set("present set", cpu_present_set);
 
 	/*
 	 * Allocate and initialize cpu_possible_set
@@ -9527,6 +9553,8 @@ void topology_probe(bool startup)
 	cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 	CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
 	initialize_cpu_set_from_sysfs(cpu_possible_set, "/sys/devices/system/cpu", "possible");
+	if (debug)
+		print_cpu_set("possible set", cpu_possible_set);
 
 	/*
 	 * Allocate and initialize cpu_effective_set
@@ -9537,6 +9565,8 @@ void topology_probe(bool startup)
 	cpu_effective_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
 	CPU_ZERO_S(cpu_effective_setsize, cpu_effective_set);
 	update_effective_set(startup);
+	if (debug)
+		print_cpu_set("effective set", cpu_effective_set);
 
 	/*
 	 * Allocate and initialize cpu_allowed_set
@@ -9580,6 +9610,8 @@ void topology_probe(bool startup)
 
 		CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set);
 	}
+	if (debug)
+		print_cpu_set("allowed set", cpu_allowed_set);
 
 	if (!CPU_COUNT_S(cpu_allowed_setsize, cpu_allowed_set))
 		err(-ENODEV, "No valid cpus found");
@@ -9683,12 +9715,18 @@ void topology_probe(bool startup)
 		return;
 
 	for (i = 0; i <= topo.max_cpu_num; ++i) {
+		int ht_id;
+
 		if (cpu_is_not_present(i))
 			continue;
 		fprintf(outf,
-			"cpu %d pkg %d die %d l3 %d node %d lnode %d core %d thread %d\n",
+			"cpu %d pkg %d die %d l3 %d node %d lnode %d core %d ht_id %d",
 			i, cpus[i].package_id, cpus[i].die_id, cpus[i].l3_id,
 			cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].core_id, cpus[i].ht_id);
+		fprintf(outf, " siblings");
+		for (ht_id = 0; ht_id <= MAX_HT_ID; ++ht_id)
+			fprintf(outf, " %d", cpus[i].ht_sibling_cpu_id[ht_id]);
+		fprintf(outf, "\n");
 	}
 
 }
@@ -9829,6 +9867,8 @@ void topology_update(void)
 	topo.allowed_cores = 0;
 	topo.allowed_packages = 0;
 	for_all_cpus(update_topo, ODD_COUNTERS);
+	if (debug)
+		fprintf(stderr, "allowed_cpus %d allowed_cores %d allowed_packages %d\n", topo.allowed_cpus, topo.allowed_cores, topo.allowed_packages);
 }
 
 void setup_all_buffers(bool startup)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/13] tools/power turbostat: Cleanup print helper functions
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (3 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 05/13] tools/power turbostat: Fix --cpu-set 1 " Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 07/13] tools/power turbostat: Print core_id and apic_id in hex Len Brown
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>

Make printer helper functions more readable by factoring
out a local 'sep' variable.

Remove the redundant parentheses around sprintf() calls.

Remove an unnecessary cast to "unsigned int" by using the '%08llx' instead
   of '%08x'.

No functional changes.

[lenb: fix typos, simplify]
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index e609272ed80b..624f54ee1ad8 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2866,31 +2866,38 @@ void bic_lookup(cpu_set_t *ret_set, char *name_list, enum show_hide_mode mode)
 static inline int print_name(int width, int *printed, char *delim, char *name, enum counter_type type, enum counter_format format)
 {
 	UNUSED(type);
+	char *sep = (*printed)++ ? delim : "";
 
 	if (format == FORMAT_RAW && width >= 64)
-		return (sprintf(outp, "%s%-8s", ((*printed)++ ? delim : ""), name));
+		return sprintf(outp, "%s%-8s", sep, name);
 	else
-		return (sprintf(outp, "%s%s", ((*printed)++ ? delim : ""), name));
+		return sprintf(outp, "%s%s", sep, name);
 }
 
 static inline int print_hex_value(int width, int *printed, char *delim, unsigned long long value)
 {
+	char *sep = (*printed)++ ? delim : "";
+
 	if (width <= 32)
-		return (sprintf(outp, "%s%08x", ((*printed)++ ? delim : ""), (unsigned int)value));
+		return sprintf(outp, "%s%08llx", sep, value);
 	else
-		return (sprintf(outp, "%s%016llx", ((*printed)++ ? delim : ""), value));
+		return sprintf(outp, "%s%016llx", sep, value);
 }
 
 static inline int print_decimal_value(int width, int *printed, char *delim, unsigned long long value)
 {
+	char *sep = (*printed)++ ? delim : "";
+
 	UNUSED(width);
 
-	return (sprintf(outp, "%s%lld", ((*printed)++ ? delim : ""), value));
+	return sprintf(outp, "%s%lld", sep, value);
 }
 
 static inline int print_float_value(int *printed, char *delim, double value)
 {
-	return (sprintf(outp, "%s%0.2f", ((*printed)++ ? delim : ""), value));
+	char *sep = (*printed)++ ? delim : "";
+
+	return sprintf(outp, "%s%0.2f", sep, value);
 }
 
 void print_header(char *delim)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/13] tools/power turbostat: Print core_id and apic_id in hex
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (4 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 06/13] tools/power turbostat: Cleanup print helper functions Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 08/13] tools/power turbostat: Show module_id column Len Brown
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

The core_id is based on a mask of the apic_id.
Print them both in hex, rather than decimal,
to make this relationship visibly clear.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 624f54ee1ad8..b27227414dc7 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -3214,7 +3214,7 @@ int dump_counters(PER_THREAD_PARAMS)
 	}
 
 	if (c && is_cpu_first_thread_in_core(t, c)) {
-		outp += sprintf(outp, "core: %d\n", cpus[t->cpu_id].core_id);
+		outp += sprintf(outp, "core: 0x%x\n", cpus[t->cpu_id].core_id);
 		outp += sprintf(outp, "c3: %016llX\n", c->c3);
 		outp += sprintf(outp, "c6: %016llX\n", c->c6);
 		outp += sprintf(outp, "c7: %016llX\n", c->c7);
@@ -3423,16 +3423,16 @@ int format_counters(PER_THREAD_PARAMS)
 		}
 		if (DO_BIC(BIC_Core)) {
 			if (c)
-				outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].core_id);
+				outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].core_id);
 			else
 				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 		}
 		if (DO_BIC(BIC_CPU))
 			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
 		if (DO_BIC(BIC_APIC))
-			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id);
+			outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), t->apic_id);
 		if (DO_BIC(BIC_X2APIC))
-			outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id);
+			outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), t->x2apic_id);
 	}
 
 	if (DO_BIC(BIC_Avg_MHz))
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/13] tools/power turbostat: Show module_id column
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (5 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 07/13] tools/power turbostat: Print core_id and apic_id in hex Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 09/13] tools/power turbostat: Process HT siblings in CPU order Len Brown
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

Get the "module_id" from the Linux topology "cluster_id".
If the there is more than one id, show it by default.

Module joins Die etc. in the "topology" group.

Display in hex, as it is usually based mask of the APIC-id

Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 38 +++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index b27227414dc7..f8e9aa8c9e54 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -191,6 +191,7 @@ struct msr_counter bic[] = {
 	{ 0x0, "Any%C0", NULL, 0, 0, 0, NULL, 0 },
 	{ 0x0, "GFX%C0", NULL, 0, 0, 0, NULL, 0 },
 	{ 0x0, "CPUGFX%", NULL, 0, 0, 0, NULL, 0 },
+	{ 0x0, "Module", NULL, 0, 0, 0, NULL, 0 },
 	{ 0x0, "Core", NULL, 0, 0, 0, NULL, 0 },
 	{ 0x0, "CPU", NULL, 0, 0, 0, NULL, 0 },
 	{ 0x0, "APIC", NULL, 0, 0, 0, NULL, 0 },
@@ -264,6 +265,7 @@ enum bic_names {
 	BIC_Any_c0,
 	BIC_GFX_c0,
 	BIC_CPUGFX,
+	BIC_Module,
 	BIC_Core,
 	BIC_CPU,
 	BIC_APIC,
@@ -364,6 +366,7 @@ static void bic_groups_init(void)
 	SET_BIC(BIC_Node, &bic_group_topology);
 	SET_BIC(BIC_CoreCnt, &bic_group_topology);
 	SET_BIC(BIC_PkgCnt, &bic_group_topology);
+	SET_BIC(BIC_Module, &bic_group_topology);
 	SET_BIC(BIC_Core, &bic_group_topology);
 	SET_BIC(BIC_CPU, &bic_group_topology);
 	SET_BIC(BIC_Die, &bic_group_topology);
@@ -2383,6 +2386,7 @@ struct platform_counters {
 struct cpu_topology {
 	int cpu_id;
 	int core_id;		/* unique within a package */
+	int module_id;
 	int package_id;
 	int die_id;
 	int l3_id;
@@ -2404,6 +2408,8 @@ struct topo_params {
 	int allowed_cores;
 	int max_cpu_num;
 	int max_core_id;	/* within a package */
+	int min_module_id;	/* system wide */
+	int max_module_id;	/* system wide */
 	int max_package_id;
 	int max_die_id;
 	int max_l3_id;
@@ -2919,6 +2925,8 @@ void print_header(char *delim)
 		outp += sprintf(outp, "%sL3", (printed++ ? delim : ""));
 	if (DO_BIC(BIC_Node))
 		outp += sprintf(outp, "%sNode", (printed++ ? delim : ""));
+	if (DO_BIC(BIC_Module))
+		outp += sprintf(outp, "%sModule", (printed++ ? delim : ""));
 	if (DO_BIC(BIC_Core))
 		outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
 	if (DO_BIC(BIC_CPU))
@@ -3388,6 +3396,8 @@ int format_counters(PER_THREAD_PARAMS)
 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 		if (DO_BIC(BIC_Node))
 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
+		if (DO_BIC(BIC_Module))
+			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 		if (DO_BIC(BIC_Core))
 			outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 		if (DO_BIC(BIC_CPU))
@@ -3421,6 +3431,12 @@ int format_counters(PER_THREAD_PARAMS)
 			else
 				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
 		}
+		if (DO_BIC(BIC_Module)) {
+			if (c)
+				outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].module_id);
+			else
+				outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
+		}
 		if (DO_BIC(BIC_Core)) {
 			if (c)
 				outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].core_id);
@@ -6079,6 +6095,11 @@ int get_l3_id(int cpu)
 	return parse_int_file("/sys/devices/system/cpu/cpu%d/cache/index3/id", cpu);
 }
 
+int get_module_id(int cpu)
+{
+	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/cluster_id", cpu);
+}
+
 int get_core_id(int cpu)
 {
 	return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
@@ -9641,6 +9662,7 @@ void topology_probe(bool startup)
 	 * For online cpus
 	 * find max_core_id, max_package_id, num_cores (per system)
 	 */
+	topo.min_module_id = 0x7FFFFFFF;
 	for (i = 0; i <= topo.max_cpu_num; ++i) {
 		int siblings;
 
@@ -9672,6 +9694,13 @@ void topology_probe(bool startup)
 		if (cpus[i].physical_node_id > topo.max_node_num)
 			topo.max_node_num = cpus[i].physical_node_id;
 
+		/* get module information */
+		cpus[i].module_id = get_module_id(i);
+		if (cpus[i].module_id > topo.max_module_id)
+			topo.max_module_id = cpus[i].module_id;
+		if (cpus[i].module_id < topo.min_module_id)
+			topo.min_module_id = cpus[i].module_id;
+
 		/* get core information */
 		cpus[i].core_id = get_core_id(i);
 		if (cpus[i].core_id > max_core_id)
@@ -9693,6 +9722,11 @@ void topology_probe(bool startup)
 	if (!summary_only)
 		BIC_PRESENT(BIC_Core);
 
+	if (debug > 1)
+		fprintf(outf, "min_module_id %d max_module_id %d\n", topo.min_module_id, topo.max_module_id);
+	if (!summary_only && (topo.min_module_id != topo.max_module_id))
+		BIC_PRESENT(BIC_Module);
+
 	topo.num_die = topo.max_die_id + 1;
 	if (debug > 1)
 		fprintf(outf, "max_die_id %d, sizing for %d die\n", topo.max_die_id, topo.num_die);
@@ -9727,9 +9761,9 @@ void topology_probe(bool startup)
 		if (cpu_is_not_present(i))
 			continue;
 		fprintf(outf,
-			"cpu %d pkg %d die %d l3 %d node %d lnode %d core %d ht_id %d",
+			"cpu %d pkg %d die %d l3 %d node %d lnode %d module 0x%x core %d ht_id %d",
 			i, cpus[i].package_id, cpus[i].die_id, cpus[i].l3_id,
-			cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].core_id, cpus[i].ht_id);
+			cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].module_id, cpus[i].core_id, cpus[i].ht_id);
 		fprintf(outf, " siblings");
 		for (ht_id = 0; ht_id <= MAX_HT_ID; ++ht_id)
 			fprintf(outf, " %d", cpus[i].ht_sibling_cpu_id[ht_id]);
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/13] tools/power turbostat: Process HT siblings in CPU order
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (6 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 08/13] tools/power turbostat: Show module_id column Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 10/13] tools/power turbostat: v2026.04.21 Len Brown
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

On large systems with HT sibling cpu#'s more than 32 apart,
HT siblings were processed and displayed in reverse order.

This was due to how set_thread_siblings() parsed the
sibling-bit-mask.

Update set_thread_siblings to instead parse the sibling-list,
like other cpu lists, and to thus order HT siblings
by ascending CPU number, no matter the size of the system.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 80 +++++++++++----------------
 1 file changed, 31 insertions(+), 49 deletions(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index f8e9aa8c9e54..d46878c63a80 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -6219,55 +6219,6 @@ static int parse_cpu_str(char *cpu_str, cpu_set_t *cpu_set, int cpu_set_size)
 	return 0;
 }
 
-int set_thread_siblings(struct cpu_topology *thiscpu)
-{
-	char path[80], character;
-	FILE *filep;
-	unsigned long map;
-	int so, shift, sib_core;
-	int cpu = thiscpu->cpu_id;
-	int offset = topo.max_cpu_num + 1;
-	size_t size;
-	int ht_id = 0;
-
-	thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
-	if (thiscpu->ht_id < 0)
-		thiscpu->ht_id = 0;	/* first CPU in core */
-	if (!thiscpu->put_ids)
-		return -1;
-
-	size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
-	CPU_ZERO_S(size, thiscpu->put_ids);
-
-	sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
-	filep = fopen(path, "r");
-
-	if (!filep) {
-		warnx("%s: open failed", path);
-		return -1;
-	}
-	do {
-		offset -= BITMASK_SIZE;
-		if (fscanf(filep, "%lx%c", &map, &character) != 2)
-			err(1, "%s: failed to parse file", path);
-		for (shift = 0; shift < BITMASK_SIZE; shift++) {
-			if ((map >> shift) & 0x1) {
-				so = shift + offset;
-				sib_core = get_core_id(so);
-				if (sib_core == thiscpu->core_id) {
-					CPU_SET_S(so, size, thiscpu->put_ids);
-					cpus[so].ht_id = ht_id;
-					cpus[cpu].ht_sibling_cpu_id[ht_id] = so;
-					ht_id += 1;
-				}
-			}
-		}
-	} while (character == ',');
-	fclose(filep);
-
-	return CPU_COUNT_S(size, thiscpu->put_ids);
-}
-
 /*
  * run func(thread, core, package) in topology order
  * skip non-present cpus
@@ -9539,6 +9490,37 @@ int dir_filter(const struct dirent *dirp)
 		return 0;
 }
 
+int set_thread_siblings(struct cpu_topology *thiscpu)
+{
+	char path[80];
+	int cpu = thiscpu->cpu_id;
+	size_t size;
+	int ht_id = 0;
+	int i;
+
+	thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
+	if (thiscpu->ht_id < 0)
+		thiscpu->ht_id = 0;	/* first CPU in core */
+	if (!thiscpu->put_ids)
+		return -1;
+
+	size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
+	CPU_ZERO_S(size, thiscpu->put_ids);
+
+	sprintf(path, "/sys/devices/system/cpu/cpu%d/topology", cpu);
+
+	initialize_cpu_set_from_sysfs(thiscpu->put_ids, path, "thread_siblings_list");
+
+	for (i = 0; i <= topo.max_cpu_num; ++i)
+		if (CPU_ISSET_S(i, size, thiscpu->put_ids)) {
+			cpus[i].ht_id = ht_id;
+			cpus[cpu].ht_sibling_cpu_id[ht_id] = i;
+			ht_id += 1;
+		}
+
+	return (ht_id - 1);
+}
+
 void topology_probe(bool startup)
 {
 	int i;
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/13] tools/power turbostat: v2026.04.21
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (7 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 09/13] tools/power turbostat: Process HT siblings in CPU order Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 11/13] tools/power x86_energy_perf_policy: Enhances SoC Slider related checks Len Brown
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

Since v2026.02.14

Display HT siblings in cpu# order.
Add Module-ID column.
Print Core-ID and APIC-ID in hex.
Fix misc bugs.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 tools/power/x86/turbostat/turbostat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index d46878c63a80..920694c3c1ec 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -10608,7 +10608,7 @@ int get_and_dump_counters(void)
 
 void print_version()
 {
-	fprintf(outf, "turbostat version 2026.02.14 - Len Brown <lenb@kernel.org>\n");
+	fprintf(outf, "turbostat version 2026.04.21 - Len Brown <lenb@kernel.org>\n");
 }
 
 #define COMMAND_LINE_SIZE 2048
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/13] tools/power x86_energy_perf_policy: Enhances SoC Slider related checks
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (8 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 10/13] tools/power turbostat: v2026.04.21 Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 12/13] tools/power x86_energy_perf_policy.8: Document SoC Slider Options Len Brown
  2026-04-25 18:42   ` [PATCH 13/13] tools/power x86_energy_perf_policy: Version 2026.04.25 Len Brown
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

When processor_thermal_soc_slider is loaded, its slider
and offset modparams are visible.  Check that the driver
actually registered the profile named "SoC Slider" before
reading or writing these modparams.

n.b. This utility allows writing the Slider and Offset modparams
even if the driver policy is not "balanced".  Currently the
processor_thermal_soc_slider consults those modparams
only in "balanced" mode.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 .../x86_energy_perf_policy.c                  | 142 +++++++++++++-----
 1 file changed, 104 insertions(+), 38 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 1f330c82d7c1..83e5adbcda69 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
@@ -104,9 +104,14 @@ char platform_profile[64];
 #define PATH_SOC_SLIDER_BALANCE "/sys/module/processor_thermal_soc_slider/parameters/slider_balance"
 #define PATH_SOC_SLIDER_OFFSET "/sys/module/processor_thermal_soc_slider/parameters/slider_offset"
 #define PATH_PLATFORM_PROFILE "/sys/class/platform-profile/platform-profile-0/profile"
+#define PATH_PLATFORM_PROFILE_NAME "/sys/class/platform-profile/platform-profile-0/name"
+#define POWER_SLIDER_NAME "SoC Power Slider"
 
 static int use_android_msr_path;
 
+static unsigned int read_sysfs(const char *, char *, size_t);
+static int sysfs_read_string(const char *, char *, size_t);
+
 /*
  * maintain compatibility with original implementation, but don't document it:
  */
@@ -551,39 +556,91 @@ void print_version(void)
 	printf("x86_energy_perf_policy 2025.11.22 Len Brown <lenb@kernel.org>\n");
 }
 
+static int platform_profile_access(int mode)
+{
+	if (access(PATH_PLATFORM_PROFILE, mode)) {
+		if (debug)
+			fprintf(stderr, "Can not access %s\n", PATH_PLATFORM_PROFILE);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int platform_profile_name_is(char *name)
+{
+	char buf[64];
+
+	if (sysfs_read_string(PATH_PLATFORM_PROFILE_NAME, buf, sizeof(buf)) != 0) {
+		if (debug)
+			fprintf(stderr, "Can not read %s\n", PATH_PLATFORM_PROFILE_NAME);
+		return 0;
+	}
+
+	if (strncmp(buf, name, 16)) {
+		if (debug)
+			fprintf(stderr, "%s does not match '%s'\n", PATH_PLATFORM_PROFILE_NAME, name);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int soc_slider_access(int mode)
+{
+	if (!platform_profile_access(R_OK))
+		return 0;
+
+	if (!platform_profile_name_is(POWER_SLIDER_NAME))
+		return 0;
+
+	if (access(PATH_SOC_SLIDER_BALANCE, mode)) {
+		if (debug)
+			fprintf(stderr, "Can not access %s\n", PATH_SOC_SLIDER_BALANCE);
+		return 0;
+	}
+
+	if (access(PATH_SOC_SLIDER_OFFSET, mode)) {
+		if (debug)
+			fprintf(stderr, "Can not access %s\n", PATH_SOC_SLIDER_OFFSET);
+		return 0;
+	}
+
+	return 1;
+}
+
 void cmdline(int argc, char **argv)
 {
 	int opt;
 	int option_index = 0;
 
 	static struct option long_options[] = {
-		{"all",		required_argument,	0, 'a'},
-		{"cpu",		required_argument,	0, 'c'},
-		{"pkg",		required_argument,	0, 'p'},
-		{"debug",	no_argument,		0, 'd'},
-		{"hwp-desired",	required_argument,	0, 'D'},
-		{"epb",	required_argument,	0, 'B'},
-		{"force",	no_argument,	0, 'f'},
-		{"hwp-enable",	no_argument,	0, 'e'},
-		{"help",	no_argument,	0, 'h'},
-		{"hwp-epp",	required_argument,	0, 'P'},
-		{"hwp-min",	required_argument,	0, 'm'},
-		{"hwp-max",	required_argument,	0, 'M'},
-		{"read",	no_argument,		0, 'r'},
-		{"turbo-enable",	required_argument,	0, 't'},
-		{"hwp-use-pkg",	required_argument,	0, 'u'},
-		{"version",	no_argument,		0, 'v'},
-		{"hwp-window",	required_argument,	0, 'w'},
-		{"soc-slider-balance", required_argument, 0, 'S'},
-		{"soc-slider-offset",  required_argument, 0, 'O'},
-		{"platform-profile",   required_argument, 0, 'F'},
-		{0,		0,			0, 0 }
+		{ "all", required_argument, 0, 'a' },
+		{ "cpu", required_argument, 0, 'c' },
+		{ "pkg", required_argument, 0, 'p' },
+		{ "debug", no_argument, 0, 'd' },
+		{ "hwp-desired", required_argument, 0, 'D' },
+		{ "epb", required_argument, 0, 'B' },
+		{ "force", no_argument, 0, 'f' },
+		{ "hwp-enable", no_argument, 0, 'e' },
+		{ "help", no_argument, 0, 'h' },
+		{ "hwp-epp", required_argument, 0, 'P' },
+		{ "hwp-min", required_argument, 0, 'm' },
+		{ "hwp-max", required_argument, 0, 'M' },
+		{ "read", no_argument, 0, 'r' },
+		{ "turbo-enable", required_argument, 0, 't' },
+		{ "hwp-use-pkg", required_argument, 0, 'u' },
+		{ "version", no_argument, 0, 'v' },
+		{ "hwp-window", required_argument, 0, 'w' },
+		{ "soc-slider-balance", required_argument, 0, 'S' },
+		{ "soc-slider-offset", required_argument, 0, 'O' },
+		{ "platform-profile", required_argument, 0, 'F' },
+		{ 0, 0, 0, 0 }
 	};
 
 	progname = argv[0];
 
-	while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw::S:O:F:",
-				long_options, &option_index)) != -1) {
+	while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw::S:O:F:", long_options, &option_index)) != -1) {
 		switch (opt) {
 		case 'a':
 			parse_cmdline_all(optarg);
@@ -613,6 +670,8 @@ void cmdline(int argc, char **argv)
 		case 'F':
 			if (strlen(optarg) >= sizeof(platform_profile))
 				errx(1, "--platform-profile: value too long");
+			if (!platform_profile_access(W_OK))
+				errx(1, "Can not update platform-profile in '%s'", PATH_PLATFORM_PROFILE);
 			strcpy(platform_profile, optarg);
 			update_platform_profile = 1;
 			break;
@@ -625,6 +684,8 @@ void cmdline(int argc, char **argv)
 		case 'O':
 			if (parse_cmdline_int(optarg, &soc_slider_offset))
 				errx(1, "--soc-slider-offset: invalid value");
+			if (!soc_slider_access(W_OK))
+				errx(1, "Unable to write SOC Slider Offset");
 			update_soc_slider_offset = 1;
 			break;
 		case 'p':
@@ -639,6 +700,8 @@ void cmdline(int argc, char **argv)
 		case 'S':
 			if (parse_cmdline_int(optarg, &soc_slider_balance))
 				errx(1, "--soc-slider-balance: invalid value");
+			if (!soc_slider_access(W_OK))
+				errx(1, "Unable to write SOC Slider-Balance in '%s'", PATH_SOC_SLIDER_BALANCE);
 			update_soc_slider_balance = 1;
 			break;
 		case 't':
@@ -814,7 +877,8 @@ static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
 
 	numwritten = write(fd, buf, buflen - 1);
 	if (numwritten < 1) {
-		perror("write failed\n");
+		buf[strcspn(buf, "\n")] = '\0';
+		warn("Write '%s' to '%s' failed", buf, path);
 		close(fd);
 		return -1;
 	}
@@ -972,27 +1036,30 @@ static int set_epb_sysfs(int cpu, int val)
 	return (int)val;
 }
 
-static int soc_slider_available(void)
-{
-	if (access(PATH_SOC_SLIDER_BALANCE, R_OK) &&
-			access(PATH_SOC_SLIDER_OFFSET, R_OK) &&
-			access(PATH_PLATFORM_PROFILE, R_OK))
-		return 0;
-
-	return 1;
-}
-
 static void print_soc_slider(void)
 {
 	char buf[64];
 
-	if (!soc_slider_available())
+	if (!soc_slider_access(R_OK))
 		return;
 
 	if (sysfs_read_string(PATH_SOC_SLIDER_BALANCE, buf, sizeof(buf)) == 0)
 		printf("soc-slider-balance: %s\n", buf);
+
 	if (sysfs_read_string(PATH_SOC_SLIDER_OFFSET, buf, sizeof(buf)) == 0)
 		printf("soc-slider-offset: %s\n", buf);
+}
+
+static void print_platform_profile(void)
+{
+	char buf[64];
+
+	if (!platform_profile_access(R_OK))
+		return;
+
+	if (sysfs_read_string(PATH_PLATFORM_PROFILE_NAME, buf, sizeof(buf)) == 0)
+		printf("platform-profile-name: %s\n", buf);
+
 	if (sysfs_read_string(PATH_PLATFORM_PROFILE, buf, sizeof(buf)) == 0)
 		printf("platform-profile: %s\n", buf);
 }
@@ -1725,13 +1792,12 @@ int main(int argc, char **argv)
 		return -EINVAL;
 
 	/* display information only, no updates to settings */
-	if (!update_epb && !update_turbo && !hwp_update_enabled() &&
-	    !update_soc_slider_balance && !update_soc_slider_offset &&
-	    !update_platform_profile) {
+	if (!update_epb && !update_turbo && !hwp_update_enabled() && !update_soc_slider_balance && !update_soc_slider_offset && !update_platform_profile) {
 		if (cpu_selected_set)
 			for_all_cpus_in_set(cpu_setsize, cpu_selected_set, print_cpu_msrs);
 
 		print_soc_slider();
+		print_platform_profile();
 
 		if (has_hwp_request_pkg) {
 			if (pkg_selected_set == 0)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 12/13] tools/power x86_energy_perf_policy.8: Document SoC Slider Options
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (9 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 11/13] tools/power x86_energy_perf_policy: Enhances SoC Slider related checks Len Brown
@ 2026-04-25 18:42   ` Len Brown
  2026-04-25 18:42   ` [PATCH 13/13] tools/power x86_energy_perf_policy: Version 2026.04.25 Len Brown
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

x86_energy_perf_policy accesses the SoC Slider via standard
user/kernel APIs to the processor_thermal_soc_slider driver.

Machines that support SoC Slider largely use it instead of EPP,
which may continue to exist in a diminished role, or vanish entirely.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 .../x86_energy_perf_policy.8                  | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
index 0aa981c18e56..836553e9a92c 100644
--- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
+++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
@@ -15,6 +15,8 @@ x86_energy_perf_policy \- Manage Energy vs. Performance Policy
 .br
 .RB "other: (\-\-force | \-\-hwp-enable | \-\-turbo-enable)  value)"
 .br
+.RB "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>"
+.br
 .RB "value: # | default | performance | balance-performance | balance-power | power"
 .SH DESCRIPTION
 \fBx86_energy_perf_policy\fP
@@ -154,6 +156,26 @@ level on this processor, specified in multiples of 100 MHz.
 in the sliding window that HWP uses to maintain average frequency.
 This parameter is meaningful only when the "desired" field above is non-zero.
 Default is 0, allowing the HW to choose.
+.SH SOC SLIDER OPTIONS
+.PP
+Note that the Platform Profile Name must be "SoC Slider", and the
+Platform Profile must be "balanced" for the --soc-slider-balance
+and --soc-slider-offset options to take effect.
+.PP
+\fB--soc-slider-balance #\fP write numeric value to the SoC Slider.
+Values range from 0 to 6.
+Lower values result in higher performance,
+and higher values improve energy efficiency.
+Actual values are model specific.
+.PP
+\fB--soc-slider-offset #\fP write the numeric value to the Soc Slider Offset.
+The slider offset is the maximum value that software allows the SoC to
+autonomously add to the SoC Slider to improve energy efficiency.
+The value 0 prohibits the SoC from autonomously changing the slider.
+.PP
+\fB--platform-profile <name>"\fP set the platform profile to <name>.
+Available choices are in platform-profile-0/choices.  The Soc Slider
+driver currently supports "low-power", "balanced", and "performance".
 .SH OTHER OPTIONS
 .PP
 \fB-f, --force\fP writes the specified values without bounds checking.
@@ -208,6 +230,10 @@ runs only as root.
 EPB: /sys/devices/system/cpu/cpu*/power/energy_perf_bias
 EPP: /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference
 MSR: /dev/cpu/*/msr
+Platform Profile Name: /sys/class/platform-profile/platform-profile-0/name
+Platform Profile: /sys/class/platform-profile/platform-profile-0/profile
+SOC Slider Balanced: /sys/module/processor_thermal_soc_slider/parameters/slider_balance
+SOC Slider Balanced Offset: /sys/module/processor_thermal_soc_slider/parameters/slider_offset
 .fi
 .SH "SEE ALSO"
 .nf
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 13/13] tools/power x86_energy_perf_policy: Version 2026.04.25
  2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
                     ` (10 preceding siblings ...)
  2026-04-25 18:42   ` [PATCH 12/13] tools/power x86_energy_perf_policy.8: Document SoC Slider Options Len Brown
@ 2026-04-25 18:42   ` Len Brown
  11 siblings, 0 replies; 14+ messages in thread
From: Len Brown @ 2026-04-25 18:42 UTC (permalink / raw)
  To: linux-pm; +Cc: linux-kernel

From: Len Brown <len.brown@intel.com>

Since v2025.11.22:
	Initial SoC Slider support
	SoC Slider is an SoC-wide power/performance policy setting.
	On SoC Slider systems, EPP plays a diminished role.

Whitespace cleanup via: indent -npro -kr -i8 -ts8 -sob -l160 -ss -ncs -cp1

No functional changes

Signed-off-by: Len Brown <len.brown@intel.com>
---
 .../x86_energy_perf_policy.c                  | 161 +++++++-----------
 1 file changed, 66 insertions(+), 95 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 83e5adbcda69..0dc959e30076 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
@@ -4,7 +4,7 @@
  * policy preference bias on recent X86 processors.
  */
 /*
- * Copyright (c) 2010 - 2025 Intel Corporation.
+ * Copyright (c) 2010 - 2026 Intel Corporation.
  * Len Brown <len.brown@intel.com>
  */
 
@@ -82,10 +82,10 @@ size_t cpu_setsize;
 
 char *proc_stat = "/proc/stat";
 
-unsigned int has_epb;	/* MSR_IA32_ENERGY_PERF_BIAS */
-unsigned int has_hwp;	/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
+unsigned int has_epb;		/* MSR_IA32_ENERGY_PERF_BIAS */
+unsigned int has_hwp;		/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
 			/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
-unsigned int has_hwp_notify;		/* IA32_HWP_INTERRUPT */
+unsigned int has_hwp_notify;	/* IA32_HWP_INTERRUPT */
 unsigned int has_hwp_activity_window;	/* IA32_HWP_REQUEST[bits 41:32] */
 unsigned int has_hwp_epp;	/* IA32_HWP_REQUEST[bits 31:24] */
 unsigned int has_hwp_request_pkg;	/* IA32_HWP_REQUEST_PKG */
@@ -122,8 +122,7 @@ void usage(void)
 	fprintf(stderr, "field: --all | --epb | --hwp-epp | --hwp-min | --hwp-max | --hwp-desired\n");
 	fprintf(stderr, "other: --hwp-enable | --turbo-enable (0 | 1) | --help | --force\n");
 	fprintf(stderr, "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>\n");
-	fprintf(stderr,
-		"value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
+	fprintf(stderr, "value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
 	fprintf(stderr, "--hwp-window usec\n");
 
 	fprintf(stderr, "Specify only Energy Performance BIAS (legacy usage):\n");
@@ -151,6 +150,7 @@ int ratio_2_msr_perf(int ratio)
 
 	return msr_perf;
 }
+
 int msr_perf_2_ratio(int msr_perf)
 {
 	int ratio;
@@ -159,8 +159,8 @@ int msr_perf_2_ratio(int msr_perf)
 	if (!bdx_highest_ratio)
 		return msr_perf;
 
-	d = (double)msr_perf * (double) bdx_highest_ratio / 255.0;
-	d = d + 0.5;	/* round */
+	d = (double)msr_perf * (double)bdx_highest_ratio / 255.0;
+	d = d + 0.5;		/* round */
 	ratio = (int)d;
 
 	if (debug)
@@ -168,6 +168,7 @@ int msr_perf_2_ratio(int msr_perf)
 
 	return ratio;
 }
+
 int parse_cmdline_epb(int i)
 {
 	if (!has_epb)
@@ -214,6 +215,7 @@ int parse_cmdline_hwp_min(int i)
 	}
 	return i;
 }
+
 /*
  * "power" changes hwp_max to cap.lowest
  * All others leave it at cap.highest
@@ -233,6 +235,7 @@ int parse_cmdline_hwp_max(int i)
 	}
 	return i;
 }
+
 /*
  * for --hwp-des, all strings leave it in autonomous mode
  * If you want to change it, you need to explicitly pick a value
@@ -270,7 +273,7 @@ int parse_cmdline_hwp_window(int i)
 		fprintf(stderr, "--hwp-window: 0 for auto; 1 - 1270000000 usec for window duration\n");
 		usage();
 	}
-	for (exponent = 0; ; ++exponent) {
+	for (exponent = 0;; ++exponent) {
 		if (debug)
 			printf("%d 10^%d\n", i, exponent);
 
@@ -284,6 +287,7 @@ int parse_cmdline_hwp_window(int i)
 
 	return (exponent << 7) | i;
 }
+
 int parse_cmdline_hwp_epp(int i)
 {
 	update_hwp_epp = 1;
@@ -305,6 +309,7 @@ int parse_cmdline_hwp_epp(int i)
 	}
 	return i;
 }
+
 int parse_cmdline_turbo(int i)
 {
 	update_turbo = 1;
@@ -524,7 +529,7 @@ void parse_cmdline_pkg(char *s)
 	}
 }
 
-void for_packages(unsigned long long pkg_set, int (func)(int))
+void for_packages(unsigned long long pkg_set, int (func) (int))
 {
 	int pkg_num;
 
@@ -553,7 +558,7 @@ static int parse_cmdline_int(const char *s, int *out)
 
 void print_version(void)
 {
-	printf("x86_energy_perf_policy 2025.11.22 Len Brown <lenb@kernel.org>\n");
+	printf("x86_energy_perf_policy 2026.04.25 Len Brown <lenb@kernel.org>\n");
 }
 
 static int platform_profile_access(int mode)
@@ -791,8 +796,7 @@ void err_on_hypervisor(void)
 	free(buffer);
 
 	if (hypervisor)
-		err(-1,
-		    "not supported on this virtual machine");
+		err(-1, "not supported on this virtual machine");
 }
 
 int get_msr(int cpu, int offset, unsigned long long *msr)
@@ -804,9 +808,7 @@ int get_msr(int cpu, int offset, unsigned long long *msr)
 	sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
 	fd = open(pathname, O_RDONLY);
 	if (fd < 0)
-		err(-1, "%s open failed, try chown or chmod +r %s, or run as root",
-		   pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
-
+		err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
 
 	retval = pread(fd, msr, sizeof(*msr), offset);
 	if (retval != sizeof(*msr)) {
@@ -830,8 +832,7 @@ int put_msr(int cpu, int offset, unsigned long long new_msr)
 	sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
 	fd = open(pathname, O_RDWR);
 	if (fd < 0)
-		err(-1, "%s open failed, try chown or chmod +r %s, or run as root",
-		   pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
+		err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
 
 	retval = pwrite(fd, &new_msr, sizeof(new_msr), offset);
 	if (retval != sizeof(new_msr))
@@ -863,7 +864,7 @@ static unsigned int read_sysfs(const char *path, char *buf, size_t buflen)
 	buf[numread] = '\0';
 	close(fd);
 
-	return (unsigned int) numread;
+	return (unsigned int)numread;
 }
 
 static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
@@ -885,7 +886,7 @@ static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
 
 	close(fd);
 
-	return (unsigned int) numwritten;
+	return (unsigned int)numwritten;
 }
 
 static int sysfs_read_string(const char *path, char *buf, size_t buflen)
@@ -918,9 +919,9 @@ void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
 	if (cpu != -1)
 		printf("cpu%d: ", cpu);
 
-	printf("HWP_CAP: low %d eff %d guar %d high %d\n",
-		cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
+	printf("HWP_CAP: low %d eff %d guar %d high %d\n", cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
 }
+
 void read_hwp_cap(int cpu, struct msr_hwp_cap *cap, unsigned int msr_offset)
 {
 	unsigned long long msr;
@@ -942,9 +943,9 @@ void print_hwp_request(int cpu, struct msr_hwp_request *h, char *str)
 		printf("%s", str);
 
 	printf("HWP_REQ: min %d max %d des %d epp %d window 0x%x (%d*10^%dus) use_pkg %d\n",
-		h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
-		h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
+	       h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
 }
+
 void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
 {
 	printf("pkg%d: ", pkg);
@@ -953,9 +954,9 @@ void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
 		printf("%s", str);
 
 	printf("HWP_REQ_PKG: min %d max %d des %d epp %d window 0x%x (%d*10^%dus)\n",
-		h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
-		h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
+	       h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
 }
+
 void read_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned int msr_offset)
 {
 	unsigned long long msr;
@@ -976,9 +977,7 @@ void write_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned in
 
 	if (debug > 1)
 		printf("cpu%d: requesting min %d max %d des %d epp %d window 0x%0x use_pkg %d\n",
-			cpu, hwp_req->hwp_min, hwp_req->hwp_max,
-			hwp_req->hwp_desired, hwp_req->hwp_epp,
-			hwp_req->hwp_window, hwp_req->hwp_use_pkg);
+		       cpu, hwp_req->hwp_min, hwp_req->hwp_max, hwp_req->hwp_desired, hwp_req->hwp_epp, hwp_req->hwp_window, hwp_req->hwp_use_pkg);
 
 	msr |= HWP_MIN_PERF(ratio_2_msr_perf(hwp_req->hwp_min));
 	msr |= HWP_MAX_PERF(ratio_2_msr_perf(hwp_req->hwp_max));
@@ -1096,7 +1095,7 @@ int print_cpu_msrs(int cpu)
 
 	epb = get_epb_sysfs(cpu);
 	if (epb >= 0)
-		printf("cpu%d: EPB %u\n", cpu, (unsigned int) epb);
+		printf("cpu%d: EPB %u\n", cpu, (unsigned int)epb);
 
 	if (!has_hwp)
 		return 0;
@@ -1124,17 +1123,13 @@ int print_pkg_msrs(int pkg)
 	if (has_hwp_notify) {
 		get_msr(first_cpu_in_pkg[pkg], MSR_HWP_INTERRUPT, &msr);
 		fprintf(stderr,
-		"pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n",
-		pkg, msr,
-		((msr) & 0x2) ? "EN" : "Dis",
-		((msr) & 0x1) ? "EN" : "Dis");
+			"pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n",
+			pkg, msr, ((msr) & 0x2) ? "EN" : "Dis", ((msr) & 0x1) ? "EN" : "Dis");
 	}
 	get_msr(first_cpu_in_pkg[pkg], MSR_HWP_STATUS, &msr);
 	fprintf(stderr,
 		"pkg%d: MSR_HWP_STATUS: 0x%08llx (%sExcursion_Min, %sGuaranteed_Perf_Change)\n",
-		pkg, msr,
-		((msr) & 0x4) ? "" : "No-",
-		((msr) & 0x1) ? "" : "No-");
+		pkg, msr, ((msr) & 0x4) ? "" : "No-", ((msr) & 0x1) ? "" : "No-");
 
 	return 0;
 }
@@ -1148,6 +1143,7 @@ int ratio_2_sysfs_khz(int ratio)
 
 	return ratio * bclk_khz;
 }
+
 /*
  * If HWP is enabled and cpufreq sysfs attribtes are present,
  * then update via sysfs. The intel_pstate driver may modify (clip)
@@ -1164,8 +1160,7 @@ void update_cpufreq_scaling_freq(int is_max, int cpu, unsigned int ratio)
 	int retval;
 	int khz;
 
-	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq",
-		cpu, is_max ? "max" : "min");
+	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq", cpu, is_max ? "max" : "min");
 
 	fp = fopen(pathname, "w");
 	if (!fp) {
@@ -1217,19 +1212,16 @@ int verify_hwp_req_self_consistency(int cpu, struct msr_hwp_request *req)
 {
 	/* fail if min > max requested */
 	if (req->hwp_min > req->hwp_max) {
-		errx(1, "cpu%d: requested hwp-min %d > hwp_max %d",
-			cpu, req->hwp_min, req->hwp_max);
+		errx(1, "cpu%d: requested hwp-min %d > hwp_max %d", cpu, req->hwp_min, req->hwp_max);
 	}
 
 	/* fail if desired > max requestd */
 	if (req->hwp_desired && (req->hwp_desired > req->hwp_max)) {
-		errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d",
-			cpu, req->hwp_desired, req->hwp_max);
+		errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d", cpu, req->hwp_desired, req->hwp_max);
 	}
 	/* fail if desired < min requestd */
 	if (req->hwp_desired && (req->hwp_desired < req->hwp_min)) {
-		errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d",
-			cpu, req->hwp_desired, req->hwp_min);
+		errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d", cpu, req->hwp_desired, req->hwp_min);
 	}
 
 	return 0;
@@ -1239,39 +1231,30 @@ int check_hwp_request_v_hwp_capabilities(int cpu, struct msr_hwp_request *req, s
 {
 	if (update_hwp_max) {
 		if (req->hwp_max > cap->highest)
-			errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?",
-				cpu, req->hwp_max, cap->highest);
+			errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?", cpu, req->hwp_max, cap->highest);
 		if (req->hwp_max < cap->lowest)
-			errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?",
-				cpu, req->hwp_max, cap->lowest);
+			errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?", cpu, req->hwp_max, cap->lowest);
 	}
 
 	if (update_hwp_min) {
 		if (req->hwp_min > cap->highest)
-			errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?",
-				cpu, req->hwp_min, cap->highest);
+			errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?", cpu, req->hwp_min, cap->highest);
 		if (req->hwp_min < cap->lowest)
-			errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?",
-				cpu, req->hwp_min, cap->lowest);
+			errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?", cpu, req->hwp_min, cap->lowest);
 	}
 
 	if (update_hwp_min && update_hwp_max && (req->hwp_min > req->hwp_max))
-		errx(1, "cpu%d: requested min %d > requested max %d",
-			cpu, req->hwp_min, req->hwp_max);
+		errx(1, "cpu%d: requested min %d > requested max %d", cpu, req->hwp_min, req->hwp_max);
 
 	if (update_hwp_desired && req->hwp_desired) {
 		if (req->hwp_desired > req->hwp_max)
-			errx(1, "cpu%d: requested desired %d > requested max %d, use --force?",
-				cpu, req->hwp_desired, req->hwp_max);
+			errx(1, "cpu%d: requested desired %d > requested max %d, use --force?", cpu, req->hwp_desired, req->hwp_max);
 		if (req->hwp_desired < req->hwp_min)
-			errx(1, "cpu%d: requested desired %d < requested min %d, use --force?",
-				cpu, req->hwp_desired, req->hwp_min);
+			errx(1, "cpu%d: requested desired %d < requested min %d, use --force?", cpu, req->hwp_desired, req->hwp_min);
 		if (req->hwp_desired < cap->lowest)
-			errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?",
-				cpu, req->hwp_desired, cap->lowest);
+			errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?", cpu, req->hwp_desired, cap->lowest);
 		if (req->hwp_desired > cap->highest)
-			errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?",
-				cpu, req->hwp_desired, cap->highest);
+			errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?", cpu, req->hwp_desired, cap->highest);
 	}
 
 	return 0;
@@ -1322,6 +1305,7 @@ int update_hwp_request_msr(int cpu)
 	}
 	return 0;
 }
+
 int update_hwp_request_pkg_msr(int pkg)
 {
 	struct msr_hwp_request req;
@@ -1393,8 +1377,7 @@ int update_cpu_epb_sysfs(int cpu)
 	set_epb_sysfs(cpu, new_epb);
 
 	if (verbose)
-		printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n",
-			cpu, epb, (unsigned int) new_epb);
+		printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n", cpu, epb, (unsigned int)new_epb);
 
 	return 0;
 }
@@ -1410,7 +1393,7 @@ int update_cpu_msrs(int cpu)
 
 		turbo_is_present_and_disabled = ((msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE) != 0);
 
-		if (turbo_update_value == 1)	{
+		if (turbo_update_value == 1) {
 			if (turbo_is_present_and_disabled) {
 				msr &= ~MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
 				put_msr(cpu, MSR_IA32_MISC_ENABLE, msr);
@@ -1479,6 +1462,7 @@ int set_max_cpu_pkg_num(int cpu)
 
 	return 0;
 }
+
 int mark_cpu_present(int cpu)
 {
 	CPU_SET_S(cpu, cpu_setsize, cpu_present_set);
@@ -1489,7 +1473,7 @@ int mark_cpu_present(int cpu)
  * run func(cpu) on every cpu in /proc/stat
  * return max_cpu number
  */
-int for_all_proc_cpus(int (func)(int))
+int for_all_proc_cpus(int (func) (int))
 {
 	FILE *fp;
 	int cpu_num;
@@ -1516,7 +1500,7 @@ int for_all_proc_cpus(int (func)(int))
 	return 0;
 }
 
-void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
+void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func) (int))
 {
 	int cpu_num;
 
@@ -1524,7 +1508,8 @@ void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
 		if (CPU_ISSET_S(cpu_num, set_size, cpu_set))
 			func(cpu_num);
 }
-int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
+
+int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func) (int))
 {
 	int cpu_num;
 	int retval = 1;
@@ -1573,7 +1558,7 @@ void verify_hwp_is_enabled(void)
 {
 	int retval;
 
-	if (!has_hwp)	/* set in early_cpuid() */
+	if (!has_hwp)		/* set in early_cpuid() */
 		return;
 
 	retval = for_all_cpus_in_set_and(cpu_setsize, cpu_selected_set, is_hwp_enabled_on_cpu);
@@ -1590,21 +1575,18 @@ int req_update_bounds_check(void)
 		return 0;
 
 	/* fail if min > max requested */
-	if ((update_hwp_max && update_hwp_min) &&
-	    (req_update.hwp_min > req_update.hwp_max)) {
+	if ((update_hwp_max && update_hwp_min) && (req_update.hwp_min > req_update.hwp_max)) {
 		printf("hwp-min %d > hwp_max %d\n", req_update.hwp_min, req_update.hwp_max);
 		return -EINVAL;
 	}
 
 	/* fail if desired > max requestd */
-	if (req_update.hwp_desired && update_hwp_max &&
-	    (req_update.hwp_desired > req_update.hwp_max)) {
+	if (req_update.hwp_desired && update_hwp_max && (req_update.hwp_desired > req_update.hwp_max)) {
 		printf("hwp-desired cannot be greater than hwp_max\n");
 		return -EINVAL;
 	}
 	/* fail if desired < min requestd */
-	if (req_update.hwp_desired && update_hwp_min &&
-	    (req_update.hwp_desired < req_update.hwp_min)) {
+	if (req_update.hwp_desired && update_hwp_min && (req_update.hwp_desired < req_update.hwp_min)) {
 		printf("hwp-desired cannot be less than hwp_min\n");
 		return -EINVAL;
 	}
@@ -1647,9 +1629,7 @@ void probe_dev_msr(void)
 	}
 }
 
-static void get_cpuid_or_exit(unsigned int leaf,
-			     unsigned int *eax, unsigned int *ebx,
-			     unsigned int *ecx, unsigned int *edx)
+static void get_cpuid_or_exit(unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
 {
 	if (!__get_cpuid(leaf, eax, ebx, ecx, edx))
 		errx(1, "Processor not supported\n");
@@ -1703,8 +1683,7 @@ void parse_cpuid(void)
 		genuine_intel = 1;
 
 	if (debug)
-		fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
-			(char *)&ebx, (char *)&edx, (char *)&ecx);
+		fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", (char *)&ebx, (char *)&edx, (char *)&ecx);
 
 	get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
 	family = (fms >> 8) & 0xf;
@@ -1714,23 +1693,18 @@ void parse_cpuid(void)
 		model += ((fms >> 16) & 0xf) << 4;
 
 	if (debug) {
-		fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
-			max_level, family, model, stepping, family, model, stepping);
+		fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", max_level, family, model, stepping, family, model, stepping);
 		fprintf(stderr, "CPUID(1): %s %s %s %s %s %s %s %s\n",
 			ecx & (1 << 0) ? "SSE3" : "-",
 			ecx & (1 << 3) ? "MONITOR" : "-",
 			ecx & (1 << 7) ? "EIST" : "-",
 			ecx & (1 << 8) ? "TM2" : "-",
-			edx & (1 << 4) ? "TSC" : "-",
-			edx & (1 << 5) ? "MSR" : "-",
-			edx & (1 << 22) ? "ACPI-TM" : "-",
-			edx & (1 << 29) ? "TM" : "-");
+			edx & (1 << 4) ? "TSC" : "-", edx & (1 << 5) ? "MSR" : "-", edx & (1 << 22) ? "ACPI-TM" : "-", edx & (1 << 29) ? "TM" : "-");
 	}
 
 	if (!(edx & (1 << 5)))
 		errx(1, "CPUID: no MSR");
 
-
 	get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
 	/* turbo_is_enabled already set */
 	/* has_hwp already set */
@@ -1750,12 +1724,9 @@ void parse_cpuid(void)
 			turbo_is_enabled ? "" : "No-",
 			has_hwp ? "" : "No-",
 			has_hwp_notify ? "" : "No-",
-			has_hwp_activity_window ? "" : "No-",
-			has_hwp_epp ? "" : "No-",
-			has_hwp_request_pkg ? "" : "No-",
-			has_epb ? "" : "No-");
+			has_hwp_activity_window ? "" : "No-", has_hwp_epp ? "" : "No-", has_hwp_request_pkg ? "" : "No-", has_epb ? "" : "No-");
 
-	return;	/* success */
+	return;			/* success */
 }
 
 int main(int argc, char **argv)
@@ -1765,7 +1736,7 @@ int main(int argc, char **argv)
 	probe_dev_msr();
 	init_data_structures();
 
-	early_cpuid();	/* initial cpuid parse before cmdline */
+	early_cpuid();		/* initial cpuid parse before cmdline */
 
 	cmdline(argc, argv);
 
@@ -1774,7 +1745,7 @@ int main(int argc, char **argv)
 
 	parse_cpuid();
 
-	 /* If CPU-set and PKG-set are not initialized, default to all CPUs */
+	/* If CPU-set and PKG-set are not initialized, default to all CPUs */
 	if ((cpu_selected_set == 0) && (pkg_selected_set == 0))
 		cpu_selected_set = cpu_present_set;
 
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-04-25 18:48 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-25 18:42 [PATCH 0/13] Power Utilities update for Linux-7.1 Len Brown
2026-04-25 18:42 ` [PATCH 01/13] tools/power/x86: Add SOC slider and platform profile support Len Brown
2026-04-25 18:42   ` [PATCH 02/13] tools/power turbostat: Fix AMD RAPL regression on big systems Len Brown
2026-04-25 18:42   ` [PATCH 03/13] tools/power turbostat: Fix unrecognized option '-P' Len Brown
2026-04-25 18:42   ` [PATCH 04/13] tools/power turbostat: Fix --cpu-set 0 regression on HT systems Len Brown
2026-04-25 18:42   ` [PATCH 05/13] tools/power turbostat: Fix --cpu-set 1 " Len Brown
2026-04-25 18:42   ` [PATCH 06/13] tools/power turbostat: Cleanup print helper functions Len Brown
2026-04-25 18:42   ` [PATCH 07/13] tools/power turbostat: Print core_id and apic_id in hex Len Brown
2026-04-25 18:42   ` [PATCH 08/13] tools/power turbostat: Show module_id column Len Brown
2026-04-25 18:42   ` [PATCH 09/13] tools/power turbostat: Process HT siblings in CPU order Len Brown
2026-04-25 18:42   ` [PATCH 10/13] tools/power turbostat: v2026.04.21 Len Brown
2026-04-25 18:42   ` [PATCH 11/13] tools/power x86_energy_perf_policy: Enhances SoC Slider related checks Len Brown
2026-04-25 18:42   ` [PATCH 12/13] tools/power x86_energy_perf_policy.8: Document SoC Slider Options Len Brown
2026-04-25 18:42   ` [PATCH 13/13] tools/power x86_energy_perf_policy: Version 2026.04.25 Len Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox