summaryrefslogtreecommitdiffstats
path: root/tools/power
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2015-02-09 23:39:45 -0500
committerLen Brown <len.brown@intel.com>2015-02-09 23:39:45 -0500
commitee7e38e3d8805ba6471bddd088fae92ce5ab1ef5 (patch)
treebfab3cdd9b2ac60aebaddaf9489ba1f8477d3ec7 /tools/power
parenta729617c58529be0be8faa22c5d45748bb0f12e5 (diff)
tools/power turbostat: Skip printing disabled package C-states
Replaced previously open-coded Package C-state Limit decoding with table-driven decoding. In doing so, updated to match January 2015 "Intel(R) 64 and IA-23 Architectures Software Developer's Manual". In the past, turbostat would print package C-state residency columns for all package states supported by the model's architecture, even though a particular SKU may not support them, or they may be disabled by the BIOS. Now turbostat will skip printing colunns if MSRs indicate that they are not enabled. eg. many SKUs don't support PC7, and so that column will no longer be printed. Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools/power')
-rw-r--r--tools/power/x86/turbostat/turbostat.c188
1 files changed, 116 insertions, 72 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index a02c02f25e88..ba8846b309f7 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -53,6 +53,10 @@ unsigned int skip_c0;
53unsigned int skip_c1; 53unsigned int skip_c1;
54unsigned int do_nhm_cstates; 54unsigned int do_nhm_cstates;
55unsigned int do_snb_cstates; 55unsigned int do_snb_cstates;
56unsigned int do_pc2;
57unsigned int do_pc3;
58unsigned int do_pc6;
59unsigned int do_pc7;
56unsigned int do_c8_c9_c10; 60unsigned int do_c8_c9_c10;
57unsigned int do_slm_cstates; 61unsigned int do_slm_cstates;
58unsigned int use_c1_residency_msr; 62unsigned int use_c1_residency_msr;
@@ -313,13 +317,13 @@ void print_header(void)
313 if (do_ptm) 317 if (do_ptm)
314 outp += sprintf(outp, " PkgTmp"); 318 outp += sprintf(outp, " PkgTmp");
315 319
316 if (do_snb_cstates) 320 if (do_pc2)
317 outp += sprintf(outp, " Pkg%%pc2"); 321 outp += sprintf(outp, " Pkg%%pc2");
318 if (do_nhm_cstates && !do_slm_cstates) 322 if (do_pc3)
319 outp += sprintf(outp, " Pkg%%pc3"); 323 outp += sprintf(outp, " Pkg%%pc3");
320 if (do_nhm_cstates && !do_slm_cstates) 324 if (do_pc6)
321 outp += sprintf(outp, " Pkg%%pc6"); 325 outp += sprintf(outp, " Pkg%%pc6");
322 if (do_snb_cstates) 326 if (do_pc7)
323 outp += sprintf(outp, " Pkg%%pc7"); 327 outp += sprintf(outp, " Pkg%%pc7");
324 if (do_c8_c9_c10) { 328 if (do_c8_c9_c10) {
325 outp += sprintf(outp, " Pkg%%pc8"); 329 outp += sprintf(outp, " Pkg%%pc8");
@@ -394,9 +398,12 @@ int dump_counters(struct thread_data *t, struct core_data *c,
394 if (p) { 398 if (p) {
395 outp += sprintf(outp, "package: %d\n", p->package_id); 399 outp += sprintf(outp, "package: %d\n", p->package_id);
396 outp += sprintf(outp, "pc2: %016llX\n", p->pc2); 400 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
397 outp += sprintf(outp, "pc3: %016llX\n", p->pc3); 401 if (do_pc3)
398 outp += sprintf(outp, "pc6: %016llX\n", p->pc6); 402 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
399 outp += sprintf(outp, "pc7: %016llX\n", p->pc7); 403 if (do_pc6)
404 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
405 if (do_pc7)
406 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
400 outp += sprintf(outp, "pc8: %016llX\n", p->pc8); 407 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
401 outp += sprintf(outp, "pc9: %016llX\n", p->pc9); 408 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
402 outp += sprintf(outp, "pc10: %016llX\n", p->pc10); 409 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
@@ -528,13 +535,13 @@ int format_counters(struct thread_data *t, struct core_data *c,
528 if (do_ptm) 535 if (do_ptm)
529 outp += sprintf(outp, "%8d", p->pkg_temp_c); 536 outp += sprintf(outp, "%8d", p->pkg_temp_c);
530 537
531 if (do_snb_cstates) 538 if (do_pc2)
532 outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc); 539 outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc);
533 if (do_nhm_cstates && !do_slm_cstates) 540 if (do_pc3)
534 outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc); 541 outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc);
535 if (do_nhm_cstates && !do_slm_cstates) 542 if (do_pc6)
536 outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc); 543 outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc);
537 if (do_snb_cstates) 544 if (do_pc7)
538 outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc); 545 outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc);
539 if (do_c8_c9_c10) { 546 if (do_c8_c9_c10) {
540 outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc); 547 outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc);
@@ -631,9 +638,12 @@ void
631delta_package(struct pkg_data *new, struct pkg_data *old) 638delta_package(struct pkg_data *new, struct pkg_data *old)
632{ 639{
633 old->pc2 = new->pc2 - old->pc2; 640 old->pc2 = new->pc2 - old->pc2;
634 old->pc3 = new->pc3 - old->pc3; 641 if (do_pc3)
635 old->pc6 = new->pc6 - old->pc6; 642 old->pc3 = new->pc3 - old->pc3;
636 old->pc7 = new->pc7 - old->pc7; 643 if (do_pc6)
644 old->pc6 = new->pc6 - old->pc6;
645 if (do_pc7)
646 old->pc7 = new->pc7 - old->pc7;
637 old->pc8 = new->pc8 - old->pc8; 647 old->pc8 = new->pc8 - old->pc8;
638 old->pc9 = new->pc9 - old->pc9; 648 old->pc9 = new->pc9 - old->pc9;
639 old->pc10 = new->pc10 - old->pc10; 649 old->pc10 = new->pc10 - old->pc10;
@@ -774,9 +784,12 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
774 c->core_temp_c = 0; 784 c->core_temp_c = 0;
775 785
776 p->pc2 = 0; 786 p->pc2 = 0;
777 p->pc3 = 0; 787 if (do_pc3)
778 p->pc6 = 0; 788 p->pc3 = 0;
779 p->pc7 = 0; 789 if (do_pc6)
790 p->pc6 = 0;
791 if (do_pc7)
792 p->pc7 = 0;
780 p->pc8 = 0; 793 p->pc8 = 0;
781 p->pc9 = 0; 794 p->pc9 = 0;
782 p->pc10 = 0; 795 p->pc10 = 0;
@@ -815,9 +828,12 @@ int sum_counters(struct thread_data *t, struct core_data *c,
815 return 0; 828 return 0;
816 829
817 average.packages.pc2 += p->pc2; 830 average.packages.pc2 += p->pc2;
818 average.packages.pc3 += p->pc3; 831 if (do_pc3)
819 average.packages.pc6 += p->pc6; 832 average.packages.pc3 += p->pc3;
820 average.packages.pc7 += p->pc7; 833 if (do_pc6)
834 average.packages.pc6 += p->pc6;
835 if (do_pc7)
836 average.packages.pc7 += p->pc7;
821 average.packages.pc8 += p->pc8; 837 average.packages.pc8 += p->pc8;
822 average.packages.pc9 += p->pc9; 838 average.packages.pc9 += p->pc9;
823 average.packages.pc10 += p->pc10; 839 average.packages.pc10 += p->pc10;
@@ -859,9 +875,12 @@ void compute_average(struct thread_data *t, struct core_data *c,
859 average.cores.c7 /= topo.num_cores; 875 average.cores.c7 /= topo.num_cores;
860 876
861 average.packages.pc2 /= topo.num_packages; 877 average.packages.pc2 /= topo.num_packages;
862 average.packages.pc3 /= topo.num_packages; 878 if (do_pc3)
863 average.packages.pc6 /= topo.num_packages; 879 average.packages.pc3 /= topo.num_packages;
864 average.packages.pc7 /= topo.num_packages; 880 if (do_pc6)
881 average.packages.pc6 /= topo.num_packages;
882 if (do_pc7)
883 average.packages.pc7 /= topo.num_packages;
865 884
866 average.packages.pc8 /= topo.num_packages; 885 average.packages.pc8 /= topo.num_packages;
867 average.packages.pc9 /= topo.num_packages; 886 average.packages.pc9 /= topo.num_packages;
@@ -961,18 +980,18 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
961 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 980 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
962 return 0; 981 return 0;
963 982
964 if (do_nhm_cstates && !do_slm_cstates) { 983 if (do_pc3)
965 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) 984 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
966 return -9; 985 return -9;
986 if (do_pc6)
967 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) 987 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
968 return -10; 988 return -10;
969 } 989 if (do_pc2)
970 if (do_snb_cstates) {
971 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2)) 990 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
972 return -11; 991 return -11;
992 if (do_pc7)
973 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) 993 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
974 return -12; 994 return -12;
975 }
976 if (do_c8_c9_c10) { 995 if (do_c8_c9_c10) {
977 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8)) 996 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
978 return -13; 997 return -13;
@@ -1019,6 +1038,37 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1019 return 0; 1038 return 0;
1020} 1039}
1021 1040
1041/*
1042 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1043 * If you change the values, note they are used both in comparisons
1044 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1045 */
1046
1047#define PCLUKN 0 /* Unknown */
1048#define PCLRSV 1 /* Reserved */
1049#define PCL__0 2 /* PC0 */
1050#define PCL__1 3 /* PC1 */
1051#define PCL__2 4 /* PC2 */
1052#define PCL__3 5 /* PC3 */
1053#define PCL__4 6 /* PC4 */
1054#define PCL__6 7 /* PC6 */
1055#define PCL_6N 8 /* PC6 No Retention */
1056#define PCL_6R 9 /* PC6 Retention */
1057#define PCL__7 10 /* PC7 */
1058#define PCL_7S 11 /* PC7 Shrink */
1059#define PCLUNL 12 /* Unlimited */
1060
1061int pkg_cstate_limit = PCLUKN;
1062char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
1063 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "unlimited"};
1064
1065int nhm_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL};
1066int snb_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL};
1067int hsw_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCLRSV, PCLUNL};
1068int slv_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7};
1069int amt_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
1070int phi_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL};
1071
1022void print_verbose_header(void) 1072void print_verbose_header(void)
1023{ 1073{
1024 unsigned long long msr; 1074 unsigned long long msr;
@@ -1098,44 +1148,14 @@ print_nhm_turbo_ratio_limits:
1098 1148
1099 fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr); 1149 fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr);
1100 1150
1101 fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: ", 1151 fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
1102 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "", 1152 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1103 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "", 1153 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1104 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "", 1154 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1105 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "", 1155 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1106 (msr & (1 << 15)) ? "" : "UN", 1156 (msr & (1 << 15)) ? "" : "UN",
1107 (unsigned int)msr & 7); 1157 (unsigned int)msr & 7,
1108 1158 pkg_cstate_limit_strings[pkg_cstate_limit]);
1109
1110 switch(msr & 0x7) {
1111 case 0:
1112 fprintf(stderr, do_slm_cstates ? "no pkg states" : "pc0");
1113 break;
1114 case 1:
1115 fprintf(stderr, do_slm_cstates ? "no pkg states" : do_snb_cstates ? "pc2" : "pc0");
1116 break;
1117 case 2:
1118 fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc6-noret" : "pc3");
1119 break;
1120 case 3:
1121 fprintf(stderr, do_slm_cstates ? "invalid" : "pc6");
1122 break;
1123 case 4:
1124 fprintf(stderr, do_slm_cstates ? "pc4" : "pc7");
1125 break;
1126 case 5:
1127 fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc7s" : "invalid");
1128 break;
1129 case 6:
1130 fprintf(stderr, do_slm_cstates ? "pc6" : "invalid");
1131 break;
1132 case 7:
1133 fprintf(stderr, do_slm_cstates ? "pc7" : "unlimited");
1134 break;
1135 default:
1136 fprintf(stderr, "invalid");
1137 }
1138 fprintf(stderr, ")\n");
1139 1159
1140 if (!do_nhm_turbo_ratio_limit) 1160 if (!do_nhm_turbo_ratio_limit)
1141 return; 1161 return;
@@ -1516,9 +1536,14 @@ void check_permissions()
1516 * MSR_CORE_C3_RESIDENCY 0x000003fc 1536 * MSR_CORE_C3_RESIDENCY 0x000003fc
1517 * MSR_CORE_C6_RESIDENCY 0x000003fd 1537 * MSR_CORE_C6_RESIDENCY 0x000003fd
1518 * 1538 *
1539 * Side effect:
1540 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL
1519 */ 1541 */
1520int has_nhm_msrs(unsigned int family, unsigned int model) 1542int probe_nhm_msrs(unsigned int family, unsigned int model)
1521{ 1543{
1544 unsigned long long msr;
1545 int *pkg_cstate_limits;
1546
1522 if (!genuine_intel) 1547 if (!genuine_intel)
1523 return 0; 1548 return 0;
1524 1549
@@ -1531,31 +1556,46 @@ int has_nhm_msrs(unsigned int family, unsigned int model)
1531 case 0x1F: /* Core i7 and i5 Processor - Nehalem */ 1556 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
1532 case 0x25: /* Westmere Client - Clarkdale, Arrandale */ 1557 case 0x25: /* Westmere Client - Clarkdale, Arrandale */
1533 case 0x2C: /* Westmere EP - Gulftown */ 1558 case 0x2C: /* Westmere EP - Gulftown */
1559 case 0x2E: /* Nehalem-EX Xeon - Beckton */
1560 case 0x2F: /* Westmere-EX Xeon - Eagleton */
1561 pkg_cstate_limits = nhm_pkg_cstate_limits;
1562 break;
1534 case 0x2A: /* SNB */ 1563 case 0x2A: /* SNB */
1535 case 0x2D: /* SNB Xeon */ 1564 case 0x2D: /* SNB Xeon */
1536 case 0x3A: /* IVB */ 1565 case 0x3A: /* IVB */
1537 case 0x3E: /* IVB Xeon */ 1566 case 0x3E: /* IVB Xeon */
1567 pkg_cstate_limits = snb_pkg_cstate_limits;
1568 break;
1538 case 0x3C: /* HSW */ 1569 case 0x3C: /* HSW */
1539 case 0x3F: /* HSX */ 1570 case 0x3F: /* HSX */
1540 case 0x45: /* HSW */ 1571 case 0x45: /* HSW */
1541 case 0x46: /* HSW */ 1572 case 0x46: /* HSW */
1542 case 0x37: /* BYT */
1543 case 0x4D: /* AVN */
1544 case 0x3D: /* BDW */ 1573 case 0x3D: /* BDW */
1545 case 0x4F: /* BDX */ 1574 case 0x4F: /* BDX */
1546 case 0x56: /* BDX-DE */ 1575 case 0x56: /* BDX-DE */
1547 case 0x2E: /* Nehalem-EX Xeon - Beckton */ 1576 pkg_cstate_limits = hsw_pkg_cstate_limits;
1548 case 0x2F: /* Westmere-EX Xeon - Eagleton */ 1577 break;
1549 return 1; 1578 case 0x37: /* BYT */
1579 case 0x4D: /* AVN */
1580 pkg_cstate_limits = slv_pkg_cstate_limits;
1581 break;
1582 case 0x4C: /* AMT */
1583 pkg_cstate_limits = amt_pkg_cstate_limits;
1584 break;
1585 case 0x57: /* PHI */
1586 pkg_cstate_limits = phi_pkg_cstate_limits;
1587 break;
1550 default: 1588 default:
1551 return 0; 1589 return 0;
1552 } 1590 }
1591 get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
1592
1593 pkg_cstate_limit = pkg_cstate_limits[msr & 0x7];
1594
1595 return 1;
1553} 1596}
1554int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) 1597int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
1555{ 1598{
1556 if (!has_nhm_msrs(family, model))
1557 return 0;
1558
1559 switch (model) { 1599 switch (model) {
1560 /* Nehalem compatible, but do not include turbo-ratio limit support */ 1600 /* Nehalem compatible, but do not include turbo-ratio limit support */
1561 case 0x2E: /* Nehalem-EX Xeon - Beckton */ 1601 case 0x2E: /* Nehalem-EX Xeon - Beckton */
@@ -2252,13 +2292,17 @@ void check_cpuid()
2252 do_ptm ? "" : "No ", 2292 do_ptm ? "" : "No ",
2253 has_epb ? "" : "No "); 2293 has_epb ? "" : "No ");
2254 2294
2255 do_nhm_platform_info = do_nhm_cstates = do_smi = has_nhm_msrs(family, model); 2295 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
2256 do_snb_cstates = has_snb_msrs(family, model); 2296 do_snb_cstates = has_snb_msrs(family, model);
2297 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
2298 do_pc3 = (pkg_cstate_limit >= PCL__3);
2299 do_pc6 = (pkg_cstate_limit >= PCL__6);
2300 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
2257 do_c8_c9_c10 = has_hsw_msrs(family, model); 2301 do_c8_c9_c10 = has_hsw_msrs(family, model);
2258 do_slm_cstates = is_slm(family, model); 2302 do_slm_cstates = is_slm(family, model);
2259 bclk = discover_bclk(family, model); 2303 bclk = discover_bclk(family, model);
2260 2304
2261 do_nhm_turbo_ratio_limit = has_nhm_turbo_ratio_limit(family, model); 2305 do_nhm_turbo_ratio_limit = do_nhm_platform_info && has_nhm_turbo_ratio_limit(family, model);
2262 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); 2306 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
2263 rapl_probe(family, model); 2307 rapl_probe(family, model);
2264 perf_limit_reasons_probe(family, model); 2308 perf_limit_reasons_probe(family, model);
@@ -2631,7 +2675,7 @@ int main(int argc, char **argv)
2631 cmdline(argc, argv); 2675 cmdline(argc, argv);
2632 2676
2633 if (verbose) 2677 if (verbose)
2634 fprintf(stderr, "turbostat v3.9 23-Jan, 2015" 2678 fprintf(stderr, "turbostat v3.10 9-Feb, 2015"
2635 " - Len Brown <lenb@kernel.org>\n"); 2679 " - Len Brown <lenb@kernel.org>\n");
2636 2680
2637 turbostat_init(); 2681 turbostat_init();