]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/power turbostat: Fix --show/--hide for individual cpuidle counters
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Wed, 11 Mar 2026 09:00:33 +0000 (11:00 +0200)
committerLen Brown <len.brown@intel.com>
Wed, 18 Mar 2026 03:39:42 +0000 (23:39 -0400)
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

index 4d954533c71de706362d30ae77b98b8aa3b7cf97..3487548841e1d726f6e61b5e988e6d9824d6eadc 100644 (file)
@@ -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);
+                       }
                }
        }
 }