* [PATCH 2/9] tools/power turbostat: Fix swidle header vs data display
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 3/9] tools/power turbostat: Eliminate unnecessary data structure allocation Len Brown
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Len Brown, Artem Bityutskiy
From: Len Brown <len.brown@intel.com>
I changed my mind about displaying swidle statistics,
which are "added counters". Recently I reverted the
column headers to 8-columns, but kept print_decimal_value()
padding out to 16-columns for all 64-bit counters.
Simplify by keeping print_decimial_value() at %lld -- which
will often fit into 8-columns, and live with the fact
that it can overflow and shift the other columns,
which continue to tab-delimited.
This is a better compromise than inserting a bunch
of space characters that most users don't like.
Fixes: 1a23ba6a1ba2 ("tools/power turbostat: Print wide names only for RAW 64-bit columns")
Reported-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
tools/power/x86/turbostat/turbostat.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index ae827485950d..791b9154f662 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2852,10 +2852,9 @@ static inline int print_hex_value(int width, int *printed, char *delim, unsigned
static inline int print_decimal_value(int width, int *printed, char *delim, unsigned long long value)
{
- if (width <= 32)
- return (sprintf(outp, "%s%d", (*printed++ ? delim : ""), (unsigned int)value));
- else
- return (sprintf(outp, "%s%-8lld", (*printed++ ? delim : ""), value));
+ UNUSED(width);
+
+ return (sprintf(outp, "%s%lld", (*printed++ ? delim : ""), value));
}
static inline int print_float_value(int *printed, char *delim, double value)
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/9] tools/power turbostat: Eliminate unnecessary data structure allocation
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
2026-04-10 13:25 ` [PATCH 2/9] tools/power turbostat: Fix swidle header vs data display Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 4/9] tools/power/turbostat: Fix microcode patch level output for AMD/Hygon Len Brown
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
Linux core_id's are a per-package namespace, not a per-node namespace.
Rename topo.cores_per_node to topo.cores_per_pkg to reflect this.
Eliminate topo.nodes_per_pkg from the sizing for core data structures,
since it has no role except to unnecessarily bloat the allocation.
Validated on multiple Intel platforms (ICX/SPR/SRF/EMR/GNR/CWF) with
various CPU online/offline configurations and SMT enabled/disabled
scenarios.
No functional changes.
[lenb: commit message]
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
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 791b9154f662..14021a6ed717 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2409,7 +2409,7 @@ struct topo_params {
int max_l3_id;
int max_node_num;
int nodes_per_pkg;
- int cores_per_node;
+ int cores_per_pkg;
int threads_per_core;
} topo;
@@ -9633,9 +9633,9 @@ void topology_probe(bool startup)
topo.max_core_id = max_core_id; /* within a package */
topo.max_package_id = max_package_id;
- topo.cores_per_node = max_core_id + 1;
+ topo.cores_per_pkg = max_core_id + 1;
if (debug > 1)
- fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node);
+ fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_pkg);
if (!summary_only)
BIC_PRESENT(BIC_Core);
@@ -9700,7 +9700,7 @@ void allocate_counters_1(struct counters *counters)
void allocate_counters(struct counters *counters)
{
int i;
- int num_cores = topo.cores_per_node * topo.nodes_per_pkg * topo.num_packages;
+ int num_cores = topo.cores_per_pkg * topo.num_packages;
counters->threads = calloc(topo.max_cpu_num + 1, sizeof(struct thread_data));
if (counters->threads == NULL)
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/9] tools/power/turbostat: Fix microcode patch level output for AMD/Hygon
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
2026-04-10 13:25 ` [PATCH 2/9] tools/power turbostat: Fix swidle header vs data display Len Brown
2026-04-10 13:25 ` [PATCH 3/9] tools/power turbostat: Eliminate unnecessary data structure allocation Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 5/9] tools/power turbostat: Consistently use print_float_value() Len Brown
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Serhii Pievniev, Len Brown
From: Serhii Pievniev <spevnev16@gmail.com>
turbostat always used the same logic to read the microcode patch level,
which is correct for Intel but not for AMD/Hygon.
While Intel stores the patch level in the upper 32 bits of MSR, AMD
stores it in the lower 32 bits, which causes turbostat to report the
microcode version as 0x0 on AMD/Hygon.
Fix by shifting right by 32 for non-AMD/Hygon, preserving the existing
behavior for Intel and unknown vendors.
Fixes: 3e4048466c39 ("tools/power turbostat: Add --no-msr option")
Signed-off-by: Serhii Pievniev <spevnev16@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
tools/power/x86/turbostat/turbostat.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 14021a6ed717..b985bce69142 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -9121,10 +9121,13 @@ void process_cpuid()
cpuid_has_hv = ecx_flags & (1 << 31);
if (!no_msr) {
- if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch))
+ if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch)) {
warnx("get_msr(UCODE)");
- else
+ } else {
ucode_patch_valid = true;
+ if (!authentic_amd && !hygon_genuine)
+ ucode_patch >>= 32;
+ }
}
/*
@@ -9138,7 +9141,7 @@ void process_cpuid()
if (!quiet) {
fprintf(outf, "CPUID(1): family:model:stepping 0x%x:%x:%x (%d:%d:%d)", family, model, stepping, family, model, stepping);
if (ucode_patch_valid)
- fprintf(outf, " microcode 0x%x", (unsigned int)((ucode_patch >> 32) & 0xFFFFFFFF));
+ fprintf(outf, " microcode 0x%x", (unsigned int)ucode_patch);
fputc('\n', outf);
fprintf(outf, "CPUID(0x80000000): max_extended_levels: 0x%x\n", max_extended_level);
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/9] tools/power turbostat: Consistently use print_float_value()
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
` (2 preceding siblings ...)
2026-04-10 13:25 ` [PATCH 4/9] tools/power/turbostat: Fix microcode patch level output for AMD/Hygon Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 6/9] tools/power turbostat: Fix incorrect format variable Len Brown
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Artem Bityutskiy, Len Brown
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Fix the PMT thread code to use print_float_value(),
to be consistent with the PMT core and package code.
[lenb: commit message]
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 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index b985bce69142..9744f9caac9a 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -3489,12 +3489,12 @@ int format_counters(PER_THREAD_PARAMS)
case PMT_TYPE_XTAL_TIME:
value_converted = pct(value_raw / crystal_hz, interval_float);
- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
+ outp += print_float_value(&printed, delim, value_converted);
break;
case PMT_TYPE_TCORE_CLOCK:
value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
+ outp += print_float_value(&printed, delim, value_converted);
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/9] tools/power turbostat: Fix incorrect format variable
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
` (3 preceding siblings ...)
2026-04-10 13:25 ` [PATCH 5/9] tools/power turbostat: Consistently use print_float_value() Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 7/9] tools/power turbostat: Fix --show/--hide for individual cpuidle counters Len Brown
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Artem Bityutskiy, Len Brown
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
In the perf thread, core, and package counter loops, an incorrect
'mp->format' variable is used instead of 'pp->format'.
[lenb: edit commit message]
Fixes: 696d15cbd8c2 ("tools/power turbostat: Refactor floating point printout code")
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 | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 9744f9caac9a..4d954533c71d 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -3468,7 +3468,7 @@ int format_counters(PER_THREAD_PARAMS)
for (i = 0, pp = sys.perf_tp; pp; ++i, pp = pp->next) {
if (pp->format == FORMAT_RAW)
outp += print_hex_value(pp->width, &printed, delim, t->perf_counter[i]);
- else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ else if (pp->format == FORMAT_DELTA || pp->format == FORMAT_AVERAGE)
outp += print_decimal_value(pp->width, &printed, delim, t->perf_counter[i]);
else if (pp->format == FORMAT_PERCENT) {
if (pp->type == COUNTER_USEC)
@@ -3538,7 +3538,7 @@ int format_counters(PER_THREAD_PARAMS)
for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) {
if (pp->format == FORMAT_RAW)
outp += print_hex_value(pp->width, &printed, delim, c->perf_counter[i]);
- else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ else if (pp->format == FORMAT_DELTA || pp->format == FORMAT_AVERAGE)
outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]);
else if (pp->format == FORMAT_PERCENT)
outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc));
@@ -3694,7 +3694,7 @@ int format_counters(PER_THREAD_PARAMS)
outp += print_hex_value(pp->width, &printed, delim, p->perf_counter[i]);
else if (pp->type == COUNTER_K2M)
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), (unsigned int)p->perf_counter[i] / 1000);
- else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ else if (pp->format == FORMAT_DELTA || pp->format == FORMAT_AVERAGE)
outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]);
else if (pp->format == FORMAT_PERCENT)
outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc));
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/9] tools/power turbostat: Fix --show/--hide for individual cpuidle counters
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
` (4 preceding siblings ...)
2026-04-10 13:25 ` [PATCH 6/9] tools/power turbostat: Fix incorrect format variable Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 8/9] tools/power turbostat: Fix delimiter bug in print functions Len Brown
2026-04-10 13:25 ` [PATCH 9/9] tools/power turbostat: Allow execution to continue after perf_l2_init() failure Len Brown
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Artem Bityutskiy, Len Brown
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Problem: individual swidle counter names (C1, C1+, C1-, etc.) cannot be
selected via --show/--hide due to two bugs in probe_cpuidle_counts():
1. The function returns immediately when BIC_cpuidle is not enabled,
without checking deferred_add_index.
2. The deferred name check runs against name_buf before the trailing
newline is stripped, so is_deferred_add("C1\n") never matches "C1".
Fix:
1. Relax the early return to pass through when deferred names are
queued.
2. Strip the trailing newline from name_buf before performing deferred
name checks.
3. Check each suffixed variant (C1+, C1, C1-) individually so that
e.g. "--show C1+" enables only the requested metric.
In addition, introduce a helper function to avoid repeating the
condition (readability cleanup).
Fixes: ec4acd3166d8 ("tools/power turbostat: disable "cpuidle" invocation counters, by default")
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 | 35 ++++++++++++++++-----------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 4d954533c71d..3487548841e1 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -11285,6 +11285,14 @@ void probe_cpuidle_residency(void)
}
}
+static bool cpuidle_counter_wanted(char *name)
+{
+ if (is_deferred_skip(name))
+ return false;
+
+ return DO_BIC(BIC_cpuidle) || is_deferred_add(name);
+}
+
void probe_cpuidle_counts(void)
{
char path[64];
@@ -11294,7 +11302,7 @@ void probe_cpuidle_counts(void)
int min_state = 1024, max_state = 0;
char *sp;
- if (!DO_BIC(BIC_cpuidle))
+ if (!DO_BIC(BIC_cpuidle) && !deferred_add_index)
return;
for (state = 10; state >= 0; --state) {
@@ -11309,12 +11317,6 @@ void probe_cpuidle_counts(void)
remove_underbar(name_buf);
- if (!DO_BIC(BIC_cpuidle) && !is_deferred_add(name_buf))
- continue;
-
- if (is_deferred_skip(name_buf))
- continue;
-
/* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
sp = strchr(name_buf, '-');
if (!sp)
@@ -11329,16 +11331,19 @@ void probe_cpuidle_counts(void)
* Add 'C1+' for C1, and so on. The 'below' sysfs file always contains 0 for
* the last state, so do not add it.
*/
-
*sp = '+';
*(sp + 1) = '\0';
- sprintf(path, "cpuidle/state%d/below", state);
- add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
+ if (cpuidle_counter_wanted(name_buf)) {
+ sprintf(path, "cpuidle/state%d/below", state);
+ add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
+ }
}
*sp = '\0';
- sprintf(path, "cpuidle/state%d/usage", state);
- add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
+ if (cpuidle_counter_wanted(name_buf)) {
+ sprintf(path, "cpuidle/state%d/usage", state);
+ add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
+ }
/*
* The 'above' sysfs file always contains 0 for the shallowest state (smallest
@@ -11347,8 +11352,10 @@ void probe_cpuidle_counts(void)
if (state != min_state) {
*sp = '-';
*(sp + 1) = '\0';
- sprintf(path, "cpuidle/state%d/above", state);
- add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
+ if (cpuidle_counter_wanted(name_buf)) {
+ sprintf(path, "cpuidle/state%d/above", state);
+ add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
+ }
}
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 8/9] tools/power turbostat: Fix delimiter bug in print functions
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
` (5 preceding siblings ...)
2026-04-10 13:25 ` [PATCH 7/9] tools/power turbostat: Fix --show/--hide for individual cpuidle counters Len Brown
@ 2026-04-10 13:25 ` Len Brown
2026-04-10 13:25 ` [PATCH 9/9] tools/power turbostat: Allow execution to continue after perf_l2_init() failure Len Brown
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: Artem Bityutskiy, Len Brown
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Commands that add counters, such as 'turbostat --show C1,C1+'
display merged columns without a delimiter.
This is caused by the bad syntax: '(*printed++ ? delim : "")', shared by
print_name()/print_hex_value()/print_decimal_value()/print_float_value()
Use '((*printed)++ ? delim : "")' to correctly increment the value at *printed.
[lenb: fix code and commit message typo, re-word]
Fixes: 56dbb878507b ("tools/power turbostat: Refactor added column header printing")
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 | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 3487548841e1..34e2143cd4b3 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2837,29 +2837,29 @@ static inline int print_name(int width, int *printed, char *delim, char *name, e
UNUSED(type);
if (format == FORMAT_RAW && width >= 64)
- return (sprintf(outp, "%s%-8s", (*printed++ ? delim : ""), name));
+ return (sprintf(outp, "%s%-8s", ((*printed)++ ? delim : ""), name));
else
- return (sprintf(outp, "%s%s", (*printed++ ? delim : ""), name));
+ return (sprintf(outp, "%s%s", ((*printed)++ ? delim : ""), name));
}
static inline int print_hex_value(int width, int *printed, char *delim, unsigned long long value)
{
if (width <= 32)
- return (sprintf(outp, "%s%08x", (*printed++ ? delim : ""), (unsigned int)value));
+ return (sprintf(outp, "%s%08x", ((*printed)++ ? delim : ""), (unsigned int)value));
else
- return (sprintf(outp, "%s%016llx", (*printed++ ? delim : ""), value));
+ return (sprintf(outp, "%s%016llx", ((*printed)++ ? delim : ""), value));
}
static inline int print_decimal_value(int width, int *printed, char *delim, unsigned long long value)
{
UNUSED(width);
- return (sprintf(outp, "%s%lld", (*printed++ ? delim : ""), value));
+ return (sprintf(outp, "%s%lld", ((*printed)++ ? delim : ""), value));
}
static inline int print_float_value(int *printed, char *delim, double value)
{
- return (sprintf(outp, "%s%0.2f", (*printed++ ? delim : ""), value));
+ return (sprintf(outp, "%s%0.2f", ((*printed)++ ? delim : ""), value));
}
void print_header(char *delim)
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 9/9] tools/power turbostat: Allow execution to continue after perf_l2_init() failure
2026-04-10 13:25 ` [PATCH 1/9] tools/power turbostat: Fix illegal memory access when SMT is present and disabled Len Brown
` (6 preceding siblings ...)
2026-04-10 13:25 ` [PATCH 8/9] tools/power turbostat: Fix delimiter bug in print functions Len Brown
@ 2026-04-10 13:25 ` Len Brown
7 siblings, 0 replies; 10+ messages in thread
From: Len Brown @ 2026-04-10 13:25 UTC (permalink / raw)
To: linux-pm; +Cc: David Arcari, Len Brown
From: David Arcari <darcari@redhat.com>
Currently, if perf_l2_init() fails turbostat exits after issuing the
following error (which was encountered on AlderLake):
turbostat: perf_l2_init(cpu0, 0x0, 0xff24) REFS: Invalid argument
This occurs because perf_l2_init() calls err(). However, the code has been
written in such a manner that it is able to perform cleanup and continue.
Therefore, this issue can be addressed by changing the appropriate calls
to err() to warnx().
Additionally, correct the PMU type arguments passed to the warning strings
in the ecore and lcore blocks so the logs accurately reflect the failing
counter type.
Signed-off-by: David Arcari <darcari@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
tools/power/x86/turbostat/turbostat.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 34e2143cd4b3..e9e8ef72395a 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -9405,13 +9405,13 @@ void perf_l2_init(void)
if (!is_hybrid) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits);
free_fd_l2_percpu();
return;
}
@@ -9420,39 +9420,39 @@ void perf_l2_init(void)
if (perf_pcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_pcore_set)) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits);
free_fd_l2_percpu();
return;
}
} else if (perf_ecore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_ecore_set)) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.ecore, perf_model_support->second.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.ecore, perf_model_support->second.hits);
free_fd_l2_percpu();
return;
}
} else if (perf_lcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_lcore_set)) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.lcore, perf_model_support->third.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.lcore, perf_model_support->third.hits);
free_fd_l2_percpu();
return;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread