tools/power turbostat: Add idle governor statistics reporting

The idle governor provides the following per-idle state sysfs files:
* above - Indicates overshoots, where a more shallow state should have
been requested (if avaliale and enabled).
* below - Indicates undershoots, where a deeper state should have been
requested (if available and enabled).

These files offer valuable insights into how effectively the Linux kernel
idle governor selects idle states for a given workload. This commit adds
support for these files in turbostat.

Expose the contents of these files with the following naming convention:
* C1: The number of times the C1 state was requested (existing counter).
* C1+: The number of times the idle governor selected C1, but a deeper
idle state should have been selected instead.
* C1-: The number of times the idle governor selected C1, but a shallower
idle state should have been selected instead.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by Artem Bityutskiy and committed by Len Brown ed625c61 5132681d

+45 -9
+4
tools/power/x86/turbostat/turbostat.8
··· 160 .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. 162 .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. 164 .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.
··· 160 .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. 162 .PP 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. 164 + .PP 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. 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. 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.
+41 -9
tools/power/x86/turbostat/turbostat.c
··· 10265 char name_buf[16]; 10266 FILE *input; 10267 int state; 10268 char *sp; 10269 10270 for (state = 10; state >= 0; --state) { ··· 10297 continue; 10298 10299 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC, FORMAT_PERCENT, SYSFS_PERCPU, 0); 10300 } 10301 10302 for (state = 10; state >= 0; --state) { ··· 10312 continue; 10313 if (!fgets(name_buf, sizeof(name_buf), input)) 10314 err(1, "%s: failed to read file", path); 10315 - /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ 10316 - sp = strchr(name_buf, '-'); 10317 - if (!sp) 10318 - sp = strchrnul(name_buf, '\n'); 10319 - *sp = '\0'; 10320 fclose(input); 10321 10322 remove_underbar(name_buf); 10323 - 10324 - sprintf(path, "cpuidle/state%d/usage", state); 10325 10326 if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf)) 10327 continue; ··· 10322 if (is_deferred_skip(name_buf)) 10323 continue; 10324 10325 - add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0); 10326 - } 10327 10328 } 10329 10330 /*
··· 10265 char name_buf[16]; 10266 FILE *input; 10267 int state; 10268 + int min_state = 1024, max_state = 0; 10269 char *sp; 10270 10271 for (state = 10; state >= 0; --state) { ··· 10296 continue; 10297 10298 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC, FORMAT_PERCENT, SYSFS_PERCPU, 0); 10299 + 10300 + if (state > max_state) 10301 + max_state = state; 10302 + if (state < min_state) 10303 + min_state = state; 10304 } 10305 10306 for (state = 10; state >= 0; --state) { ··· 10306 continue; 10307 if (!fgets(name_buf, sizeof(name_buf), input)) 10308 err(1, "%s: failed to read file", path); 10309 fclose(input); 10310 10311 remove_underbar(name_buf); 10312 10313 if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf)) 10314 continue; ··· 10323 if (is_deferred_skip(name_buf)) 10324 continue; 10325 10326 + /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ 10327 + sp = strchr(name_buf, '-'); 10328 + if (!sp) 10329 + sp = strchrnul(name_buf, '\n'); 10330 10331 + /* 10332 + * The 'below' sysfs file always contains 0 for the deepest state (largest index), 10333 + * do not add it. 10334 + */ 10335 + if (state != max_state) { 10336 + /* 10337 + * Add 'C1+' for C1, and so on. The 'below' sysfs file always contains 0 for 10338 + * the last state, so do not add it. 10339 + */ 10340 + 10341 + *sp = '+'; 10342 + *(sp + 1) = '\0'; 10343 + sprintf(path, "cpuidle/state%d/below", state); 10344 + add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0); 10345 + } 10346 + 10347 + *sp = '\0'; 10348 + sprintf(path, "cpuidle/state%d/usage", state); 10349 + add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0); 10350 + 10351 + /* 10352 + * The 'above' sysfs file always contains 0 for the shallowest state (smallest 10353 + * index), do not add it. 10354 + */ 10355 + if (state != min_state) { 10356 + *sp = '-'; 10357 + *(sp + 1) = '\0'; 10358 + sprintf(path, "cpuidle/state%d/above", state); 10359 + add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU, 0); 10360 + } 10361 + } 10362 } 10363 10364 /*