diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-21 16:57:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-21 16:57:36 -0400 |
commit | 26c92a38cec99ee7b657901ff64bd01a96a2fb22 (patch) | |
tree | 8c5c51b76354a81544c9e1f15d29606f859113eb /tools | |
parent | 1abd8a8f39cd9a2925149000056494523c85643a (diff) | |
parent | b51e001385f1c861445af3efeab766811ee8db29 (diff) |
Merge tag 'pm-4.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki:
"These are mostly fixes, including some fixes for changes made during
the recent merge window and some "stable" material, plus some minor
extensions of the turbostat utility.
Specifics:
- Fix the PM core to avoid introducing a runtime PM usage counter
imbalance when adding device links during driver probe (Rafael
Wysocki).
- Fix the operating performance points (OPP) framework to ensure that
the regulator voltage is always updated as appropriate when
updating clock rates (Waldemar Rymarkiewicz).
- Fix the intel_pstate driver to use correct max/min limits for cores
with differing maximum frequences (Srinivas Pandruvada).
- Fix a typo in the intel_pstate driver documentation (Rafael
Wysocki).
- Fix two issues with the recently added Kryo cpufreq driver (Ilia
Lin).
- Fix two recent regressions and some other minor issues in the
turbostat utility and extend it to provide some more diagnostic
information (Len Brown, Nathan Ciobanu)"
* tag 'pm-4.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Documentation: intel_pstate: Fix typo
tools/power turbostat: version 18.06.20
tools/power turbostat: add the missing command line switches
tools/power turbostat: add single character tokens to help
tools/power turbostat: alphabetize the help output
tools/power turbostat: fix segfault on 'no node' machines
tools/power turbostat: add optional APIC X2APIC columns
tools/power turbostat: decode cpuid.1.HT
tools/power turbostat: fix show/hide issues resulting from mis-merge
PM / OPP: Update voltage in case freq == old_freq
cpufreq: intel_pstate: Fix scaling max/min limits with Turbo 3.0
cpufreq: kryo: Add module remove and exit
cpufreq: kryo: Fix possible error code dereference
PM / core: Fix supplier device runtime PM usage counter imbalance
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.8 | 2 | ||||
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 240 |
2 files changed, 167 insertions, 75 deletions
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index ca9ef7017624..d39e4ff7d0bf 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 | |||
@@ -56,7 +56,7 @@ name as necessary to disambiguate it from others is necessary. Note that option | |||
56 | .PP | 56 | .PP |
57 | \fB--hide column\fP do not show the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--hide sysfs" to hide the sysfs statistics columns as a group. | 57 | \fB--hide column\fP do not show the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--hide sysfs" to hide the sysfs statistics columns as a group. |
58 | .PP | 58 | .PP |
59 | \fB--enable column\fP show the specified built-in columns, which are otherwise disabled, by default. Currently the only built-in counters disabled by default are "usec" and "Time_Of_Day_Seconds". | 59 | \fB--enable column\fP show the specified built-in columns, which are otherwise disabled, by default. Currently the only built-in counters disabled by default are "usec", "Time_Of_Day_Seconds", "APIC" and "X2APIC". |
60 | The column name "all" can be used to enable all disabled-by-default built-in counters. | 60 | The column name "all" can be used to enable all disabled-by-default built-in counters. |
61 | .PP | 61 | .PP |
62 | \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. Use "--show sysfs" to show the sysfs statistics columns as a group. | 62 | \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. Use "--show sysfs" to show the sysfs statistics columns as a group. |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index d6cff3070ebd..4d14bbbf9b63 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -109,6 +109,7 @@ unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */ | |||
109 | unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ | 109 | unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ |
110 | unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ | 110 | unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ |
111 | unsigned int has_misc_feature_control; | 111 | unsigned int has_misc_feature_control; |
112 | unsigned int first_counter_read = 1; | ||
112 | 113 | ||
113 | #define RAPL_PKG (1 << 0) | 114 | #define RAPL_PKG (1 << 0) |
114 | /* 0x610 MSR_PKG_POWER_LIMIT */ | 115 | /* 0x610 MSR_PKG_POWER_LIMIT */ |
@@ -170,6 +171,8 @@ struct thread_data { | |||
170 | unsigned long long irq_count; | 171 | unsigned long long irq_count; |
171 | unsigned int smi_count; | 172 | unsigned int smi_count; |
172 | unsigned int cpu_id; | 173 | unsigned int cpu_id; |
174 | unsigned int apic_id; | ||
175 | unsigned int x2apic_id; | ||
173 | unsigned int flags; | 176 | unsigned int flags; |
174 | #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 | 177 | #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 |
175 | #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 | 178 | #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 |
@@ -381,19 +384,23 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) | |||
381 | } | 384 | } |
382 | 385 | ||
383 | /* | 386 | /* |
384 | * Each string in this array is compared in --show and --hide cmdline. | 387 | * This list matches the column headers, except |
385 | * Thus, strings that are proper sub-sets must follow their more specific peers. | 388 | * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time |
389 | * 2. Core and CPU are moved to the end, we can't have strings that contain them | ||
390 | * matching on them for --show and --hide. | ||
386 | */ | 391 | */ |
387 | struct msr_counter bic[] = { | 392 | struct msr_counter bic[] = { |
388 | { 0x0, "usec" }, | 393 | { 0x0, "usec" }, |
389 | { 0x0, "Time_Of_Day_Seconds" }, | 394 | { 0x0, "Time_Of_Day_Seconds" }, |
390 | { 0x0, "Package" }, | 395 | { 0x0, "Package" }, |
396 | { 0x0, "Node" }, | ||
391 | { 0x0, "Avg_MHz" }, | 397 | { 0x0, "Avg_MHz" }, |
398 | { 0x0, "Busy%" }, | ||
392 | { 0x0, "Bzy_MHz" }, | 399 | { 0x0, "Bzy_MHz" }, |
393 | { 0x0, "TSC_MHz" }, | 400 | { 0x0, "TSC_MHz" }, |
394 | { 0x0, "IRQ" }, | 401 | { 0x0, "IRQ" }, |
395 | { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL}, | 402 | { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL}, |
396 | { 0x0, "Busy%" }, | 403 | { 0x0, "sysfs" }, |
397 | { 0x0, "CPU%c1" }, | 404 | { 0x0, "CPU%c1" }, |
398 | { 0x0, "CPU%c3" }, | 405 | { 0x0, "CPU%c3" }, |
399 | { 0x0, "CPU%c6" }, | 406 | { 0x0, "CPU%c6" }, |
@@ -424,73 +431,73 @@ struct msr_counter bic[] = { | |||
424 | { 0x0, "Cor_J" }, | 431 | { 0x0, "Cor_J" }, |
425 | { 0x0, "GFX_J" }, | 432 | { 0x0, "GFX_J" }, |
426 | { 0x0, "RAM_J" }, | 433 | { 0x0, "RAM_J" }, |
427 | { 0x0, "Core" }, | ||
428 | { 0x0, "CPU" }, | ||
429 | { 0x0, "Mod%c6" }, | 434 | { 0x0, "Mod%c6" }, |
430 | { 0x0, "sysfs" }, | ||
431 | { 0x0, "Totl%C0" }, | 435 | { 0x0, "Totl%C0" }, |
432 | { 0x0, "Any%C0" }, | 436 | { 0x0, "Any%C0" }, |
433 | { 0x0, "GFX%C0" }, | 437 | { 0x0, "GFX%C0" }, |
434 | { 0x0, "CPUGFX%" }, | 438 | { 0x0, "CPUGFX%" }, |
435 | { 0x0, "Node%" }, | 439 | { 0x0, "Core" }, |
440 | { 0x0, "CPU" }, | ||
441 | { 0x0, "APIC" }, | ||
442 | { 0x0, "X2APIC" }, | ||
436 | }; | 443 | }; |
437 | 444 | ||
438 | |||
439 | |||
440 | #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) | 445 | #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) |
441 | #define BIC_USEC (1ULL << 0) | 446 | #define BIC_USEC (1ULL << 0) |
442 | #define BIC_TOD (1ULL << 1) | 447 | #define BIC_TOD (1ULL << 1) |
443 | #define BIC_Package (1ULL << 2) | 448 | #define BIC_Package (1ULL << 2) |
444 | #define BIC_Avg_MHz (1ULL << 3) | 449 | #define BIC_Node (1ULL << 3) |
445 | #define BIC_Bzy_MHz (1ULL << 4) | 450 | #define BIC_Avg_MHz (1ULL << 4) |
446 | #define BIC_TSC_MHz (1ULL << 5) | 451 | #define BIC_Busy (1ULL << 5) |
447 | #define BIC_IRQ (1ULL << 6) | 452 | #define BIC_Bzy_MHz (1ULL << 6) |
448 | #define BIC_SMI (1ULL << 7) | 453 | #define BIC_TSC_MHz (1ULL << 7) |
449 | #define BIC_Busy (1ULL << 8) | 454 | #define BIC_IRQ (1ULL << 8) |
450 | #define BIC_CPU_c1 (1ULL << 9) | 455 | #define BIC_SMI (1ULL << 9) |
451 | #define BIC_CPU_c3 (1ULL << 10) | 456 | #define BIC_sysfs (1ULL << 10) |
452 | #define BIC_CPU_c6 (1ULL << 11) | 457 | #define BIC_CPU_c1 (1ULL << 11) |
453 | #define BIC_CPU_c7 (1ULL << 12) | 458 | #define BIC_CPU_c3 (1ULL << 12) |
454 | #define BIC_ThreadC (1ULL << 13) | 459 | #define BIC_CPU_c6 (1ULL << 13) |
455 | #define BIC_CoreTmp (1ULL << 14) | 460 | #define BIC_CPU_c7 (1ULL << 14) |
456 | #define BIC_CoreCnt (1ULL << 15) | 461 | #define BIC_ThreadC (1ULL << 15) |
457 | #define BIC_PkgTmp (1ULL << 16) | 462 | #define BIC_CoreTmp (1ULL << 16) |
458 | #define BIC_GFX_rc6 (1ULL << 17) | 463 | #define BIC_CoreCnt (1ULL << 17) |
459 | #define BIC_GFXMHz (1ULL << 18) | 464 | #define BIC_PkgTmp (1ULL << 18) |
460 | #define BIC_Pkgpc2 (1ULL << 19) | 465 | #define BIC_GFX_rc6 (1ULL << 19) |
461 | #define BIC_Pkgpc3 (1ULL << 20) | 466 | #define BIC_GFXMHz (1ULL << 20) |
462 | #define BIC_Pkgpc6 (1ULL << 21) | 467 | #define BIC_Pkgpc2 (1ULL << 21) |
463 | #define BIC_Pkgpc7 (1ULL << 22) | 468 | #define BIC_Pkgpc3 (1ULL << 22) |
464 | #define BIC_Pkgpc8 (1ULL << 23) | 469 | #define BIC_Pkgpc6 (1ULL << 23) |
465 | #define BIC_Pkgpc9 (1ULL << 24) | 470 | #define BIC_Pkgpc7 (1ULL << 24) |
466 | #define BIC_Pkgpc10 (1ULL << 25) | 471 | #define BIC_Pkgpc8 (1ULL << 25) |
467 | #define BIC_CPU_LPI (1ULL << 26) | 472 | #define BIC_Pkgpc9 (1ULL << 26) |
468 | #define BIC_SYS_LPI (1ULL << 27) | 473 | #define BIC_Pkgpc10 (1ULL << 27) |
469 | #define BIC_PkgWatt (1ULL << 26) | 474 | #define BIC_CPU_LPI (1ULL << 28) |
470 | #define BIC_CorWatt (1ULL << 27) | 475 | #define BIC_SYS_LPI (1ULL << 29) |
471 | #define BIC_GFXWatt (1ULL << 28) | 476 | #define BIC_PkgWatt (1ULL << 30) |
472 | #define BIC_PkgCnt (1ULL << 29) | 477 | #define BIC_CorWatt (1ULL << 31) |
473 | #define BIC_RAMWatt (1ULL << 30) | 478 | #define BIC_GFXWatt (1ULL << 32) |
474 | #define BIC_PKG__ (1ULL << 31) | 479 | #define BIC_PkgCnt (1ULL << 33) |
475 | #define BIC_RAM__ (1ULL << 32) | 480 | #define BIC_RAMWatt (1ULL << 34) |
476 | #define BIC_Pkg_J (1ULL << 33) | 481 | #define BIC_PKG__ (1ULL << 35) |
477 | #define BIC_Cor_J (1ULL << 34) | 482 | #define BIC_RAM__ (1ULL << 36) |
478 | #define BIC_GFX_J (1ULL << 35) | 483 | #define BIC_Pkg_J (1ULL << 37) |
479 | #define BIC_RAM_J (1ULL << 36) | 484 | #define BIC_Cor_J (1ULL << 38) |
480 | #define BIC_Core (1ULL << 37) | 485 | #define BIC_GFX_J (1ULL << 39) |
481 | #define BIC_CPU (1ULL << 38) | 486 | #define BIC_RAM_J (1ULL << 40) |
482 | #define BIC_Mod_c6 (1ULL << 39) | 487 | #define BIC_Mod_c6 (1ULL << 41) |
483 | #define BIC_sysfs (1ULL << 40) | 488 | #define BIC_Totl_c0 (1ULL << 42) |
484 | #define BIC_Totl_c0 (1ULL << 41) | 489 | #define BIC_Any_c0 (1ULL << 43) |
485 | #define BIC_Any_c0 (1ULL << 42) | 490 | #define BIC_GFX_c0 (1ULL << 44) |
486 | #define BIC_GFX_c0 (1ULL << 43) | 491 | #define BIC_CPUGFX (1ULL << 45) |
487 | #define BIC_CPUGFX (1ULL << 44) | 492 | #define BIC_Core (1ULL << 46) |
488 | #define BIC_Node (1ULL << 45) | 493 | #define BIC_CPU (1ULL << 47) |
489 | 494 | #define BIC_APIC (1ULL << 48) | |
490 | #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD) | 495 | #define BIC_X2APIC (1ULL << 49) |
496 | |||
497 | #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) | ||
491 | 498 | ||
492 | unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT); | 499 | unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT); |
493 | unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs; | 500 | unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC; |
494 | 501 | ||
495 | #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME) | 502 | #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME) |
496 | #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) | 503 | #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) |
@@ -517,17 +524,34 @@ void help(void) | |||
517 | "when COMMAND completes.\n" | 524 | "when COMMAND completes.\n" |
518 | "If no COMMAND is specified, turbostat wakes every 5-seconds\n" | 525 | "If no COMMAND is specified, turbostat wakes every 5-seconds\n" |
519 | "to print statistics, until interrupted.\n" | 526 | "to print statistics, until interrupted.\n" |
520 | "--add add a counter\n" | 527 | " -a, --add add a counter\n" |
521 | " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n" | 528 | " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n" |
522 | "--cpu cpu-set limit output to summary plus cpu-set:\n" | 529 | " -c, --cpu cpu-set limit output to summary plus cpu-set:\n" |
523 | " {core | package | j,k,l..m,n-p }\n" | 530 | " {core | package | j,k,l..m,n-p }\n" |
524 | "--quiet skip decoding system configuration header\n" | 531 | " -d, --debug displays usec, Time_Of_Day_Seconds and more debugging\n" |
525 | "--interval sec.subsec Override default 5-second measurement interval\n" | 532 | " -D, --Dump displays the raw counter values\n" |
526 | "--help print this help message\n" | 533 | " -e, --enable [all | column]\n" |
527 | "--list list column headers only\n" | 534 | " shows all or the specified disabled column\n" |
528 | "--num_iterations num number of the measurement iterations\n" | 535 | " -H, --hide [column|column,column,...]\n" |
529 | "--out file create or truncate \"file\" for all output\n" | 536 | " hide the specified column(s)\n" |
530 | "--version print version information\n" | 537 | " -i, --interval sec.subsec\n" |
538 | " Override default 5-second measurement interval\n" | ||
539 | " -J, --Joules displays energy in Joules instead of Watts\n" | ||
540 | " -l, --list list column headers only\n" | ||
541 | " -n, --num_iterations num\n" | ||
542 | " number of the measurement iterations\n" | ||
543 | " -o, --out file\n" | ||
544 | " create or truncate \"file\" for all output\n" | ||
545 | " -q, --quiet skip decoding system configuration header\n" | ||
546 | " -s, --show [column|column,column,...]\n" | ||
547 | " show only the specified column(s)\n" | ||
548 | " -S, --Summary\n" | ||
549 | " limits output to 1-line system summary per interval\n" | ||
550 | " -T, --TCC temperature\n" | ||
551 | " sets the Thermal Control Circuit temperature in\n" | ||
552 | " degrees Celsius\n" | ||
553 | " -h, --help print this help message\n" | ||
554 | " -v, --version print version information\n" | ||
531 | "\n" | 555 | "\n" |
532 | "For more help, run \"man turbostat\"\n"); | 556 | "For more help, run \"man turbostat\"\n"); |
533 | } | 557 | } |
@@ -601,6 +625,10 @@ void print_header(char *delim) | |||
601 | outp += sprintf(outp, "%sCore", (printed++ ? delim : "")); | 625 | outp += sprintf(outp, "%sCore", (printed++ ? delim : "")); |
602 | if (DO_BIC(BIC_CPU)) | 626 | if (DO_BIC(BIC_CPU)) |
603 | outp += sprintf(outp, "%sCPU", (printed++ ? delim : "")); | 627 | outp += sprintf(outp, "%sCPU", (printed++ ? delim : "")); |
628 | if (DO_BIC(BIC_APIC)) | ||
629 | outp += sprintf(outp, "%sAPIC", (printed++ ? delim : "")); | ||
630 | if (DO_BIC(BIC_X2APIC)) | ||
631 | outp += sprintf(outp, "%sX2APIC", (printed++ ? delim : "")); | ||
604 | if (DO_BIC(BIC_Avg_MHz)) | 632 | if (DO_BIC(BIC_Avg_MHz)) |
605 | outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : "")); | 633 | outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : "")); |
606 | if (DO_BIC(BIC_Busy)) | 634 | if (DO_BIC(BIC_Busy)) |
@@ -880,6 +908,10 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
880 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | 908 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
881 | if (DO_BIC(BIC_CPU)) | 909 | if (DO_BIC(BIC_CPU)) |
882 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | 910 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
911 | if (DO_BIC(BIC_APIC)) | ||
912 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | ||
913 | if (DO_BIC(BIC_X2APIC)) | ||
914 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | ||
883 | } else { | 915 | } else { |
884 | if (DO_BIC(BIC_Package)) { | 916 | if (DO_BIC(BIC_Package)) { |
885 | if (p) | 917 | if (p) |
@@ -904,6 +936,10 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
904 | } | 936 | } |
905 | if (DO_BIC(BIC_CPU)) | 937 | if (DO_BIC(BIC_CPU)) |
906 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id); | 938 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id); |
939 | if (DO_BIC(BIC_APIC)) | ||
940 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id); | ||
941 | if (DO_BIC(BIC_X2APIC)) | ||
942 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id); | ||
907 | } | 943 | } |
908 | 944 | ||
909 | if (DO_BIC(BIC_Avg_MHz)) | 945 | if (DO_BIC(BIC_Avg_MHz)) |
@@ -1231,6 +1267,12 @@ delta_thread(struct thread_data *new, struct thread_data *old, | |||
1231 | int i; | 1267 | int i; |
1232 | struct msr_counter *mp; | 1268 | struct msr_counter *mp; |
1233 | 1269 | ||
1270 | /* we run cpuid just the 1st time, copy the results */ | ||
1271 | if (DO_BIC(BIC_APIC)) | ||
1272 | new->apic_id = old->apic_id; | ||
1273 | if (DO_BIC(BIC_X2APIC)) | ||
1274 | new->x2apic_id = old->x2apic_id; | ||
1275 | |||
1234 | /* | 1276 | /* |
1235 | * the timestamps from start of measurement interval are in "old" | 1277 | * the timestamps from start of measurement interval are in "old" |
1236 | * the timestamp from end of measurement interval are in "new" | 1278 | * the timestamp from end of measurement interval are in "new" |
@@ -1393,6 +1435,12 @@ int sum_counters(struct thread_data *t, struct core_data *c, | |||
1393 | int i; | 1435 | int i; |
1394 | struct msr_counter *mp; | 1436 | struct msr_counter *mp; |
1395 | 1437 | ||
1438 | /* copy un-changing apic_id's */ | ||
1439 | if (DO_BIC(BIC_APIC)) | ||
1440 | average.threads.apic_id = t->apic_id; | ||
1441 | if (DO_BIC(BIC_X2APIC)) | ||
1442 | average.threads.x2apic_id = t->x2apic_id; | ||
1443 | |||
1396 | /* remember first tv_begin */ | 1444 | /* remember first tv_begin */ |
1397 | if (average.threads.tv_begin.tv_sec == 0) | 1445 | if (average.threads.tv_begin.tv_sec == 0) |
1398 | average.threads.tv_begin = t->tv_begin; | 1446 | average.threads.tv_begin = t->tv_begin; |
@@ -1619,6 +1667,34 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp) | |||
1619 | return 0; | 1667 | return 0; |
1620 | } | 1668 | } |
1621 | 1669 | ||
1670 | void get_apic_id(struct thread_data *t) | ||
1671 | { | ||
1672 | unsigned int eax, ebx, ecx, edx, max_level; | ||
1673 | |||
1674 | eax = ebx = ecx = edx = 0; | ||
1675 | |||
1676 | if (!genuine_intel) | ||
1677 | return; | ||
1678 | |||
1679 | __cpuid(0, max_level, ebx, ecx, edx); | ||
1680 | |||
1681 | __cpuid(1, eax, ebx, ecx, edx); | ||
1682 | t->apic_id = (ebx >> 24) & 0xf; | ||
1683 | |||
1684 | if (max_level < 0xb) | ||
1685 | return; | ||
1686 | |||
1687 | if (!DO_BIC(BIC_X2APIC)) | ||
1688 | return; | ||
1689 | |||
1690 | ecx = 0; | ||
1691 | __cpuid(0xb, eax, ebx, ecx, edx); | ||
1692 | t->x2apic_id = edx; | ||
1693 | |||
1694 | if (debug && (t->apic_id != t->x2apic_id)) | ||
1695 | fprintf(stderr, "cpu%d: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id); | ||
1696 | } | ||
1697 | |||
1622 | /* | 1698 | /* |
1623 | * get_counters(...) | 1699 | * get_counters(...) |
1624 | * migrate to cpu | 1700 | * migrate to cpu |
@@ -1632,7 +1708,6 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1632 | struct msr_counter *mp; | 1708 | struct msr_counter *mp; |
1633 | int i; | 1709 | int i; |
1634 | 1710 | ||
1635 | |||
1636 | gettimeofday(&t->tv_begin, (struct timezone *)NULL); | 1711 | gettimeofday(&t->tv_begin, (struct timezone *)NULL); |
1637 | 1712 | ||
1638 | if (cpu_migrate(cpu)) { | 1713 | if (cpu_migrate(cpu)) { |
@@ -1640,6 +1715,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1640 | return -1; | 1715 | return -1; |
1641 | } | 1716 | } |
1642 | 1717 | ||
1718 | if (first_counter_read) | ||
1719 | get_apic_id(t); | ||
1643 | retry: | 1720 | retry: |
1644 | t->tsc = rdtsc(); /* we are running on local CPU of interest */ | 1721 | t->tsc = rdtsc(); /* we are running on local CPU of interest */ |
1645 | 1722 | ||
@@ -2432,6 +2509,12 @@ void set_node_data(void) | |||
2432 | if (pni[pkg].count > topo.nodes_per_pkg) | 2509 | if (pni[pkg].count > topo.nodes_per_pkg) |
2433 | topo.nodes_per_pkg = pni[0].count; | 2510 | topo.nodes_per_pkg = pni[0].count; |
2434 | 2511 | ||
2512 | /* Fake 1 node per pkg for machines that don't | ||
2513 | * expose nodes and thus avoid -nan results | ||
2514 | */ | ||
2515 | if (topo.nodes_per_pkg == 0) | ||
2516 | topo.nodes_per_pkg = 1; | ||
2517 | |||
2435 | for (cpu = 0; cpu < topo.num_cpus; cpu++) { | 2518 | for (cpu = 0; cpu < topo.num_cpus; cpu++) { |
2436 | pkg = cpus[cpu].physical_package_id; | 2519 | pkg = cpus[cpu].physical_package_id; |
2437 | node = cpus[cpu].physical_node_id; | 2520 | node = cpus[cpu].physical_node_id; |
@@ -2879,6 +2962,7 @@ void do_sleep(void) | |||
2879 | } | 2962 | } |
2880 | } | 2963 | } |
2881 | 2964 | ||
2965 | |||
2882 | void turbostat_loop() | 2966 | void turbostat_loop() |
2883 | { | 2967 | { |
2884 | int retval; | 2968 | int retval; |
@@ -2892,6 +2976,7 @@ restart: | |||
2892 | 2976 | ||
2893 | snapshot_proc_sysfs_files(); | 2977 | snapshot_proc_sysfs_files(); |
2894 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); | 2978 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); |
2979 | first_counter_read = 0; | ||
2895 | if (retval < -1) { | 2980 | if (retval < -1) { |
2896 | exit(retval); | 2981 | exit(retval); |
2897 | } else if (retval == -1) { | 2982 | } else if (retval == -1) { |
@@ -4392,7 +4477,7 @@ void process_cpuid() | |||
4392 | if (!quiet) { | 4477 | if (!quiet) { |
4393 | fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", | 4478 | fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", |
4394 | max_level, family, model, stepping, family, model, stepping); | 4479 | max_level, family, model, stepping, family, model, stepping); |
4395 | fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n", | 4480 | fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n", |
4396 | ecx & (1 << 0) ? "SSE3" : "-", | 4481 | ecx & (1 << 0) ? "SSE3" : "-", |
4397 | ecx & (1 << 3) ? "MONITOR" : "-", | 4482 | ecx & (1 << 3) ? "MONITOR" : "-", |
4398 | ecx & (1 << 6) ? "SMX" : "-", | 4483 | ecx & (1 << 6) ? "SMX" : "-", |
@@ -4401,6 +4486,7 @@ void process_cpuid() | |||
4401 | edx & (1 << 4) ? "TSC" : "-", | 4486 | edx & (1 << 4) ? "TSC" : "-", |
4402 | edx & (1 << 5) ? "MSR" : "-", | 4487 | edx & (1 << 5) ? "MSR" : "-", |
4403 | edx & (1 << 22) ? "ACPI-TM" : "-", | 4488 | edx & (1 << 22) ? "ACPI-TM" : "-", |
4489 | edx & (1 << 28) ? "HT" : "-", | ||
4404 | edx & (1 << 29) ? "TM" : "-"); | 4490 | edx & (1 << 29) ? "TM" : "-"); |
4405 | } | 4491 | } |
4406 | 4492 | ||
@@ -4652,7 +4738,6 @@ void process_cpuid() | |||
4652 | return; | 4738 | return; |
4653 | } | 4739 | } |
4654 | 4740 | ||
4655 | |||
4656 | /* | 4741 | /* |
4657 | * in /dev/cpu/ return success for names that are numbers | 4742 | * in /dev/cpu/ return success for names that are numbers |
4658 | * ie. filter out ".", "..", "microcode". | 4743 | * ie. filter out ".", "..", "microcode". |
@@ -4842,6 +4927,13 @@ void init_counter(struct thread_data *thread_base, struct core_data *core_base, | |||
4842 | struct core_data *c; | 4927 | struct core_data *c; |
4843 | struct pkg_data *p; | 4928 | struct pkg_data *p; |
4844 | 4929 | ||
4930 | |||
4931 | /* Workaround for systems where physical_node_id==-1 | ||
4932 | * and logical_node_id==(-1 - topo.num_cpus) | ||
4933 | */ | ||
4934 | if (node_id < 0) | ||
4935 | node_id = 0; | ||
4936 | |||
4845 | t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id); | 4937 | t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id); |
4846 | c = GET_CORE(core_base, core_id, node_id, pkg_id); | 4938 | c = GET_CORE(core_base, core_id, node_id, pkg_id); |
4847 | p = GET_PKG(pkg_base, pkg_id); | 4939 | p = GET_PKG(pkg_base, pkg_id); |
@@ -4946,6 +5038,7 @@ int fork_it(char **argv) | |||
4946 | 5038 | ||
4947 | snapshot_proc_sysfs_files(); | 5039 | snapshot_proc_sysfs_files(); |
4948 | status = for_all_cpus(get_counters, EVEN_COUNTERS); | 5040 | status = for_all_cpus(get_counters, EVEN_COUNTERS); |
5041 | first_counter_read = 0; | ||
4949 | if (status) | 5042 | if (status) |
4950 | exit(status); | 5043 | exit(status); |
4951 | /* clear affinity side-effect of get_counters() */ | 5044 | /* clear affinity side-effect of get_counters() */ |
@@ -5009,7 +5102,7 @@ int get_and_dump_counters(void) | |||
5009 | } | 5102 | } |
5010 | 5103 | ||
5011 | void print_version() { | 5104 | void print_version() { |
5012 | fprintf(outf, "turbostat version 18.06.01" | 5105 | fprintf(outf, "turbostat version 18.06.20" |
5013 | " - Len Brown <lenb@kernel.org>\n"); | 5106 | " - Len Brown <lenb@kernel.org>\n"); |
5014 | } | 5107 | } |
5015 | 5108 | ||
@@ -5381,7 +5474,7 @@ void cmdline(int argc, char **argv) | |||
5381 | break; | 5474 | break; |
5382 | case 'e': | 5475 | case 'e': |
5383 | /* --enable specified counter */ | 5476 | /* --enable specified counter */ |
5384 | bic_enabled |= bic_lookup(optarg, SHOW_LIST); | 5477 | bic_enabled = bic_enabled | bic_lookup(optarg, SHOW_LIST); |
5385 | break; | 5478 | break; |
5386 | case 'd': | 5479 | case 'd': |
5387 | debug++; | 5480 | debug++; |
@@ -5465,7 +5558,6 @@ void cmdline(int argc, char **argv) | |||
5465 | int main(int argc, char **argv) | 5558 | int main(int argc, char **argv) |
5466 | { | 5559 | { |
5467 | outf = stderr; | 5560 | outf = stderr; |
5468 | |||
5469 | cmdline(argc, argv); | 5561 | cmdline(argc, argv); |
5470 | 5562 | ||
5471 | if (!quiet) | 5563 | if (!quiet) |