diff options
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 5 | ||||
| -rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 277 |
2 files changed, 223 insertions, 59 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index b599c7318aab..2986119dd31f 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -2596,6 +2596,9 @@ static int __init intel_pstate_init(void) | |||
| 2596 | const struct x86_cpu_id *id; | 2596 | const struct x86_cpu_id *id; |
| 2597 | int rc; | 2597 | int rc; |
| 2598 | 2598 | ||
| 2599 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | ||
| 2600 | return -ENODEV; | ||
| 2601 | |||
| 2599 | if (no_load) | 2602 | if (no_load) |
| 2600 | return -ENODEV; | 2603 | return -ENODEV; |
| 2601 | 2604 | ||
| @@ -2611,7 +2614,7 @@ static int __init intel_pstate_init(void) | |||
| 2611 | } else { | 2614 | } else { |
| 2612 | id = x86_match_cpu(intel_pstate_cpu_ids); | 2615 | id = x86_match_cpu(intel_pstate_cpu_ids); |
| 2613 | if (!id) { | 2616 | if (!id) { |
| 2614 | pr_info("CPU ID not supported\n"); | 2617 | pr_info("CPU model not supported\n"); |
| 2615 | return -ENODEV; | 2618 | return -ENODEV; |
| 2616 | } | 2619 | } |
| 2617 | 2620 | ||
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index c3fad065c89c..c7727be9719f 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <cpuid.h> | 44 | #include <cpuid.h> |
| 45 | #include <linux/capability.h> | 45 | #include <linux/capability.h> |
| 46 | #include <errno.h> | 46 | #include <errno.h> |
| 47 | #include <math.h> | ||
| 47 | 48 | ||
| 48 | char *proc_stat = "/proc/stat"; | 49 | char *proc_stat = "/proc/stat"; |
| 49 | FILE *outf; | 50 | FILE *outf; |
| @@ -63,7 +64,6 @@ unsigned int dump_only; | |||
| 63 | unsigned int do_snb_cstates; | 64 | unsigned int do_snb_cstates; |
| 64 | unsigned int do_knl_cstates; | 65 | unsigned int do_knl_cstates; |
| 65 | unsigned int do_slm_cstates; | 66 | unsigned int do_slm_cstates; |
| 66 | unsigned int do_cnl_cstates; | ||
| 67 | unsigned int use_c1_residency_msr; | 67 | unsigned int use_c1_residency_msr; |
| 68 | unsigned int has_aperf; | 68 | unsigned int has_aperf; |
| 69 | unsigned int has_epb; | 69 | unsigned int has_epb; |
| @@ -141,9 +141,21 @@ unsigned int first_counter_read = 1; | |||
| 141 | 141 | ||
| 142 | #define RAPL_CORES_ENERGY_STATUS (1 << 9) | 142 | #define RAPL_CORES_ENERGY_STATUS (1 << 9) |
| 143 | /* 0x639 MSR_PP0_ENERGY_STATUS */ | 143 | /* 0x639 MSR_PP0_ENERGY_STATUS */ |
| 144 | #define RAPL_PER_CORE_ENERGY (1 << 10) | ||
| 145 | /* Indicates cores energy collection is per-core, | ||
| 146 | * not per-package. */ | ||
| 147 | #define RAPL_AMD_F17H (1 << 11) | ||
| 148 | /* 0xc0010299 MSR_RAPL_PWR_UNIT */ | ||
| 149 | /* 0xc001029a MSR_CORE_ENERGY_STAT */ | ||
| 150 | /* 0xc001029b MSR_PKG_ENERGY_STAT */ | ||
| 144 | #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) | 151 | #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) |
| 145 | #define TJMAX_DEFAULT 100 | 152 | #define TJMAX_DEFAULT 100 |
| 146 | 153 | ||
| 154 | /* MSRs that are not yet in the kernel-provided header. */ | ||
| 155 | #define MSR_RAPL_PWR_UNIT 0xc0010299 | ||
| 156 | #define MSR_CORE_ENERGY_STAT 0xc001029a | ||
| 157 | #define MSR_PKG_ENERGY_STAT 0xc001029b | ||
| 158 | |||
| 147 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 159 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
| 148 | 160 | ||
| 149 | /* | 161 | /* |
| @@ -187,6 +199,7 @@ struct core_data { | |||
| 187 | unsigned long long c7; | 199 | unsigned long long c7; |
| 188 | unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */ | 200 | unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */ |
| 189 | unsigned int core_temp_c; | 201 | unsigned int core_temp_c; |
| 202 | unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */ | ||
| 190 | unsigned int core_id; | 203 | unsigned int core_id; |
| 191 | unsigned long long counter[MAX_ADDED_COUNTERS]; | 204 | unsigned long long counter[MAX_ADDED_COUNTERS]; |
| 192 | } *core_even, *core_odd; | 205 | } *core_even, *core_odd; |
| @@ -273,6 +286,7 @@ struct system_summary { | |||
| 273 | 286 | ||
| 274 | struct cpu_topology { | 287 | struct cpu_topology { |
| 275 | int physical_package_id; | 288 | int physical_package_id; |
| 289 | int die_id; | ||
| 276 | int logical_cpu_id; | 290 | int logical_cpu_id; |
| 277 | int physical_node_id; | 291 | int physical_node_id; |
| 278 | int logical_node_id; /* 0-based count within the package */ | 292 | int logical_node_id; /* 0-based count within the package */ |
| @@ -283,6 +297,7 @@ struct cpu_topology { | |||
| 283 | 297 | ||
| 284 | struct topo_params { | 298 | struct topo_params { |
| 285 | int num_packages; | 299 | int num_packages; |
| 300 | int num_die; | ||
| 286 | int num_cpus; | 301 | int num_cpus; |
| 287 | int num_cores; | 302 | int num_cores; |
| 288 | int max_cpu_num; | 303 | int max_cpu_num; |
| @@ -314,9 +329,8 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg | |||
| 314 | int retval, pkg_no, core_no, thread_no, node_no; | 329 | int retval, pkg_no, core_no, thread_no, node_no; |
| 315 | 330 | ||
| 316 | for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { | 331 | for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { |
| 317 | for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { | 332 | for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) { |
| 318 | for (node_no = 0; node_no < topo.nodes_per_pkg; | 333 | for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { |
| 319 | node_no++) { | ||
| 320 | for (thread_no = 0; thread_no < | 334 | for (thread_no = 0; thread_no < |
| 321 | topo.threads_per_core; ++thread_no) { | 335 | topo.threads_per_core; ++thread_no) { |
| 322 | struct thread_data *t; | 336 | struct thread_data *t; |
| @@ -442,6 +456,7 @@ struct msr_counter bic[] = { | |||
| 442 | { 0x0, "CPU" }, | 456 | { 0x0, "CPU" }, |
| 443 | { 0x0, "APIC" }, | 457 | { 0x0, "APIC" }, |
| 444 | { 0x0, "X2APIC" }, | 458 | { 0x0, "X2APIC" }, |
| 459 | { 0x0, "Die" }, | ||
| 445 | }; | 460 | }; |
| 446 | 461 | ||
| 447 | #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) | 462 | #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) |
| @@ -495,6 +510,7 @@ struct msr_counter bic[] = { | |||
| 495 | #define BIC_CPU (1ULL << 47) | 510 | #define BIC_CPU (1ULL << 47) |
| 496 | #define BIC_APIC (1ULL << 48) | 511 | #define BIC_APIC (1ULL << 48) |
| 497 | #define BIC_X2APIC (1ULL << 49) | 512 | #define BIC_X2APIC (1ULL << 49) |
| 513 | #define BIC_Die (1ULL << 50) | ||
| 498 | 514 | ||
| 499 | #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) | 515 | #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) |
| 500 | 516 | ||
| @@ -621,6 +637,8 @@ void print_header(char *delim) | |||
| 621 | outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : "")); | 637 | outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : "")); |
| 622 | if (DO_BIC(BIC_Package)) | 638 | if (DO_BIC(BIC_Package)) |
| 623 | outp += sprintf(outp, "%sPackage", (printed++ ? delim : "")); | 639 | outp += sprintf(outp, "%sPackage", (printed++ ? delim : "")); |
| 640 | if (DO_BIC(BIC_Die)) | ||
| 641 | outp += sprintf(outp, "%sDie", (printed++ ? delim : "")); | ||
| 624 | if (DO_BIC(BIC_Node)) | 642 | if (DO_BIC(BIC_Node)) |
| 625 | outp += sprintf(outp, "%sNode", (printed++ ? delim : "")); | 643 | outp += sprintf(outp, "%sNode", (printed++ ? delim : "")); |
| 626 | if (DO_BIC(BIC_Core)) | 644 | if (DO_BIC(BIC_Core)) |
| @@ -667,7 +685,7 @@ void print_header(char *delim) | |||
| 667 | 685 | ||
| 668 | if (DO_BIC(BIC_CPU_c1)) | 686 | if (DO_BIC(BIC_CPU_c1)) |
| 669 | outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : "")); | 687 | outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : "")); |
| 670 | if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) | 688 | if (DO_BIC(BIC_CPU_c3)) |
| 671 | outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : "")); | 689 | outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : "")); |
| 672 | if (DO_BIC(BIC_CPU_c6)) | 690 | if (DO_BIC(BIC_CPU_c6)) |
| 673 | outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : "")); | 691 | outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : "")); |
| @@ -680,6 +698,14 @@ void print_header(char *delim) | |||
| 680 | if (DO_BIC(BIC_CoreTmp)) | 698 | if (DO_BIC(BIC_CoreTmp)) |
| 681 | outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : "")); | 699 | outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : "")); |
| 682 | 700 | ||
| 701 | if (do_rapl && !rapl_joules) { | ||
| 702 | if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 703 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); | ||
| 704 | } else if (do_rapl && rapl_joules) { | ||
| 705 | if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 706 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); | ||
| 707 | } | ||
| 708 | |||
| 683 | for (mp = sys.cp; mp; mp = mp->next) { | 709 | for (mp = sys.cp; mp; mp = mp->next) { |
| 684 | if (mp->format == FORMAT_RAW) { | 710 | if (mp->format == FORMAT_RAW) { |
| 685 | if (mp->width == 64) | 711 | if (mp->width == 64) |
| @@ -734,7 +760,7 @@ void print_header(char *delim) | |||
| 734 | if (do_rapl && !rapl_joules) { | 760 | if (do_rapl && !rapl_joules) { |
| 735 | if (DO_BIC(BIC_PkgWatt)) | 761 | if (DO_BIC(BIC_PkgWatt)) |
| 736 | outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : "")); | 762 | outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : "")); |
| 737 | if (DO_BIC(BIC_CorWatt)) | 763 | if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 738 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); | 764 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); |
| 739 | if (DO_BIC(BIC_GFXWatt)) | 765 | if (DO_BIC(BIC_GFXWatt)) |
| 740 | outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : "")); | 766 | outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : "")); |
| @@ -747,7 +773,7 @@ void print_header(char *delim) | |||
| 747 | } else if (do_rapl && rapl_joules) { | 773 | } else if (do_rapl && rapl_joules) { |
| 748 | if (DO_BIC(BIC_Pkg_J)) | 774 | if (DO_BIC(BIC_Pkg_J)) |
| 749 | outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : "")); | 775 | outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : "")); |
| 750 | if (DO_BIC(BIC_Cor_J)) | 776 | if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 751 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); | 777 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); |
| 752 | if (DO_BIC(BIC_GFX_J)) | 778 | if (DO_BIC(BIC_GFX_J)) |
| 753 | outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : "")); | 779 | outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : "")); |
| @@ -808,6 +834,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, | |||
| 808 | outp += sprintf(outp, "c6: %016llX\n", c->c6); | 834 | outp += sprintf(outp, "c6: %016llX\n", c->c6); |
| 809 | outp += sprintf(outp, "c7: %016llX\n", c->c7); | 835 | outp += sprintf(outp, "c7: %016llX\n", c->c7); |
| 810 | outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); | 836 | outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); |
| 837 | outp += sprintf(outp, "Joules: %0X\n", c->core_energy); | ||
| 811 | 838 | ||
| 812 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 839 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 813 | outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", | 840 | outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", |
| @@ -904,6 +931,8 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 904 | if (t == &average.threads) { | 931 | if (t == &average.threads) { |
| 905 | if (DO_BIC(BIC_Package)) | 932 | if (DO_BIC(BIC_Package)) |
| 906 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | 933 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
| 934 | if (DO_BIC(BIC_Die)) | ||
| 935 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | ||
| 907 | if (DO_BIC(BIC_Node)) | 936 | if (DO_BIC(BIC_Node)) |
| 908 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | 937 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
| 909 | if (DO_BIC(BIC_Core)) | 938 | if (DO_BIC(BIC_Core)) |
| @@ -921,6 +950,12 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 921 | else | 950 | else |
| 922 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | 951 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
| 923 | } | 952 | } |
| 953 | if (DO_BIC(BIC_Die)) { | ||
| 954 | if (c) | ||
| 955 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].die_id); | ||
| 956 | else | ||
| 957 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); | ||
| 958 | } | ||
| 924 | if (DO_BIC(BIC_Node)) { | 959 | if (DO_BIC(BIC_Node)) { |
| 925 | if (t) | 960 | if (t) |
| 926 | outp += sprintf(outp, "%s%d", | 961 | outp += sprintf(outp, "%s%d", |
| @@ -1003,7 +1038,7 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1003 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) | 1038 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
| 1004 | goto done; | 1039 | goto done; |
| 1005 | 1040 | ||
| 1006 | if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) | 1041 | if (DO_BIC(BIC_CPU_c3)) |
| 1007 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc); | 1042 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc); |
| 1008 | if (DO_BIC(BIC_CPU_c6)) | 1043 | if (DO_BIC(BIC_CPU_c6)) |
| 1009 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc); | 1044 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc); |
| @@ -1033,6 +1068,20 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1033 | } | 1068 | } |
| 1034 | } | 1069 | } |
| 1035 | 1070 | ||
| 1071 | /* | ||
| 1072 | * If measurement interval exceeds minimum RAPL Joule Counter range, | ||
| 1073 | * indicate that results are suspect by printing "**" in fraction place. | ||
| 1074 | */ | ||
| 1075 | if (interval_float < rapl_joule_counter_range) | ||
| 1076 | fmt8 = "%s%.2f"; | ||
| 1077 | else | ||
| 1078 | fmt8 = "%6.0f**"; | ||
| 1079 | |||
| 1080 | if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 1081 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float); | ||
| 1082 | if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) | ||
| 1083 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units); | ||
| 1084 | |||
| 1036 | /* print per-package data only for 1st core in package */ | 1085 | /* print per-package data only for 1st core in package */ |
| 1037 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) | 1086 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) |
| 1038 | goto done; | 1087 | goto done; |
| @@ -1085,18 +1134,9 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1085 | if (DO_BIC(BIC_SYS_LPI)) | 1134 | if (DO_BIC(BIC_SYS_LPI)) |
| 1086 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float); | 1135 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float); |
| 1087 | 1136 | ||
| 1088 | /* | ||
| 1089 | * If measurement interval exceeds minimum RAPL Joule Counter range, | ||
| 1090 | * indicate that results are suspect by printing "**" in fraction place. | ||
| 1091 | */ | ||
| 1092 | if (interval_float < rapl_joule_counter_range) | ||
| 1093 | fmt8 = "%s%.2f"; | ||
| 1094 | else | ||
| 1095 | fmt8 = "%6.0f**"; | ||
| 1096 | |||
| 1097 | if (DO_BIC(BIC_PkgWatt)) | 1137 | if (DO_BIC(BIC_PkgWatt)) |
| 1098 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float); | 1138 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float); |
| 1099 | if (DO_BIC(BIC_CorWatt)) | 1139 | if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 1100 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float); | 1140 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float); |
| 1101 | if (DO_BIC(BIC_GFXWatt)) | 1141 | if (DO_BIC(BIC_GFXWatt)) |
| 1102 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float); | 1142 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float); |
| @@ -1104,7 +1144,7 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
| 1104 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float); | 1144 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float); |
| 1105 | if (DO_BIC(BIC_Pkg_J)) | 1145 | if (DO_BIC(BIC_Pkg_J)) |
| 1106 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units); | 1146 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units); |
| 1107 | if (DO_BIC(BIC_Cor_J)) | 1147 | if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
| 1108 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units); | 1148 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units); |
| 1109 | if (DO_BIC(BIC_GFX_J)) | 1149 | if (DO_BIC(BIC_GFX_J)) |
| 1110 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units); | 1150 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units); |
| @@ -1249,6 +1289,8 @@ delta_core(struct core_data *new, struct core_data *old) | |||
| 1249 | old->core_temp_c = new->core_temp_c; | 1289 | old->core_temp_c = new->core_temp_c; |
| 1250 | old->mc6_us = new->mc6_us - old->mc6_us; | 1290 | old->mc6_us = new->mc6_us - old->mc6_us; |
| 1251 | 1291 | ||
| 1292 | DELTA_WRAP32(new->core_energy, old->core_energy); | ||
| 1293 | |||
| 1252 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 1294 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 1253 | if (mp->format == FORMAT_RAW) | 1295 | if (mp->format == FORMAT_RAW) |
| 1254 | old->counter[i] = new->counter[i]; | 1296 | old->counter[i] = new->counter[i]; |
| @@ -1391,6 +1433,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data | |||
| 1391 | c->c7 = 0; | 1433 | c->c7 = 0; |
| 1392 | c->mc6_us = 0; | 1434 | c->mc6_us = 0; |
| 1393 | c->core_temp_c = 0; | 1435 | c->core_temp_c = 0; |
| 1436 | c->core_energy = 0; | ||
| 1394 | 1437 | ||
| 1395 | p->pkg_wtd_core_c0 = 0; | 1438 | p->pkg_wtd_core_c0 = 0; |
| 1396 | p->pkg_any_core_c0 = 0; | 1439 | p->pkg_any_core_c0 = 0; |
| @@ -1473,6 +1516,8 @@ int sum_counters(struct thread_data *t, struct core_data *c, | |||
| 1473 | 1516 | ||
| 1474 | average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); | 1517 | average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); |
| 1475 | 1518 | ||
| 1519 | average.cores.core_energy += c->core_energy; | ||
| 1520 | |||
| 1476 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 1521 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 1477 | if (mp->format == FORMAT_RAW) | 1522 | if (mp->format == FORMAT_RAW) |
| 1478 | continue; | 1523 | continue; |
| @@ -1818,7 +1863,7 @@ retry: | |||
| 1818 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) | 1863 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
| 1819 | goto done; | 1864 | goto done; |
| 1820 | 1865 | ||
| 1821 | if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) { | 1866 | if (DO_BIC(BIC_CPU_c3)) { |
| 1822 | if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) | 1867 | if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) |
| 1823 | return -6; | 1868 | return -6; |
| 1824 | } | 1869 | } |
| @@ -1845,6 +1890,12 @@ retry: | |||
| 1845 | c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); | 1890 | c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); |
| 1846 | } | 1891 | } |
| 1847 | 1892 | ||
| 1893 | if (do_rapl & RAPL_AMD_F17H) { | ||
| 1894 | if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr)) | ||
| 1895 | return -14; | ||
| 1896 | c->core_energy = msr & 0xFFFFFFFF; | ||
| 1897 | } | ||
| 1898 | |||
| 1848 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { | 1899 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
| 1849 | if (get_mp(cpu, mp, &c->counter[i])) | 1900 | if (get_mp(cpu, mp, &c->counter[i])) |
| 1850 | return -10; | 1901 | return -10; |
| @@ -1934,6 +1985,11 @@ retry: | |||
| 1934 | return -16; | 1985 | return -16; |
| 1935 | p->rapl_dram_perf_status = msr & 0xFFFFFFFF; | 1986 | p->rapl_dram_perf_status = msr & 0xFFFFFFFF; |
| 1936 | } | 1987 | } |
| 1988 | if (do_rapl & RAPL_AMD_F17H) { | ||
| 1989 | if (get_msr(cpu, MSR_PKG_ENERGY_STAT, &msr)) | ||
| 1990 | return -13; | ||
| 1991 | p->energy_pkg = msr & 0xFFFFFFFF; | ||
| 1992 | } | ||
| 1937 | if (DO_BIC(BIC_PkgTmp)) { | 1993 | if (DO_BIC(BIC_PkgTmp)) { |
| 1938 | if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) | 1994 | if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) |
| 1939 | return -17; | 1995 | return -17; |
| @@ -2456,6 +2512,8 @@ void free_all_buffers(void) | |||
| 2456 | 2512 | ||
| 2457 | /* | 2513 | /* |
| 2458 | * Parse a file containing a single int. | 2514 | * Parse a file containing a single int. |
| 2515 | * Return 0 if file can not be opened | ||
| 2516 | * Exit if file can be opened, but can not be parsed | ||
| 2459 | */ | 2517 | */ |
| 2460 | int parse_int_file(const char *fmt, ...) | 2518 | int parse_int_file(const char *fmt, ...) |
| 2461 | { | 2519 | { |
| @@ -2467,7 +2525,9 @@ int parse_int_file(const char *fmt, ...) | |||
| 2467 | va_start(args, fmt); | 2525 | va_start(args, fmt); |
| 2468 | vsnprintf(path, sizeof(path), fmt, args); | 2526 | vsnprintf(path, sizeof(path), fmt, args); |
| 2469 | va_end(args); | 2527 | va_end(args); |
| 2470 | filep = fopen_or_die(path, "r"); | 2528 | filep = fopen(path, "r"); |
| 2529 | if (!filep) | ||
| 2530 | return 0; | ||
| 2471 | if (fscanf(filep, "%d", &value) != 1) | 2531 | if (fscanf(filep, "%d", &value) != 1) |
| 2472 | err(1, "%s: failed to parse number from file", path); | 2532 | err(1, "%s: failed to parse number from file", path); |
| 2473 | fclose(filep); | 2533 | fclose(filep); |
| @@ -2488,6 +2548,11 @@ int get_physical_package_id(int cpu) | |||
| 2488 | return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); | 2548 | return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); |
| 2489 | } | 2549 | } |
| 2490 | 2550 | ||
| 2551 | int get_die_id(int cpu) | ||
| 2552 | { | ||
| 2553 | return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/die_id", cpu); | ||
| 2554 | } | ||
| 2555 | |||
| 2491 | int get_core_id(int cpu) | 2556 | int get_core_id(int cpu) |
| 2492 | { | 2557 | { |
| 2493 | return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); | 2558 | return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); |
| @@ -2578,7 +2643,8 @@ int get_thread_siblings(struct cpu_topology *thiscpu) | |||
| 2578 | filep = fopen_or_die(path, "r"); | 2643 | filep = fopen_or_die(path, "r"); |
| 2579 | do { | 2644 | do { |
| 2580 | offset -= BITMASK_SIZE; | 2645 | offset -= BITMASK_SIZE; |
| 2581 | fscanf(filep, "%lx%c", &map, &character); | 2646 | if (fscanf(filep, "%lx%c", &map, &character) != 2) |
| 2647 | err(1, "%s: failed to parse file", path); | ||
| 2582 | for (shift = 0; shift < BITMASK_SIZE; shift++) { | 2648 | for (shift = 0; shift < BITMASK_SIZE; shift++) { |
| 2583 | if ((map >> shift) & 0x1) { | 2649 | if ((map >> shift) & 0x1) { |
| 2584 | so = shift + offset; | 2650 | so = shift + offset; |
| @@ -2855,8 +2921,11 @@ int snapshot_cpu_lpi_us(void) | |||
| 2855 | fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r"); | 2921 | fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r"); |
| 2856 | 2922 | ||
| 2857 | retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us); | 2923 | retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us); |
| 2858 | if (retval != 1) | 2924 | if (retval != 1) { |
| 2859 | err(1, "CPU LPI"); | 2925 | fprintf(stderr, "Disabling Low Power Idle CPU output\n"); |
| 2926 | BIC_NOT_PRESENT(BIC_CPU_LPI); | ||
| 2927 | return -1; | ||
| 2928 | } | ||
| 2860 | 2929 | ||
| 2861 | fclose(fp); | 2930 | fclose(fp); |
| 2862 | 2931 | ||
| @@ -2878,9 +2947,11 @@ int snapshot_sys_lpi_us(void) | |||
| 2878 | fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r"); | 2947 | fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r"); |
| 2879 | 2948 | ||
| 2880 | retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); | 2949 | retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); |
| 2881 | if (retval != 1) | 2950 | if (retval != 1) { |
| 2882 | err(1, "SYS LPI"); | 2951 | fprintf(stderr, "Disabling Low Power Idle System output\n"); |
| 2883 | 2952 | BIC_NOT_PRESENT(BIC_SYS_LPI); | |
| 2953 | return -1; | ||
| 2954 | } | ||
| 2884 | fclose(fp); | 2955 | fclose(fp); |
| 2885 | 2956 | ||
| 2886 | return 0; | 2957 | return 0; |
| @@ -3410,14 +3481,14 @@ dump_sysfs_cstate_config(void) | |||
| 3410 | input = fopen(path, "r"); | 3481 | input = fopen(path, "r"); |
| 3411 | if (input == NULL) | 3482 | if (input == NULL) |
| 3412 | continue; | 3483 | continue; |
| 3413 | fgets(name_buf, sizeof(name_buf), input); | 3484 | if (!fgets(name_buf, sizeof(name_buf), input)) |
| 3485 | err(1, "%s: failed to read file", path); | ||
| 3414 | 3486 | ||
| 3415 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ | 3487 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ |
| 3416 | sp = strchr(name_buf, '-'); | 3488 | sp = strchr(name_buf, '-'); |
| 3417 | if (!sp) | 3489 | if (!sp) |
| 3418 | sp = strchrnul(name_buf, '\n'); | 3490 | sp = strchrnul(name_buf, '\n'); |
| 3419 | *sp = '\0'; | 3491 | *sp = '\0'; |
| 3420 | |||
| 3421 | fclose(input); | 3492 | fclose(input); |
| 3422 | 3493 | ||
| 3423 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", | 3494 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", |
| @@ -3425,7 +3496,8 @@ dump_sysfs_cstate_config(void) | |||
| 3425 | input = fopen(path, "r"); | 3496 | input = fopen(path, "r"); |
| 3426 | if (input == NULL) | 3497 | if (input == NULL) |
| 3427 | continue; | 3498 | continue; |
| 3428 | fgets(desc, sizeof(desc), input); | 3499 | if (!fgets(desc, sizeof(desc), input)) |
| 3500 | err(1, "%s: failed to read file", path); | ||
| 3429 | 3501 | ||
| 3430 | fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc); | 3502 | fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc); |
| 3431 | fclose(input); | 3503 | fclose(input); |
| @@ -3444,20 +3516,22 @@ dump_sysfs_pstate_config(void) | |||
| 3444 | base_cpu); | 3516 | base_cpu); |
| 3445 | input = fopen(path, "r"); | 3517 | input = fopen(path, "r"); |
| 3446 | if (input == NULL) { | 3518 | if (input == NULL) { |
| 3447 | fprintf(stderr, "NSFOD %s\n", path); | 3519 | fprintf(outf, "NSFOD %s\n", path); |
| 3448 | return; | 3520 | return; |
| 3449 | } | 3521 | } |
| 3450 | fgets(driver_buf, sizeof(driver_buf), input); | 3522 | if (!fgets(driver_buf, sizeof(driver_buf), input)) |
| 3523 | err(1, "%s: failed to read file", path); | ||
| 3451 | fclose(input); | 3524 | fclose(input); |
| 3452 | 3525 | ||
| 3453 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", | 3526 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", |
| 3454 | base_cpu); | 3527 | base_cpu); |
| 3455 | input = fopen(path, "r"); | 3528 | input = fopen(path, "r"); |
| 3456 | if (input == NULL) { | 3529 | if (input == NULL) { |
| 3457 | fprintf(stderr, "NSFOD %s\n", path); | 3530 | fprintf(outf, "NSFOD %s\n", path); |
| 3458 | return; | 3531 | return; |
| 3459 | } | 3532 | } |
| 3460 | fgets(governor_buf, sizeof(governor_buf), input); | 3533 | if (!fgets(governor_buf, sizeof(governor_buf), input)) |
| 3534 | err(1, "%s: failed to read file", path); | ||
| 3461 | fclose(input); | 3535 | fclose(input); |
| 3462 | 3536 | ||
| 3463 | fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf); | 3537 | fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf); |
| @@ -3466,7 +3540,8 @@ dump_sysfs_pstate_config(void) | |||
| 3466 | sprintf(path, "/sys/devices/system/cpu/cpufreq/boost"); | 3540 | sprintf(path, "/sys/devices/system/cpu/cpufreq/boost"); |
| 3467 | input = fopen(path, "r"); | 3541 | input = fopen(path, "r"); |
| 3468 | if (input != NULL) { | 3542 | if (input != NULL) { |
| 3469 | fscanf(input, "%d", &turbo); | 3543 | if (fscanf(input, "%d", &turbo) != 1) |
| 3544 | err(1, "%s: failed to parse number from file", path); | ||
| 3470 | fprintf(outf, "cpufreq boost: %d\n", turbo); | 3545 | fprintf(outf, "cpufreq boost: %d\n", turbo); |
| 3471 | fclose(input); | 3546 | fclose(input); |
| 3472 | } | 3547 | } |
| @@ -3474,7 +3549,8 @@ dump_sysfs_pstate_config(void) | |||
| 3474 | sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo"); | 3549 | sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo"); |
| 3475 | input = fopen(path, "r"); | 3550 | input = fopen(path, "r"); |
| 3476 | if (input != NULL) { | 3551 | if (input != NULL) { |
| 3477 | fscanf(input, "%d", &turbo); | 3552 | if (fscanf(input, "%d", &turbo) != 1) |
| 3553 | err(1, "%s: failed to parse number from file", path); | ||
| 3478 | fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo); | 3554 | fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo); |
| 3479 | fclose(input); | 3555 | fclose(input); |
| 3480 | } | 3556 | } |
| @@ -3718,7 +3794,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data | |||
| 3718 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ | 3794 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
| 3719 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ | 3795 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
| 3720 | 3796 | ||
| 3721 | double get_tdp(unsigned int model) | 3797 | double get_tdp_intel(unsigned int model) |
| 3722 | { | 3798 | { |
| 3723 | unsigned long long msr; | 3799 | unsigned long long msr; |
| 3724 | 3800 | ||
| @@ -3735,6 +3811,16 @@ double get_tdp(unsigned int model) | |||
| 3735 | } | 3811 | } |
| 3736 | } | 3812 | } |
| 3737 | 3813 | ||
| 3814 | double get_tdp_amd(unsigned int family) | ||
| 3815 | { | ||
| 3816 | switch (family) { | ||
| 3817 | case 0x17: | ||
| 3818 | default: | ||
| 3819 | /* This is the max stock TDP of HEDT/Server Fam17h chips */ | ||
| 3820 | return 250.0; | ||
| 3821 | } | ||
| 3822 | } | ||
| 3823 | |||
| 3738 | /* | 3824 | /* |
| 3739 | * rapl_dram_energy_units_probe() | 3825 | * rapl_dram_energy_units_probe() |
| 3740 | * Energy units are either hard-coded, or come from RAPL Energy Unit MSR. | 3826 | * Energy units are either hard-coded, or come from RAPL Energy Unit MSR. |
| @@ -3754,21 +3840,12 @@ rapl_dram_energy_units_probe(int model, double rapl_energy_units) | |||
| 3754 | } | 3840 | } |
| 3755 | } | 3841 | } |
| 3756 | 3842 | ||
| 3757 | 3843 | void rapl_probe_intel(unsigned int family, unsigned int model) | |
| 3758 | /* | ||
| 3759 | * rapl_probe() | ||
| 3760 | * | ||
| 3761 | * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units | ||
| 3762 | */ | ||
| 3763 | void rapl_probe(unsigned int family, unsigned int model) | ||
| 3764 | { | 3844 | { |
| 3765 | unsigned long long msr; | 3845 | unsigned long long msr; |
| 3766 | unsigned int time_unit; | 3846 | unsigned int time_unit; |
| 3767 | double tdp; | 3847 | double tdp; |
| 3768 | 3848 | ||
| 3769 | if (!genuine_intel) | ||
| 3770 | return; | ||
| 3771 | |||
| 3772 | if (family != 6) | 3849 | if (family != 6) |
| 3773 | return; | 3850 | return; |
| 3774 | 3851 | ||
| @@ -3892,13 +3969,69 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
| 3892 | 3969 | ||
| 3893 | rapl_time_units = 1.0 / (1 << (time_unit)); | 3970 | rapl_time_units = 1.0 / (1 << (time_unit)); |
| 3894 | 3971 | ||
| 3895 | tdp = get_tdp(model); | 3972 | tdp = get_tdp_intel(model); |
| 3896 | 3973 | ||
| 3897 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; | 3974 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; |
| 3898 | if (!quiet) | 3975 | if (!quiet) |
| 3899 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); | 3976 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); |
| 3977 | } | ||
| 3900 | 3978 | ||
| 3901 | return; | 3979 | void rapl_probe_amd(unsigned int family, unsigned int model) |
| 3980 | { | ||
| 3981 | unsigned long long msr; | ||
| 3982 | unsigned int eax, ebx, ecx, edx; | ||
| 3983 | unsigned int has_rapl = 0; | ||
| 3984 | double tdp; | ||
| 3985 | |||
| 3986 | if (max_extended_level >= 0x80000007) { | ||
| 3987 | __cpuid(0x80000007, eax, ebx, ecx, edx); | ||
| 3988 | /* RAPL (Fam 17h) */ | ||
| 3989 | has_rapl = edx & (1 << 14); | ||
| 3990 | } | ||
| 3991 | |||
| 3992 | if (!has_rapl) | ||
| 3993 | return; | ||
| 3994 | |||
| 3995 | switch (family) { | ||
| 3996 | case 0x17: /* Zen, Zen+ */ | ||
| 3997 | do_rapl = RAPL_AMD_F17H | RAPL_PER_CORE_ENERGY; | ||
| 3998 | if (rapl_joules) { | ||
| 3999 | BIC_PRESENT(BIC_Pkg_J); | ||
| 4000 | BIC_PRESENT(BIC_Cor_J); | ||
| 4001 | } else { | ||
| 4002 | BIC_PRESENT(BIC_PkgWatt); | ||
| 4003 | BIC_PRESENT(BIC_CorWatt); | ||
| 4004 | } | ||
| 4005 | break; | ||
| 4006 | default: | ||
| 4007 | return; | ||
| 4008 | } | ||
| 4009 | |||
| 4010 | if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr)) | ||
| 4011 | return; | ||
| 4012 | |||
| 4013 | rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf)); | ||
| 4014 | rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f)); | ||
| 4015 | rapl_power_units = ldexp(1.0, -(msr & 0xf)); | ||
| 4016 | |||
| 4017 | tdp = get_tdp_amd(model); | ||
| 4018 | |||
| 4019 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; | ||
| 4020 | if (!quiet) | ||
| 4021 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); | ||
| 4022 | } | ||
| 4023 | |||
| 4024 | /* | ||
| 4025 | * rapl_probe() | ||
| 4026 | * | ||
| 4027 | * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units | ||
| 4028 | */ | ||
| 4029 | void rapl_probe(unsigned int family, unsigned int model) | ||
| 4030 | { | ||
| 4031 | if (genuine_intel) | ||
| 4032 | rapl_probe_intel(family, model); | ||
| 4033 | if (authentic_amd) | ||
| 4034 | rapl_probe_amd(family, model); | ||
| 3902 | } | 4035 | } |
| 3903 | 4036 | ||
| 3904 | void perf_limit_reasons_probe(unsigned int family, unsigned int model) | 4037 | void perf_limit_reasons_probe(unsigned int family, unsigned int model) |
| @@ -4003,6 +4136,7 @@ void print_power_limit_msr(int cpu, unsigned long long msr, char *label) | |||
| 4003 | int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | 4136 | int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) |
| 4004 | { | 4137 | { |
| 4005 | unsigned long long msr; | 4138 | unsigned long long msr; |
| 4139 | const char *msr_name; | ||
| 4006 | int cpu; | 4140 | int cpu; |
| 4007 | 4141 | ||
| 4008 | if (!do_rapl) | 4142 | if (!do_rapl) |
| @@ -4018,10 +4152,17 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
| 4018 | return -1; | 4152 | return -1; |
| 4019 | } | 4153 | } |
| 4020 | 4154 | ||
| 4021 | if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) | 4155 | if (do_rapl & RAPL_AMD_F17H) { |
| 4022 | return -1; | 4156 | msr_name = "MSR_RAPL_PWR_UNIT"; |
| 4157 | if (get_msr(cpu, MSR_RAPL_PWR_UNIT, &msr)) | ||
| 4158 | return -1; | ||
| 4159 | } else { | ||
| 4160 | msr_name = "MSR_RAPL_POWER_UNIT"; | ||
| 4161 | if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) | ||
| 4162 | return -1; | ||
| 4163 | } | ||
| 4023 | 4164 | ||
| 4024 | fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr, | 4165 | fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr, |
| 4025 | rapl_power_units, rapl_energy_units, rapl_time_units); | 4166 | rapl_power_units, rapl_energy_units, rapl_time_units); |
| 4026 | 4167 | ||
| 4027 | if (do_rapl & RAPL_PKG_POWER_INFO) { | 4168 | if (do_rapl & RAPL_PKG_POWER_INFO) { |
| @@ -4451,6 +4592,9 @@ unsigned int intel_model_duplicates(unsigned int model) | |||
| 4451 | case INTEL_FAM6_KABYLAKE_MOBILE: | 4592 | case INTEL_FAM6_KABYLAKE_MOBILE: |
| 4452 | case INTEL_FAM6_KABYLAKE_DESKTOP: | 4593 | case INTEL_FAM6_KABYLAKE_DESKTOP: |
| 4453 | return INTEL_FAM6_SKYLAKE_MOBILE; | 4594 | return INTEL_FAM6_SKYLAKE_MOBILE; |
| 4595 | |||
| 4596 | case INTEL_FAM6_ICELAKE_MOBILE: | ||
| 4597 | return INTEL_FAM6_CANNONLAKE_MOBILE; | ||
| 4454 | } | 4598 | } |
| 4455 | return model; | 4599 | return model; |
| 4456 | } | 4600 | } |
| @@ -4702,7 +4846,9 @@ void process_cpuid() | |||
| 4702 | } | 4846 | } |
| 4703 | do_slm_cstates = is_slm(family, model); | 4847 | do_slm_cstates = is_slm(family, model); |
| 4704 | do_knl_cstates = is_knl(family, model); | 4848 | do_knl_cstates = is_knl(family, model); |
| 4705 | do_cnl_cstates = is_cnl(family, model); | 4849 | |
| 4850 | if (do_slm_cstates || do_knl_cstates || is_cnl(family, model)) | ||
| 4851 | BIC_NOT_PRESENT(BIC_CPU_c3); | ||
| 4706 | 4852 | ||
| 4707 | if (!quiet) | 4853 | if (!quiet) |
| 4708 | decode_misc_pwr_mgmt_msr(); | 4854 | decode_misc_pwr_mgmt_msr(); |
| @@ -4769,6 +4915,7 @@ void topology_probe() | |||
| 4769 | int i; | 4915 | int i; |
| 4770 | int max_core_id = 0; | 4916 | int max_core_id = 0; |
| 4771 | int max_package_id = 0; | 4917 | int max_package_id = 0; |
| 4918 | int max_die_id = 0; | ||
| 4772 | int max_siblings = 0; | 4919 | int max_siblings = 0; |
| 4773 | 4920 | ||
| 4774 | /* Initialize num_cpus, max_cpu_num */ | 4921 | /* Initialize num_cpus, max_cpu_num */ |
| @@ -4835,6 +4982,11 @@ void topology_probe() | |||
| 4835 | if (cpus[i].physical_package_id > max_package_id) | 4982 | if (cpus[i].physical_package_id > max_package_id) |
| 4836 | max_package_id = cpus[i].physical_package_id; | 4983 | max_package_id = cpus[i].physical_package_id; |
| 4837 | 4984 | ||
| 4985 | /* get die information */ | ||
| 4986 | cpus[i].die_id = get_die_id(i); | ||
| 4987 | if (cpus[i].die_id > max_die_id) | ||
| 4988 | max_die_id = cpus[i].die_id; | ||
| 4989 | |||
| 4838 | /* get numa node information */ | 4990 | /* get numa node information */ |
| 4839 | cpus[i].physical_node_id = get_physical_node_id(&cpus[i]); | 4991 | cpus[i].physical_node_id = get_physical_node_id(&cpus[i]); |
| 4840 | if (cpus[i].physical_node_id > topo.max_node_num) | 4992 | if (cpus[i].physical_node_id > topo.max_node_num) |
| @@ -4860,6 +5012,13 @@ void topology_probe() | |||
| 4860 | if (!summary_only && topo.cores_per_node > 1) | 5012 | if (!summary_only && topo.cores_per_node > 1) |
| 4861 | BIC_PRESENT(BIC_Core); | 5013 | BIC_PRESENT(BIC_Core); |
| 4862 | 5014 | ||
| 5015 | topo.num_die = max_die_id + 1; | ||
| 5016 | if (debug > 1) | ||
| 5017 | fprintf(outf, "max_die_id %d, sizing for %d die\n", | ||
| 5018 | max_die_id, topo.num_die); | ||
| 5019 | if (!summary_only && topo.num_die > 1) | ||
| 5020 | BIC_PRESENT(BIC_Die); | ||
| 5021 | |||
| 4863 | topo.num_packages = max_package_id + 1; | 5022 | topo.num_packages = max_package_id + 1; |
| 4864 | if (debug > 1) | 5023 | if (debug > 1) |
| 4865 | fprintf(outf, "max_package_id %d, sizing for %d packages\n", | 5024 | fprintf(outf, "max_package_id %d, sizing for %d packages\n", |
| @@ -4884,8 +5043,8 @@ void topology_probe() | |||
| 4884 | if (cpu_is_not_present(i)) | 5043 | if (cpu_is_not_present(i)) |
| 4885 | continue; | 5044 | continue; |
| 4886 | fprintf(outf, | 5045 | fprintf(outf, |
| 4887 | "cpu %d pkg %d node %d lnode %d core %d thread %d\n", | 5046 | "cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n", |
| 4888 | i, cpus[i].physical_package_id, | 5047 | i, cpus[i].physical_package_id, cpus[i].die_id, |
| 4889 | cpus[i].physical_node_id, | 5048 | cpus[i].physical_node_id, |
| 4890 | cpus[i].logical_node_id, | 5049 | cpus[i].logical_node_id, |
| 4891 | cpus[i].physical_core_id, | 5050 | cpus[i].physical_core_id, |
| @@ -5122,7 +5281,7 @@ int get_and_dump_counters(void) | |||
| 5122 | } | 5281 | } |
| 5123 | 5282 | ||
| 5124 | void print_version() { | 5283 | void print_version() { |
| 5125 | fprintf(outf, "turbostat version 18.07.27" | 5284 | fprintf(outf, "turbostat version 19.03.20" |
| 5126 | " - Len Brown <lenb@kernel.org>\n"); | 5285 | " - Len Brown <lenb@kernel.org>\n"); |
| 5127 | } | 5286 | } |
| 5128 | 5287 | ||
| @@ -5319,7 +5478,8 @@ void probe_sysfs(void) | |||
| 5319 | input = fopen(path, "r"); | 5478 | input = fopen(path, "r"); |
| 5320 | if (input == NULL) | 5479 | if (input == NULL) |
| 5321 | continue; | 5480 | continue; |
| 5322 | fgets(name_buf, sizeof(name_buf), input); | 5481 | if (!fgets(name_buf, sizeof(name_buf), input)) |
| 5482 | err(1, "%s: failed to read file", path); | ||
| 5323 | 5483 | ||
| 5324 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ | 5484 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ |
| 5325 | sp = strchr(name_buf, '-'); | 5485 | sp = strchr(name_buf, '-'); |
| @@ -5346,7 +5506,8 @@ void probe_sysfs(void) | |||
| 5346 | input = fopen(path, "r"); | 5506 | input = fopen(path, "r"); |
| 5347 | if (input == NULL) | 5507 | if (input == NULL) |
| 5348 | continue; | 5508 | continue; |
| 5349 | fgets(name_buf, sizeof(name_buf), input); | 5509 | if (!fgets(name_buf, sizeof(name_buf), input)) |
| 5510 | err(1, "%s: failed to read file", path); | ||
| 5350 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ | 5511 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ |
| 5351 | sp = strchr(name_buf, '-'); | 5512 | sp = strchr(name_buf, '-'); |
| 5352 | if (!sp) | 5513 | if (!sp) |
