Skip to content

Commit 7103292

Browse files
committed
Merge tag 'turbostat-2025.05.06' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
Pull turbostat updates from Len Brown: - support up to 8192 processors - add cpuidle governor debug telemetry, disabled by default - update default output to exclude cpuidle invocation counts - bug fixes * tag 'turbostat-2025.05.06' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: tools/power turbostat: v2025.05.06 tools/power turbostat: disable "cpuidle" invocation counters, by default tools/power turbostat: re-factor sysfs code tools/power turbostat: Restore GFX sysfs fflush() call tools/power turbostat: Document GNR UncMHz domain convention tools/power turbostat: report CoreThr per measurement interval tools/power turbostat: Increase CPU_SUBSET_MAXCPUS to 8192 tools/power turbostat: Add idle governor statistics reporting tools/power turbostat: Fix names matching tools/power turbostat: Allow Zero return value for some RAPL registers tools/power turbostat: Clustered Uncore MHz counters should honor show/hide options
2 parents 59f392f + 03e00e3 commit 7103292

File tree

2 files changed

+135
-43
lines changed

2 files changed

+135
-43
lines changed

tools/power/x86/turbostat/turbostat.8

+12-4
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ The column name "all" can be used to enable all disabled-by-default built-in cou
100100
.PP
101101
\fB--show column\fP show only the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names.
102102
.PP
103-
\fB--show CATEGORY --hide CATEGORY\fP Show and hide also accept a single CATEGORY of columns: "all", "topology", "idle", "frequency", "power", "sysfs", "other".
103+
\fB--show CATEGORY --hide CATEGORY\fP Show and hide also accept a single CATEGORY of columns: "all", "topology", "idle", "frequency", "power", "cpuidle", "hwidle", "swidle", "other". "idle" (enabled by default), includes "hwidle" and "idle_pct". "cpuidle" (default disabled) includes cpuidle software invocation counters. "swidle" includes "cpuidle" plus "idle_pct". "hwidle" includes only hardware based idle residency counters. Older versions of turbostat used the term "sysfs" for what is now "swidle".
104104
.PP
105105
\fB--Dump\fP displays the raw counter values.
106106
.PP
@@ -158,16 +158,22 @@ The system configuration dump (if --quiet is not used) is followed by statistics
158158
.PP
159159
\fBSMI\fP The number of System Management Interrupts serviced CPU during the measurement interval. While this counter is actually per-CPU, SMI are triggered on all processors, so the number should be the same for all CPUs.
160160
.PP
161-
\fBC1, C2, C3...\fP The number times Linux requested the C1, C2, C3 idle state during the measurement interval. The system summary line shows the sum for all CPUs. These are C-state names as exported in /sys/devices/system/cpu/cpu*/cpuidle/state*/name. While their names are generic, their attributes are processor specific. They the system description section of output shows what MWAIT sub-states they are mapped to on each system.
161+
\fBC1, C2, C3...\fP The number times Linux requested the C1, C2, C3 idle state during the measurement interval. The system summary line shows the sum for all CPUs. These are C-state names as exported in /sys/devices/system/cpu/cpu*/cpuidle/state*/name. While their names are generic, their attributes are processor specific. They the system description section of output shows what MWAIT sub-states they are mapped to on each system. These counters are in the "cpuidle" group, which is disabled, by default.
162162
.PP
163-
\fBC1%, C2%, C3%\fP The residency percentage that Linux requested C1, C2, C3.... The system summary is the average of all CPUs in the system. Note that these are software, reflecting what was requested. The hardware counters reflect what was actually achieved.
163+
\fBC1+, C2+, C3+...\fP The idle governor idle state misprediction statistics. Inidcates the number times Linux requested the C1, C2, C3 idle state during the measurement interval, but should have requested a deeper idle state (if it exists and enabled). These statistics come from the /sys/devices/system/cpu/cpu*/cpuidle/state*/below file. These counters are in the "cpuidle" group, which is disabled, by default.
164164
.PP
165-
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters.
165+
\fBC1-, C2-, C3-...\fP The idle governor idle state misprediction statistics. Inidcates the number times Linux requested the C1, C2, C3 idle state during the measurement interval, but should have requested a shallower idle state (if it exists and enabled). These statistics come from the /sys/devices/system/cpu/cpu*/cpuidle/state*/above file. These counters are in the "cpuidle" group, which is disabled, by default.
166+
.PP
167+
\fBC1%, C2%, C3%\fP The residency percentage that Linux requested C1, C2, C3.... The system summary is the average of all CPUs in the system. Note that these are software, reflecting what was requested. The hardware counters reflect what was actually achieved. These counters are in the "pct_idle" group, which is enabled by default.
168+
.PP
169+
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters and are in the "hwidle" group, which is enabled, by default.
166170
.PP
167171
\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
168172
.PP
169173
\fBPkgTmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
170174
.PP
175+
\fBCoreThr\fP Core Thermal Throttling events during the measurement interval. Note that events since boot can be find in /sys/devices/system/cpu/cpu*/thermal_throttle/*
176+
.PP
171177
\fBGFX%rc6\fP The percentage of time the GPU is in the "render C6" state, rc6, during the measurement interval. From /sys/class/drm/card0/power/rc6_residency_ms or /sys/class/drm/card0/gt/gt0/rc6_residency_ms or /sys/class/drm/card0/device/tile0/gtN/gtidle/idle_residency_ms depending on the graphics driver being used.
172178
.PP
173179
\fBGFXMHz\fP Instantaneous snapshot of what sysfs presents at the end of the measurement interval. From /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz or /sys/class/drm/card0/gt_cur_freq_mhz or /sys/class/drm/card0/gt/gt0/rps_cur_freq_mhz or /sys/class/drm/card0/device/tile0/gtN/freq0/cur_freq depending on the graphics driver being used.
@@ -199,6 +205,8 @@ The system configuration dump (if --quiet is not used) is followed by statistics
199205
\fBUncMHz\fP per-package uncore MHz, instantaneous sample.
200206
.PP
201207
\fBUMHz1.0\fP per-package uncore MHz for domain=1 and fabric_cluster=0, instantaneous sample. System summary is the average of all packages.
208+
Intel Granite Rapids systems use domains 0-2 for CPUs, and 3-4 for IO, with cluster always 0.
209+
For the "--show" and "--hide" options, use "UncMHz" to operate on all UMHz*.* as a group.
202210
.SH TOO MUCH INFORMATION EXAMPLE
203211
By default, turbostat dumps all possible information -- a system configuration header, followed by columns for all counters.
204212
This is ideal for remote debugging, use the "--out" option to save everything to a text file, and get that file to the expert helping you debug.

tools/power/x86/turbostat/turbostat.c

+123-39
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ struct msr_counter bic[] = {
153153
{ 0x0, "TSC_MHz", NULL, 0, 0, 0, NULL, 0 },
154154
{ 0x0, "IRQ", NULL, 0, 0, 0, NULL, 0 },
155155
{ 0x0, "SMI", NULL, 32, 0, FORMAT_DELTA, NULL, 0 },
156-
{ 0x0, "sysfs", NULL, 0, 0, 0, NULL, 0 },
156+
{ 0x0, "cpuidle", NULL, 0, 0, 0, NULL, 0 },
157157
{ 0x0, "CPU%c1", NULL, 0, 0, 0, NULL, 0 },
158158
{ 0x0, "CPU%c3", NULL, 0, 0, 0, NULL, 0 },
159159
{ 0x0, "CPU%c6", NULL, 0, 0, 0, NULL, 0 },
@@ -206,6 +206,7 @@ struct msr_counter bic[] = {
206206
{ 0x0, "Sys_J", NULL, 0, 0, 0, NULL, 0 },
207207
{ 0x0, "NMI", NULL, 0, 0, 0, NULL, 0 },
208208
{ 0x0, "CPU%c1e", NULL, 0, 0, 0, NULL, 0 },
209+
{ 0x0, "pct_idle", NULL, 0, 0, 0, NULL, 0 },
209210
};
210211

211212
#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
@@ -219,7 +220,7 @@ struct msr_counter bic[] = {
219220
#define BIC_TSC_MHz (1ULL << 7)
220221
#define BIC_IRQ (1ULL << 8)
221222
#define BIC_SMI (1ULL << 9)
222-
#define BIC_sysfs (1ULL << 10)
223+
#define BIC_cpuidle (1ULL << 10)
223224
#define BIC_CPU_c1 (1ULL << 11)
224225
#define BIC_CPU_c3 (1ULL << 12)
225226
#define BIC_CPU_c6 (1ULL << 13)
@@ -272,17 +273,20 @@ struct msr_counter bic[] = {
272273
#define BIC_Sys_J (1ULL << 60)
273274
#define BIC_NMI (1ULL << 61)
274275
#define BIC_CPU_c1e (1ULL << 62)
275-
276-
#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die)
277-
#define BIC_THERMAL_PWR (BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__ | BIC_SysWatt)
278-
#define BIC_FREQUENCY (BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz | BIC_SAMMHz | BIC_SAMACTMHz | BIC_UNCORE_MHZ)
279-
#define BIC_IDLE (BIC_Busy | BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX | BIC_SAM_mc6 | BIC_Diec6)
276+
#define BIC_pct_idle (1ULL << 63)
277+
278+
#define BIC_GROUP_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die)
279+
#define BIC_GROUP_THERMAL_PWR (BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__ | BIC_SysWatt)
280+
#define BIC_GROUP_FREQUENCY (BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz | BIC_SAMMHz | BIC_SAMACTMHz | BIC_UNCORE_MHZ)
281+
#define BIC_GROUP_HW_IDLE (BIC_Busy | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX | BIC_SAM_mc6 | BIC_Diec6)
282+
#define BIC_GROUP_SW_IDLE (BIC_Busy | BIC_cpuidle | BIC_pct_idle )
283+
#define BIC_GROUP_IDLE (BIC_GROUP_HW_IDLE | BIC_pct_idle)
280284
#define BIC_OTHER (BIC_IRQ | BIC_NMI | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
281285

282-
#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
286+
#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC | BIC_cpuidle)
283287

284288
unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
285-
unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
289+
unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_cpuidle | BIC_pct_idle | BIC_APIC | BIC_X2APIC;
286290

287291
#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
288292
#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
@@ -1121,7 +1125,7 @@ void probe_platform_features(unsigned int family, unsigned int model)
11211125
int backwards_count;
11221126
char *progname;
11231127

1124-
#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
1128+
#define CPU_SUBSET_MAXCPUS 8192 /* need to use before probe... */
11251129
cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset;
11261130
size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size;
11271131
#define MAX_ADDED_THREAD_COUNTERS 24
@@ -2211,7 +2215,7 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
22112215
return 0;
22122216
}
22132217

2214-
int probe_msr(int cpu, off_t offset)
2218+
int probe_rapl_msr(int cpu, off_t offset, int index)
22152219
{
22162220
ssize_t retval;
22172221
unsigned long long value;
@@ -2220,13 +2224,22 @@ int probe_msr(int cpu, off_t offset)
22202224

22212225
retval = pread(get_msr_fd(cpu), &value, sizeof(value), offset);
22222226

2223-
/*
2224-
* Expect MSRs to accumulate some non-zero value since the system was powered on.
2225-
* Treat zero as a read failure.
2226-
*/
2227-
if (retval != sizeof(value) || value == 0)
2227+
/* if the read failed, the probe fails */
2228+
if (retval != sizeof(value))
22282229
return 1;
22292230

2231+
/* If an Energy Status Counter MSR returns 0, the probe fails */
2232+
switch (index) {
2233+
case RAPL_RCI_INDEX_ENERGY_PKG:
2234+
case RAPL_RCI_INDEX_ENERGY_CORES:
2235+
case RAPL_RCI_INDEX_DRAM:
2236+
case RAPL_RCI_INDEX_GFX:
2237+
case RAPL_RCI_INDEX_ENERGY_PLATFORM:
2238+
if (value == 0)
2239+
return 1;
2240+
}
2241+
2242+
/* PKG,DRAM_PERF_STATUS MSRs, can return any value */
22302243
return 0;
22312244
}
22322245

@@ -2345,16 +2358,25 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
23452358
retval |= ~0;
23462359
break;
23472360
} else if (!strcmp(name_list, "topology")) {
2348-
retval |= BIC_TOPOLOGY;
2361+
retval |= BIC_GROUP_TOPOLOGY;
23492362
break;
23502363
} else if (!strcmp(name_list, "power")) {
2351-
retval |= BIC_THERMAL_PWR;
2364+
retval |= BIC_GROUP_THERMAL_PWR;
23522365
break;
23532366
} else if (!strcmp(name_list, "idle")) {
2354-
retval |= BIC_IDLE;
2367+
retval |= BIC_GROUP_IDLE;
2368+
break;
2369+
} else if (!strcmp(name_list, "swidle")) {
2370+
retval |= BIC_GROUP_SW_IDLE;
2371+
break;
2372+
} else if (!strcmp(name_list, "sysfs")) { /* legacy compatibility */
2373+
retval |= BIC_GROUP_SW_IDLE;
2374+
break;
2375+
} else if (!strcmp(name_list, "hwidle")) {
2376+
retval |= BIC_GROUP_HW_IDLE;
23552377
break;
23562378
} else if (!strcmp(name_list, "frequency")) {
2357-
retval |= BIC_FREQUENCY;
2379+
retval |= BIC_GROUP_FREQUENCY;
23582380
break;
23592381
} else if (!strcmp(name_list, "other")) {
23602382
retval |= BIC_OTHER;
@@ -2363,6 +2385,7 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
23632385

23642386
}
23652387
if (i == MAX_BIC) {
2388+
fprintf(stderr, "deferred %s\n", name_list);
23662389
if (mode == SHOW_LIST) {
23672390
deferred_add_names[deferred_add_index++] = name_list;
23682391
if (deferred_add_index >= MAX_DEFERRED) {
@@ -3476,7 +3499,7 @@ void delta_core(struct core_data *new, struct core_data *old)
34763499
old->c6 = new->c6 - old->c6;
34773500
old->c7 = new->c7 - old->c7;
34783501
old->core_temp_c = new->core_temp_c;
3479-
old->core_throt_cnt = new->core_throt_cnt;
3502+
old->core_throt_cnt = new->core_throt_cnt - old->core_throt_cnt;
34803503
old->mc6_us = new->mc6_us - old->mc6_us;
34813504

34823505
DELTA_WRAP32(new->core_energy.raw_value, old->core_energy.raw_value);
@@ -6030,6 +6053,7 @@ int snapshot_graphics(int idx)
60306053
int retval;
60316054

60326055
rewind(gfx_info[idx].fp);
6056+
fflush(gfx_info[idx].fp);
60336057

60346058
switch (idx) {
60356059
case GFX_rc6:
@@ -6703,7 +6727,18 @@ static void probe_intel_uncore_frequency_cluster(void)
67036727
sprintf(path, "%s/current_freq_khz", path_base);
67046728
sprintf(name_buf, "UMHz%d.%d", domain_id, cluster_id);
67056729

6706-
add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id);
6730+
/*
6731+
* Once add_couter() is called, that counter is always read
6732+
* and reported -- So it is effectively (enabled & present).
6733+
* Only call add_counter() here if legacy BIC_UNCORE_MHZ (UncMHz)
6734+
* is (enabled). Since we are in this routine, we
6735+
* know we will not probe and set (present) the legacy counter.
6736+
*
6737+
* This allows "--show/--hide UncMHz" to be effective for
6738+
* the clustered MHz counters, as a group.
6739+
*/
6740+
if BIC_IS_ENABLED(BIC_UNCORE_MHZ)
6741+
add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id);
67076742

67086743
if (quiet)
67096744
continue;
@@ -7896,7 +7931,7 @@ void rapl_perf_init(void)
78967931
rci->flags[cai->rci_index] = cai->flags;
78977932

78987933
/* Use MSR for this counter */
7899-
} else if (!no_msr && cai->msr && probe_msr(cpu, cai->msr) == 0) {
7934+
} else if (!no_msr && cai->msr && probe_rapl_msr(cpu, cai->msr, cai->rci_index) == 0) {
79007935
rci->source[cai->rci_index] = COUNTER_SOURCE_MSR;
79017936
rci->msr[cai->rci_index] = cai->msr;
79027937
rci->msr_mask[cai->rci_index] = cai->msr_mask;
@@ -8034,7 +8069,7 @@ void msr_perf_init_(void)
80348069
cai->present = true;
80358070

80368071
/* User MSR for this counter */
8037-
} else if (!no_msr && cai->msr && probe_msr(cpu, cai->msr) == 0) {
8072+
} else if (!no_msr && cai->msr && probe_rapl_msr(cpu, cai->msr, cai->rci_index) == 0) {
80388073
cci->source[cai->rci_index] = COUNTER_SOURCE_MSR;
80398074
cci->msr[cai->rci_index] = cai->msr;
80408075
cci->msr_mask[cai->rci_index] = cai->msr_mask;
@@ -8148,7 +8183,7 @@ void cstate_perf_init_(bool soft_c1)
81488183

81498184
/* User MSR for this counter */
81508185
} else if (!no_msr && cai->msr && pkg_cstate_limit >= cai->pkg_cstate_limit
8151-
&& probe_msr(cpu, cai->msr) == 0) {
8186+
&& probe_rapl_msr(cpu, cai->msr, cai->rci_index) == 0) {
81528187
cci->source[cai->rci_index] = COUNTER_SOURCE_MSR;
81538188
cci->msr[cai->rci_index] = cai->msr;
81548189
}
@@ -9559,7 +9594,7 @@ int get_and_dump_counters(void)
95599594

95609595
void print_version()
95619596
{
9562-
fprintf(outf, "turbostat version 2025.02.02 - Len Brown <[email protected]>\n");
9597+
fprintf(outf, "turbostat version 2025.04.06 - Len Brown <[email protected]>\n");
95639598
}
95649599

95659600
#define COMMAND_LINE_SIZE 2048
@@ -9592,7 +9627,7 @@ struct msr_counter *find_msrp_by_name(struct msr_counter *head, char *name)
95929627
for (mp = head; mp; mp = mp->next) {
95939628
if (debug)
95949629
fprintf(stderr, "%s: %s %s\n", __func__, name, mp->name);
9595-
if (!strncmp(name, mp->name, strlen(mp->name)))
9630+
if (!strcmp(name, mp->name))
95969631
return mp;
95979632
}
95989633
return NULL;
@@ -10239,14 +10274,18 @@ int is_deferred_skip(char *name)
1023910274
return 0;
1024010275
}
1024110276

10242-
void probe_sysfs(void)
10277+
void probe_cpuidle_residency(void)
1024310278
{
1024410279
char path[64];
1024510280
char name_buf[16];
1024610281
FILE *input;
1024710282
int state;
10283+
int min_state = 1024, max_state = 0;
1024810284
char *sp;
1024910285

10286+
if (!DO_BIC(BIC_pct_idle))
10287+
return;
10288+
1025010289
for (state = 10; state >= 0; --state) {
1025110290

1025210291
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
@@ -10269,14 +10308,32 @@ void probe_sysfs(void)
1026910308

1027010309
sprintf(path, "cpuidle/state%d/time", state);
1027110310

10272-
if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf))
10311+
if (!DO_BIC(BIC_pct_idle) && !is_deferred_add(name_buf))
1027310312
continue;
1027410313

1027510314
if (is_deferred_skip(name_buf))
1027610315
continue;
1027710316

1027810317
add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC, FORMAT_PERCENT, SYSFS_PERCPU, 0);
10318+
10319+
if (state > max_state)
10320+
max_state = state;
10321+
if (state < min_state)
10322+
min_state = state;
1027910323
}
10324+
}
10325+
10326+
void probe_cpuidle_counts(void)
10327+
{
10328+
char path[64];
10329+
char name_buf[16];
10330+
FILE *input;
10331+
int state;
10332+
int min_state = 1024, max_state = 0;
10333+
char *sp;
10334+
10335+
if (!DO_BIC(BIC_cpuidle))
10336+
return;
1028010337

1028110338
for (state = 10; state >= 0; --state) {
1028210339

@@ -10286,26 +10343,52 @@ void probe_sysfs(void)
1028610343
continue;
1028710344
if (!fgets(name_buf, sizeof(name_buf), input))
1028810345
err(1, "%s: failed to read file", path);
10289-
/* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
10290-
sp = strchr(name_buf, '-');
10291-
if (!sp)
10292-
sp = strchrnul(name_buf, '\n');
10293-
*sp = '\0';
1029410346
fclose(input);
1029510347

1029610348
remove_underbar(name_buf);
1029710349

10298-
sprintf(path, "cpuidle/state%d/usage", state);
10299-
10300-
if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf))
10350+
if (!DO_BIC(BIC_cpuidle) && !is_deferred_add(name_buf))
1030110351
continue;
1030210352

1030310353
if (is_deferred_skip(name_buf))
1030410354
continue;
1030510355

10356+
/* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
10357+
sp = strchr(name_buf, '-');
10358+
if (!sp)
10359+
sp = strchrnul(name_buf, '\n');
10360+
10361+
/*
10362+
* The 'below' sysfs file always contains 0 for the deepest state (largest index),
10363+
* do not add it.
10364+
*/
10365+
if (state != max_state) {
10366+
/*
10367+
* Add 'C1+' for C1, and so on. The 'below' sysfs file always contains 0 for
10368+
* the last state, so do not add it.
10369+
*/
10370+
10371+
*sp = '+';
10372+
*(sp + 1) = '\0';
10373+
sprintf(path, "cpuidle/state%d/below", state);
10374+
add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
10375+
}
10376+
10377+
*sp = '\0';
10378+
sprintf(path, "cpuidle/state%d/usage", state);
1030610379
add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
10307-
}
1030810380

10381+
/*
10382+
* The 'above' sysfs file always contains 0 for the shallowest state (smallest
10383+
* index), do not add it.
10384+
*/
10385+
if (state != min_state) {
10386+
*sp = '-';
10387+
*(sp + 1) = '\0';
10388+
sprintf(path, "cpuidle/state%d/above", state);
10389+
add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0);
10390+
}
10391+
}
1030910392
}
1031010393

1031110394
/*
@@ -10549,7 +10632,8 @@ int main(int argc, char **argv)
1054910632
print_bootcmd();
1055010633
}
1055110634

10552-
probe_sysfs();
10635+
probe_cpuidle_residency();
10636+
probe_cpuidle_counts();
1055310637

1055410638
if (!getuid())
1055510639
set_rlimit();

0 commit comments

Comments
 (0)