.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * turbostat -- show CPU frequency and C-state residency |
---|
3 | 4 | * on modern Intel and AMD processors. |
---|
4 | 5 | * |
---|
5 | 6 | * Copyright (c) 2013 Intel Corporation. |
---|
6 | 7 | * Len Brown <len.brown@intel.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms and conditions of the GNU General Public License, |
---|
10 | | - * version 2, as published by the Free Software Foundation. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
13 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
14 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
15 | | - * more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License along with |
---|
18 | | - * this program; if not, write to the Free Software Foundation, Inc., |
---|
19 | | - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
---|
20 | 8 | */ |
---|
21 | 9 | |
---|
22 | 10 | #define _GNU_SOURCE |
---|
.. | .. |
---|
42 | 30 | #include <sched.h> |
---|
43 | 31 | #include <time.h> |
---|
44 | 32 | #include <cpuid.h> |
---|
45 | | -#include <linux/capability.h> |
---|
| 33 | +#include <sys/capability.h> |
---|
46 | 34 | #include <errno.h> |
---|
| 35 | +#include <math.h> |
---|
47 | 36 | |
---|
48 | 37 | char *proc_stat = "/proc/stat"; |
---|
49 | 38 | FILE *outf; |
---|
50 | 39 | int *fd_percpu; |
---|
51 | 40 | struct timeval interval_tv = {5, 0}; |
---|
52 | 41 | struct timespec interval_ts = {5, 0}; |
---|
53 | | -struct timespec one_msec = {0, 1000000}; |
---|
54 | 42 | unsigned int num_iterations; |
---|
55 | 43 | unsigned int debug; |
---|
56 | 44 | unsigned int quiet; |
---|
.. | .. |
---|
63 | 51 | unsigned int do_snb_cstates; |
---|
64 | 52 | unsigned int do_knl_cstates; |
---|
65 | 53 | unsigned int do_slm_cstates; |
---|
66 | | -unsigned int do_cnl_cstates; |
---|
67 | 54 | unsigned int use_c1_residency_msr; |
---|
68 | 55 | unsigned int has_aperf; |
---|
69 | 56 | unsigned int has_epb; |
---|
.. | .. |
---|
72 | 59 | unsigned int units = 1000000; /* MHz etc */ |
---|
73 | 60 | unsigned int genuine_intel; |
---|
74 | 61 | unsigned int authentic_amd; |
---|
| 62 | +unsigned int hygon_genuine; |
---|
75 | 63 | unsigned int max_level, max_extended_level; |
---|
76 | 64 | unsigned int has_invariant_tsc; |
---|
77 | 65 | unsigned int do_nhm_platform_info; |
---|
.. | .. |
---|
91 | 79 | unsigned long long cpuidle_cur_cpu_lpi_us; |
---|
92 | 80 | unsigned long long cpuidle_cur_sys_lpi_us; |
---|
93 | 81 | unsigned int gfx_cur_mhz; |
---|
| 82 | +unsigned int gfx_act_mhz; |
---|
94 | 83 | unsigned int tcc_activation_temp; |
---|
95 | 84 | unsigned int tcc_activation_temp_override; |
---|
96 | 85 | double rapl_power_units, rapl_time_units; |
---|
.. | .. |
---|
112 | 101 | unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ |
---|
113 | 102 | unsigned int has_misc_feature_control; |
---|
114 | 103 | unsigned int first_counter_read = 1; |
---|
| 104 | +int ignore_stdin; |
---|
115 | 105 | |
---|
116 | 106 | #define RAPL_PKG (1 << 0) |
---|
117 | 107 | /* 0x610 MSR_PKG_POWER_LIMIT */ |
---|
.. | .. |
---|
141 | 131 | |
---|
142 | 132 | #define RAPL_CORES_ENERGY_STATUS (1 << 9) |
---|
143 | 133 | /* 0x639 MSR_PP0_ENERGY_STATUS */ |
---|
| 134 | +#define RAPL_PER_CORE_ENERGY (1 << 10) |
---|
| 135 | + /* Indicates cores energy collection is per-core, |
---|
| 136 | + * not per-package. */ |
---|
| 137 | +#define RAPL_AMD_F17H (1 << 11) |
---|
| 138 | + /* 0xc0010299 MSR_RAPL_PWR_UNIT */ |
---|
| 139 | + /* 0xc001029a MSR_CORE_ENERGY_STAT */ |
---|
| 140 | + /* 0xc001029b MSR_PKG_ENERGY_STAT */ |
---|
144 | 141 | #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) |
---|
145 | 142 | #define TJMAX_DEFAULT 100 |
---|
| 143 | + |
---|
| 144 | +/* MSRs that are not yet in the kernel-provided header. */ |
---|
| 145 | +#define MSR_RAPL_PWR_UNIT 0xc0010299 |
---|
| 146 | +#define MSR_CORE_ENERGY_STAT 0xc001029a |
---|
| 147 | +#define MSR_PKG_ENERGY_STAT 0xc001029b |
---|
146 | 148 | |
---|
147 | 149 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
---|
148 | 150 | |
---|
.. | .. |
---|
166 | 168 | struct thread_data { |
---|
167 | 169 | struct timeval tv_begin; |
---|
168 | 170 | struct timeval tv_end; |
---|
| 171 | + struct timeval tv_delta; |
---|
169 | 172 | unsigned long long tsc; |
---|
170 | 173 | unsigned long long aperf; |
---|
171 | 174 | unsigned long long mperf; |
---|
.. | .. |
---|
187 | 190 | unsigned long long c7; |
---|
188 | 191 | unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */ |
---|
189 | 192 | unsigned int core_temp_c; |
---|
| 193 | + unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */ |
---|
190 | 194 | unsigned int core_id; |
---|
191 | 195 | unsigned long long counter[MAX_ADDED_COUNTERS]; |
---|
192 | 196 | } *core_even, *core_odd; |
---|
.. | .. |
---|
207 | 211 | unsigned long long pkg_both_core_gfxe_c0; |
---|
208 | 212 | long long gfx_rc6_ms; |
---|
209 | 213 | unsigned int gfx_mhz; |
---|
| 214 | + unsigned int gfx_act_mhz; |
---|
210 | 215 | unsigned int package_id; |
---|
211 | | - unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */ |
---|
212 | | - unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */ |
---|
213 | | - unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */ |
---|
214 | | - unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */ |
---|
215 | | - unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */ |
---|
216 | | - unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */ |
---|
| 216 | + unsigned long long energy_pkg; /* MSR_PKG_ENERGY_STATUS */ |
---|
| 217 | + unsigned long long energy_dram; /* MSR_DRAM_ENERGY_STATUS */ |
---|
| 218 | + unsigned long long energy_cores; /* MSR_PP0_ENERGY_STATUS */ |
---|
| 219 | + unsigned long long energy_gfx; /* MSR_PP1_ENERGY_STATUS */ |
---|
| 220 | + unsigned long long rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */ |
---|
| 221 | + unsigned long long rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */ |
---|
217 | 222 | unsigned int pkg_temp_c; |
---|
218 | 223 | unsigned long long counter[MAX_ADDED_COUNTERS]; |
---|
219 | 224 | } *package_even, *package_odd; |
---|
.. | .. |
---|
256 | 261 | #define SYSFS_PERCPU (1 << 1) |
---|
257 | 262 | }; |
---|
258 | 263 | |
---|
| 264 | +/* |
---|
| 265 | + * The accumulated sum of MSR is defined as a monotonic |
---|
| 266 | + * increasing MSR, it will be accumulated periodically, |
---|
| 267 | + * despite its register's bit width. |
---|
| 268 | + */ |
---|
| 269 | +enum { |
---|
| 270 | + IDX_PKG_ENERGY, |
---|
| 271 | + IDX_DRAM_ENERGY, |
---|
| 272 | + IDX_PP0_ENERGY, |
---|
| 273 | + IDX_PP1_ENERGY, |
---|
| 274 | + IDX_PKG_PERF, |
---|
| 275 | + IDX_DRAM_PERF, |
---|
| 276 | + IDX_COUNT, |
---|
| 277 | +}; |
---|
| 278 | + |
---|
| 279 | +int get_msr_sum(int cpu, off_t offset, unsigned long long *msr); |
---|
| 280 | + |
---|
| 281 | +struct msr_sum_array { |
---|
| 282 | + /* get_msr_sum() = sum + (get_msr() - last) */ |
---|
| 283 | + struct { |
---|
| 284 | + /*The accumulated MSR value is updated by the timer*/ |
---|
| 285 | + unsigned long long sum; |
---|
| 286 | + /*The MSR footprint recorded in last timer*/ |
---|
| 287 | + unsigned long long last; |
---|
| 288 | + } entries[IDX_COUNT]; |
---|
| 289 | +}; |
---|
| 290 | + |
---|
| 291 | +/* The percpu MSR sum array.*/ |
---|
| 292 | +struct msr_sum_array *per_cpu_msr_sum; |
---|
| 293 | + |
---|
| 294 | +off_t idx_to_offset(int idx) |
---|
| 295 | +{ |
---|
| 296 | + off_t offset; |
---|
| 297 | + |
---|
| 298 | + switch (idx) { |
---|
| 299 | + case IDX_PKG_ENERGY: |
---|
| 300 | + if (do_rapl & RAPL_AMD_F17H) |
---|
| 301 | + offset = MSR_PKG_ENERGY_STAT; |
---|
| 302 | + else |
---|
| 303 | + offset = MSR_PKG_ENERGY_STATUS; |
---|
| 304 | + break; |
---|
| 305 | + case IDX_DRAM_ENERGY: |
---|
| 306 | + offset = MSR_DRAM_ENERGY_STATUS; |
---|
| 307 | + break; |
---|
| 308 | + case IDX_PP0_ENERGY: |
---|
| 309 | + offset = MSR_PP0_ENERGY_STATUS; |
---|
| 310 | + break; |
---|
| 311 | + case IDX_PP1_ENERGY: |
---|
| 312 | + offset = MSR_PP1_ENERGY_STATUS; |
---|
| 313 | + break; |
---|
| 314 | + case IDX_PKG_PERF: |
---|
| 315 | + offset = MSR_PKG_PERF_STATUS; |
---|
| 316 | + break; |
---|
| 317 | + case IDX_DRAM_PERF: |
---|
| 318 | + offset = MSR_DRAM_PERF_STATUS; |
---|
| 319 | + break; |
---|
| 320 | + default: |
---|
| 321 | + offset = -1; |
---|
| 322 | + } |
---|
| 323 | + return offset; |
---|
| 324 | +} |
---|
| 325 | + |
---|
| 326 | +int offset_to_idx(off_t offset) |
---|
| 327 | +{ |
---|
| 328 | + int idx; |
---|
| 329 | + |
---|
| 330 | + switch (offset) { |
---|
| 331 | + case MSR_PKG_ENERGY_STATUS: |
---|
| 332 | + case MSR_PKG_ENERGY_STAT: |
---|
| 333 | + idx = IDX_PKG_ENERGY; |
---|
| 334 | + break; |
---|
| 335 | + case MSR_DRAM_ENERGY_STATUS: |
---|
| 336 | + idx = IDX_DRAM_ENERGY; |
---|
| 337 | + break; |
---|
| 338 | + case MSR_PP0_ENERGY_STATUS: |
---|
| 339 | + idx = IDX_PP0_ENERGY; |
---|
| 340 | + break; |
---|
| 341 | + case MSR_PP1_ENERGY_STATUS: |
---|
| 342 | + idx = IDX_PP1_ENERGY; |
---|
| 343 | + break; |
---|
| 344 | + case MSR_PKG_PERF_STATUS: |
---|
| 345 | + idx = IDX_PKG_PERF; |
---|
| 346 | + break; |
---|
| 347 | + case MSR_DRAM_PERF_STATUS: |
---|
| 348 | + idx = IDX_DRAM_PERF; |
---|
| 349 | + break; |
---|
| 350 | + default: |
---|
| 351 | + idx = -1; |
---|
| 352 | + } |
---|
| 353 | + return idx; |
---|
| 354 | +} |
---|
| 355 | + |
---|
| 356 | +int idx_valid(int idx) |
---|
| 357 | +{ |
---|
| 358 | + switch (idx) { |
---|
| 359 | + case IDX_PKG_ENERGY: |
---|
| 360 | + return do_rapl & (RAPL_PKG | RAPL_AMD_F17H); |
---|
| 361 | + case IDX_DRAM_ENERGY: |
---|
| 362 | + return do_rapl & RAPL_DRAM; |
---|
| 363 | + case IDX_PP0_ENERGY: |
---|
| 364 | + return do_rapl & RAPL_CORES_ENERGY_STATUS; |
---|
| 365 | + case IDX_PP1_ENERGY: |
---|
| 366 | + return do_rapl & RAPL_GFX; |
---|
| 367 | + case IDX_PKG_PERF: |
---|
| 368 | + return do_rapl & RAPL_PKG_PERF_STATUS; |
---|
| 369 | + case IDX_DRAM_PERF: |
---|
| 370 | + return do_rapl & RAPL_DRAM_PERF_STATUS; |
---|
| 371 | + default: |
---|
| 372 | + return 0; |
---|
| 373 | + } |
---|
| 374 | +} |
---|
259 | 375 | struct sys_counters { |
---|
260 | 376 | unsigned int added_thread_counters; |
---|
261 | 377 | unsigned int added_core_counters; |
---|
.. | .. |
---|
273 | 389 | |
---|
274 | 390 | struct cpu_topology { |
---|
275 | 391 | int physical_package_id; |
---|
| 392 | + int die_id; |
---|
276 | 393 | int logical_cpu_id; |
---|
277 | 394 | int physical_node_id; |
---|
278 | 395 | int logical_node_id; /* 0-based count within the package */ |
---|
.. | .. |
---|
283 | 400 | |
---|
284 | 401 | struct topo_params { |
---|
285 | 402 | int num_packages; |
---|
| 403 | + int num_die; |
---|
286 | 404 | int num_cpus; |
---|
287 | 405 | int num_cores; |
---|
288 | 406 | int max_cpu_num; |
---|
.. | .. |
---|
318 | 436 | int retval, pkg_no, core_no, thread_no, node_no; |
---|
319 | 437 | |
---|
320 | 438 | for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { |
---|
321 | | - for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { |
---|
322 | | - for (node_no = 0; node_no < topo.nodes_per_pkg; |
---|
323 | | - node_no++) { |
---|
| 439 | + for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) { |
---|
| 440 | + for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { |
---|
324 | 441 | for (thread_no = 0; thread_no < |
---|
325 | 442 | topo.threads_per_core; ++thread_no) { |
---|
326 | 443 | struct thread_data *t; |
---|
.. | .. |
---|
446 | 563 | { 0x0, "CPU" }, |
---|
447 | 564 | { 0x0, "APIC" }, |
---|
448 | 565 | { 0x0, "X2APIC" }, |
---|
| 566 | + { 0x0, "Die" }, |
---|
| 567 | + { 0x0, "GFXAMHz" }, |
---|
449 | 568 | }; |
---|
450 | 569 | |
---|
451 | 570 | #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) |
---|
.. | .. |
---|
499 | 618 | #define BIC_CPU (1ULL << 47) |
---|
500 | 619 | #define BIC_APIC (1ULL << 48) |
---|
501 | 620 | #define BIC_X2APIC (1ULL << 49) |
---|
| 621 | +#define BIC_Die (1ULL << 50) |
---|
| 622 | +#define BIC_GFXACTMHz (1ULL << 51) |
---|
502 | 623 | |
---|
503 | 624 | #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) |
---|
504 | 625 | |
---|
.. | .. |
---|
506 | 627 | unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC; |
---|
507 | 628 | |
---|
508 | 629 | #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME) |
---|
| 630 | +#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME) |
---|
509 | 631 | #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) |
---|
510 | 632 | #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT) |
---|
511 | 633 | #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT) |
---|
.. | .. |
---|
625 | 747 | outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : "")); |
---|
626 | 748 | if (DO_BIC(BIC_Package)) |
---|
627 | 749 | outp += sprintf(outp, "%sPackage", (printed++ ? delim : "")); |
---|
| 750 | + if (DO_BIC(BIC_Die)) |
---|
| 751 | + outp += sprintf(outp, "%sDie", (printed++ ? delim : "")); |
---|
628 | 752 | if (DO_BIC(BIC_Node)) |
---|
629 | 753 | outp += sprintf(outp, "%sNode", (printed++ ? delim : "")); |
---|
630 | 754 | if (DO_BIC(BIC_Core)) |
---|
.. | .. |
---|
671 | 795 | |
---|
672 | 796 | if (DO_BIC(BIC_CPU_c1)) |
---|
673 | 797 | outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : "")); |
---|
674 | | - if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) |
---|
| 798 | + if (DO_BIC(BIC_CPU_c3)) |
---|
675 | 799 | outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : "")); |
---|
676 | 800 | if (DO_BIC(BIC_CPU_c6)) |
---|
677 | 801 | outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : "")); |
---|
.. | .. |
---|
683 | 807 | |
---|
684 | 808 | if (DO_BIC(BIC_CoreTmp)) |
---|
685 | 809 | outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : "")); |
---|
| 810 | + |
---|
| 811 | + if (do_rapl && !rapl_joules) { |
---|
| 812 | + if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
| 813 | + outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); |
---|
| 814 | + } else if (do_rapl && rapl_joules) { |
---|
| 815 | + if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
| 816 | + outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); |
---|
| 817 | + } |
---|
686 | 818 | |
---|
687 | 819 | for (mp = sys.cp; mp; mp = mp->next) { |
---|
688 | 820 | if (mp->format == FORMAT_RAW) { |
---|
.. | .. |
---|
706 | 838 | |
---|
707 | 839 | if (DO_BIC(BIC_GFXMHz)) |
---|
708 | 840 | outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : "")); |
---|
| 841 | + |
---|
| 842 | + if (DO_BIC(BIC_GFXACTMHz)) |
---|
| 843 | + outp += sprintf(outp, "%sGFXAMHz", (printed++ ? delim : "")); |
---|
709 | 844 | |
---|
710 | 845 | if (DO_BIC(BIC_Totl_c0)) |
---|
711 | 846 | outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : "")); |
---|
.. | .. |
---|
738 | 873 | if (do_rapl && !rapl_joules) { |
---|
739 | 874 | if (DO_BIC(BIC_PkgWatt)) |
---|
740 | 875 | outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : "")); |
---|
741 | | - if (DO_BIC(BIC_CorWatt)) |
---|
| 876 | + if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
742 | 877 | outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : "")); |
---|
743 | 878 | if (DO_BIC(BIC_GFXWatt)) |
---|
744 | 879 | outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : "")); |
---|
.. | .. |
---|
751 | 886 | } else if (do_rapl && rapl_joules) { |
---|
752 | 887 | if (DO_BIC(BIC_Pkg_J)) |
---|
753 | 888 | outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : "")); |
---|
754 | | - if (DO_BIC(BIC_Cor_J)) |
---|
| 889 | + if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
755 | 890 | outp += sprintf(outp, "%sCor_J", (printed++ ? delim : "")); |
---|
756 | 891 | if (DO_BIC(BIC_GFX_J)) |
---|
757 | 892 | outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : "")); |
---|
.. | .. |
---|
812 | 947 | outp += sprintf(outp, "c6: %016llX\n", c->c6); |
---|
813 | 948 | outp += sprintf(outp, "c7: %016llX\n", c->c7); |
---|
814 | 949 | outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); |
---|
| 950 | + outp += sprintf(outp, "Joules: %0X\n", c->core_energy); |
---|
815 | 951 | |
---|
816 | 952 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
---|
817 | 953 | outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", |
---|
.. | .. |
---|
838 | 974 | outp += sprintf(outp, "pc8: %016llX\n", p->pc8); |
---|
839 | 975 | outp += sprintf(outp, "pc9: %016llX\n", p->pc9); |
---|
840 | 976 | outp += sprintf(outp, "pc10: %016llX\n", p->pc10); |
---|
841 | | - outp += sprintf(outp, "pc10: %016llX\n", p->pc10); |
---|
842 | 977 | outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi); |
---|
843 | 978 | outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi); |
---|
844 | | - outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg); |
---|
845 | | - outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores); |
---|
846 | | - outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx); |
---|
847 | | - outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram); |
---|
848 | | - outp += sprintf(outp, "Throttle PKG: %0X\n", |
---|
| 979 | + outp += sprintf(outp, "Joules PKG: %0llX\n", p->energy_pkg); |
---|
| 980 | + outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores); |
---|
| 981 | + outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx); |
---|
| 982 | + outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram); |
---|
| 983 | + outp += sprintf(outp, "Throttle PKG: %0llX\n", |
---|
849 | 984 | p->rapl_pkg_perf_status); |
---|
850 | | - outp += sprintf(outp, "Throttle RAM: %0X\n", |
---|
| 985 | + outp += sprintf(outp, "Throttle RAM: %0llX\n", |
---|
851 | 986 | p->rapl_dram_perf_status); |
---|
852 | 987 | outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c); |
---|
853 | 988 | |
---|
.. | .. |
---|
900 | 1035 | if (DO_BIC(BIC_TOD)) |
---|
901 | 1036 | outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec); |
---|
902 | 1037 | |
---|
903 | | - interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; |
---|
| 1038 | + interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec/1000000.0; |
---|
904 | 1039 | |
---|
905 | 1040 | tsc = t->tsc * tsc_tweak; |
---|
906 | 1041 | |
---|
907 | 1042 | /* topo columns, print blanks on 1st (average) line */ |
---|
908 | 1043 | if (t == &average.threads) { |
---|
909 | 1044 | if (DO_BIC(BIC_Package)) |
---|
| 1045 | + outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
---|
| 1046 | + if (DO_BIC(BIC_Die)) |
---|
910 | 1047 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
---|
911 | 1048 | if (DO_BIC(BIC_Node)) |
---|
912 | 1049 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
---|
.. | .. |
---|
922 | 1059 | if (DO_BIC(BIC_Package)) { |
---|
923 | 1060 | if (p) |
---|
924 | 1061 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id); |
---|
| 1062 | + else |
---|
| 1063 | + outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
---|
| 1064 | + } |
---|
| 1065 | + if (DO_BIC(BIC_Die)) { |
---|
| 1066 | + if (c) |
---|
| 1067 | + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].die_id); |
---|
925 | 1068 | else |
---|
926 | 1069 | outp += sprintf(outp, "%s-", (printed++ ? delim : "")); |
---|
927 | 1070 | } |
---|
.. | .. |
---|
1007 | 1150 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
---|
1008 | 1151 | goto done; |
---|
1009 | 1152 | |
---|
1010 | | - if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) |
---|
| 1153 | + if (DO_BIC(BIC_CPU_c3)) |
---|
1011 | 1154 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc); |
---|
1012 | 1155 | if (DO_BIC(BIC_CPU_c6)) |
---|
1013 | 1156 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc); |
---|
.. | .. |
---|
1037 | 1180 | } |
---|
1038 | 1181 | } |
---|
1039 | 1182 | |
---|
| 1183 | + fmt8 = "%s%.2f"; |
---|
| 1184 | + |
---|
| 1185 | + if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
| 1186 | + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float); |
---|
| 1187 | + if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
| 1188 | + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units); |
---|
| 1189 | + |
---|
1040 | 1190 | /* print per-package data only for 1st core in package */ |
---|
1041 | 1191 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) |
---|
1042 | 1192 | goto done; |
---|
.. | .. |
---|
1058 | 1208 | /* GFXMHz */ |
---|
1059 | 1209 | if (DO_BIC(BIC_GFXMHz)) |
---|
1060 | 1210 | outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz); |
---|
| 1211 | + |
---|
| 1212 | + /* GFXACTMHz */ |
---|
| 1213 | + if (DO_BIC(BIC_GFXACTMHz)) |
---|
| 1214 | + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_act_mhz); |
---|
1061 | 1215 | |
---|
1062 | 1216 | /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */ |
---|
1063 | 1217 | if (DO_BIC(BIC_Totl_c0)) |
---|
.. | .. |
---|
1089 | 1243 | if (DO_BIC(BIC_SYS_LPI)) |
---|
1090 | 1244 | outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float); |
---|
1091 | 1245 | |
---|
1092 | | - /* |
---|
1093 | | - * If measurement interval exceeds minimum RAPL Joule Counter range, |
---|
1094 | | - * indicate that results are suspect by printing "**" in fraction place. |
---|
1095 | | - */ |
---|
1096 | | - if (interval_float < rapl_joule_counter_range) |
---|
1097 | | - fmt8 = "%s%.2f"; |
---|
1098 | | - else |
---|
1099 | | - fmt8 = "%6.0f**"; |
---|
1100 | | - |
---|
1101 | 1246 | if (DO_BIC(BIC_PkgWatt)) |
---|
1102 | 1247 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float); |
---|
1103 | | - if (DO_BIC(BIC_CorWatt)) |
---|
| 1248 | + if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
1104 | 1249 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float); |
---|
1105 | 1250 | if (DO_BIC(BIC_GFXWatt)) |
---|
1106 | 1251 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float); |
---|
.. | .. |
---|
1108 | 1253 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float); |
---|
1109 | 1254 | if (DO_BIC(BIC_Pkg_J)) |
---|
1110 | 1255 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units); |
---|
1111 | | - if (DO_BIC(BIC_Cor_J)) |
---|
| 1256 | + if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) |
---|
1112 | 1257 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units); |
---|
1113 | 1258 | if (DO_BIC(BIC_GFX_J)) |
---|
1114 | 1259 | outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units); |
---|
.. | .. |
---|
1180 | 1325 | } |
---|
1181 | 1326 | |
---|
1182 | 1327 | #define DELTA_WRAP32(new, old) \ |
---|
1183 | | - if (new > old) { \ |
---|
1184 | | - old = new - old; \ |
---|
1185 | | - } else { \ |
---|
1186 | | - old = 0x100000000 + new - old; \ |
---|
1187 | | - } |
---|
| 1328 | + old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32); |
---|
1188 | 1329 | |
---|
1189 | 1330 | int |
---|
1190 | 1331 | delta_package(struct pkg_data *new, struct pkg_data *old) |
---|
.. | .. |
---|
1223 | 1364 | old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms; |
---|
1224 | 1365 | |
---|
1225 | 1366 | old->gfx_mhz = new->gfx_mhz; |
---|
| 1367 | + old->gfx_act_mhz = new->gfx_act_mhz; |
---|
1226 | 1368 | |
---|
1227 | | - DELTA_WRAP32(new->energy_pkg, old->energy_pkg); |
---|
1228 | | - DELTA_WRAP32(new->energy_cores, old->energy_cores); |
---|
1229 | | - DELTA_WRAP32(new->energy_gfx, old->energy_gfx); |
---|
1230 | | - DELTA_WRAP32(new->energy_dram, old->energy_dram); |
---|
1231 | | - DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status); |
---|
1232 | | - DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status); |
---|
| 1369 | + old->energy_pkg = new->energy_pkg - old->energy_pkg; |
---|
| 1370 | + old->energy_cores = new->energy_cores - old->energy_cores; |
---|
| 1371 | + old->energy_gfx = new->energy_gfx - old->energy_gfx; |
---|
| 1372 | + old->energy_dram = new->energy_dram - old->energy_dram; |
---|
| 1373 | + old->rapl_pkg_perf_status = new->rapl_pkg_perf_status - old->rapl_pkg_perf_status; |
---|
| 1374 | + old->rapl_dram_perf_status = new->rapl_dram_perf_status - old->rapl_dram_perf_status; |
---|
1233 | 1375 | |
---|
1234 | 1376 | for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { |
---|
1235 | 1377 | if (mp->format == FORMAT_RAW) |
---|
.. | .. |
---|
1253 | 1395 | old->core_temp_c = new->core_temp_c; |
---|
1254 | 1396 | old->mc6_us = new->mc6_us - old->mc6_us; |
---|
1255 | 1397 | |
---|
| 1398 | + DELTA_WRAP32(new->core_energy, old->core_energy); |
---|
| 1399 | + |
---|
1256 | 1400 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
---|
1257 | 1401 | if (mp->format == FORMAT_RAW) |
---|
1258 | 1402 | old->counter[i] = new->counter[i]; |
---|
1259 | 1403 | else |
---|
1260 | 1404 | old->counter[i] = new->counter[i] - old->counter[i]; |
---|
1261 | 1405 | } |
---|
| 1406 | +} |
---|
| 1407 | + |
---|
| 1408 | +int soft_c1_residency_display(int bic) |
---|
| 1409 | +{ |
---|
| 1410 | + if (!DO_BIC(BIC_CPU_c1) || use_c1_residency_msr) |
---|
| 1411 | + return 0; |
---|
| 1412 | + |
---|
| 1413 | + return DO_BIC_READ(bic); |
---|
1262 | 1414 | } |
---|
1263 | 1415 | |
---|
1264 | 1416 | /* |
---|
.. | .. |
---|
1283 | 1435 | * over-write old w/ new so we can print end of interval values |
---|
1284 | 1436 | */ |
---|
1285 | 1437 | |
---|
| 1438 | + timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta); |
---|
1286 | 1439 | old->tv_begin = new->tv_begin; |
---|
1287 | 1440 | old->tv_end = new->tv_end; |
---|
1288 | 1441 | |
---|
.. | .. |
---|
1296 | 1449 | |
---|
1297 | 1450 | old->c1 = new->c1 - old->c1; |
---|
1298 | 1451 | |
---|
1299 | | - if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) { |
---|
| 1452 | + if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || |
---|
| 1453 | + soft_c1_residency_display(BIC_Avg_MHz)) { |
---|
1300 | 1454 | if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { |
---|
1301 | 1455 | old->aperf = new->aperf - old->aperf; |
---|
1302 | 1456 | old->mperf = new->mperf - old->mperf; |
---|
.. | .. |
---|
1378 | 1532 | t->tv_begin.tv_usec = 0; |
---|
1379 | 1533 | t->tv_end.tv_sec = 0; |
---|
1380 | 1534 | t->tv_end.tv_usec = 0; |
---|
| 1535 | + t->tv_delta.tv_sec = 0; |
---|
| 1536 | + t->tv_delta.tv_usec = 0; |
---|
1381 | 1537 | |
---|
1382 | 1538 | t->tsc = 0; |
---|
1383 | 1539 | t->aperf = 0; |
---|
.. | .. |
---|
1395 | 1551 | c->c7 = 0; |
---|
1396 | 1552 | c->mc6_us = 0; |
---|
1397 | 1553 | c->core_temp_c = 0; |
---|
| 1554 | + c->core_energy = 0; |
---|
1398 | 1555 | |
---|
1399 | 1556 | p->pkg_wtd_core_c0 = 0; |
---|
1400 | 1557 | p->pkg_any_core_c0 = 0; |
---|
.. | .. |
---|
1424 | 1581 | |
---|
1425 | 1582 | p->gfx_rc6_ms = 0; |
---|
1426 | 1583 | p->gfx_mhz = 0; |
---|
| 1584 | + p->gfx_act_mhz = 0; |
---|
1427 | 1585 | for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) |
---|
1428 | 1586 | t->counter[i] = 0; |
---|
1429 | 1587 | |
---|
.. | .. |
---|
1477 | 1635 | |
---|
1478 | 1636 | average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); |
---|
1479 | 1637 | |
---|
| 1638 | + average.cores.core_energy += c->core_energy; |
---|
| 1639 | + |
---|
1480 | 1640 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
---|
1481 | 1641 | if (mp->format == FORMAT_RAW) |
---|
1482 | 1642 | continue; |
---|
.. | .. |
---|
1517 | 1677 | |
---|
1518 | 1678 | average.packages.gfx_rc6_ms = p->gfx_rc6_ms; |
---|
1519 | 1679 | average.packages.gfx_mhz = p->gfx_mhz; |
---|
| 1680 | + average.packages.gfx_act_mhz = p->gfx_act_mhz; |
---|
1520 | 1681 | |
---|
1521 | 1682 | average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c); |
---|
1522 | 1683 | |
---|
.. | .. |
---|
1543 | 1704 | clear_counters(&average.threads, &average.cores, &average.packages); |
---|
1544 | 1705 | |
---|
1545 | 1706 | for_all_cpus(sum_counters, t, c, p); |
---|
| 1707 | + |
---|
| 1708 | + /* Use the global time delta for the average. */ |
---|
| 1709 | + average.threads.tv_delta = tv_delta; |
---|
1546 | 1710 | |
---|
1547 | 1711 | average.threads.tsc /= topo.num_cpus; |
---|
1548 | 1712 | average.threads.aperf /= topo.num_cpus; |
---|
.. | .. |
---|
1685 | 1849 | if (!DO_BIC(BIC_X2APIC)) |
---|
1686 | 1850 | return; |
---|
1687 | 1851 | |
---|
1688 | | - if (authentic_amd) { |
---|
| 1852 | + if (authentic_amd || hygon_genuine) { |
---|
1689 | 1853 | unsigned int topology_extensions; |
---|
1690 | 1854 | |
---|
1691 | 1855 | if (max_extended_level < 0x8000001e) |
---|
.. | .. |
---|
1733 | 1897 | struct msr_counter *mp; |
---|
1734 | 1898 | int i; |
---|
1735 | 1899 | |
---|
1736 | | - gettimeofday(&t->tv_begin, (struct timezone *)NULL); |
---|
1737 | | - |
---|
1738 | 1900 | if (cpu_migrate(cpu)) { |
---|
1739 | | - fprintf(outf, "Could not migrate to CPU %d\n", cpu); |
---|
| 1901 | + fprintf(outf, "get_counters: Could not migrate to CPU %d\n", cpu); |
---|
1740 | 1902 | return -1; |
---|
1741 | 1903 | } |
---|
| 1904 | + |
---|
| 1905 | + gettimeofday(&t->tv_begin, (struct timezone *)NULL); |
---|
1742 | 1906 | |
---|
1743 | 1907 | if (first_counter_read) |
---|
1744 | 1908 | get_apic_id(t); |
---|
1745 | 1909 | retry: |
---|
1746 | 1910 | t->tsc = rdtsc(); /* we are running on local CPU of interest */ |
---|
1747 | 1911 | |
---|
1748 | | - if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) { |
---|
| 1912 | + if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || |
---|
| 1913 | + soft_c1_residency_display(BIC_Avg_MHz)) { |
---|
1749 | 1914 | unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time; |
---|
1750 | 1915 | |
---|
1751 | 1916 | /* |
---|
.. | .. |
---|
1822 | 1987 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
---|
1823 | 1988 | goto done; |
---|
1824 | 1989 | |
---|
1825 | | - if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates) { |
---|
| 1990 | + if (DO_BIC(BIC_CPU_c3) || soft_c1_residency_display(BIC_CPU_c3)) { |
---|
1826 | 1991 | if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) |
---|
1827 | 1992 | return -6; |
---|
1828 | 1993 | } |
---|
1829 | 1994 | |
---|
1830 | | - if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) { |
---|
| 1995 | + if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) { |
---|
1831 | 1996 | if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) |
---|
1832 | 1997 | return -7; |
---|
1833 | | - } else if (do_knl_cstates) { |
---|
| 1998 | + } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) { |
---|
1834 | 1999 | if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) |
---|
1835 | 2000 | return -7; |
---|
1836 | 2001 | } |
---|
1837 | 2002 | |
---|
1838 | | - if (DO_BIC(BIC_CPU_c7)) |
---|
| 2003 | + if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7)) |
---|
1839 | 2004 | if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7)) |
---|
1840 | 2005 | return -8; |
---|
1841 | 2006 | |
---|
.. | .. |
---|
1847 | 2012 | if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr)) |
---|
1848 | 2013 | return -9; |
---|
1849 | 2014 | c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); |
---|
| 2015 | + } |
---|
| 2016 | + |
---|
| 2017 | + if (do_rapl & RAPL_AMD_F17H) { |
---|
| 2018 | + if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr)) |
---|
| 2019 | + return -14; |
---|
| 2020 | + c->core_energy = msr & 0xFFFFFFFF; |
---|
1850 | 2021 | } |
---|
1851 | 2022 | |
---|
1852 | 2023 | for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { |
---|
.. | .. |
---|
1909 | 2080 | p->sys_lpi = cpuidle_cur_sys_lpi_us; |
---|
1910 | 2081 | |
---|
1911 | 2082 | if (do_rapl & RAPL_PKG) { |
---|
1912 | | - if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr)) |
---|
| 2083 | + if (get_msr_sum(cpu, MSR_PKG_ENERGY_STATUS, &msr)) |
---|
1913 | 2084 | return -13; |
---|
1914 | | - p->energy_pkg = msr & 0xFFFFFFFF; |
---|
| 2085 | + p->energy_pkg = msr; |
---|
1915 | 2086 | } |
---|
1916 | 2087 | if (do_rapl & RAPL_CORES_ENERGY_STATUS) { |
---|
1917 | | - if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr)) |
---|
| 2088 | + if (get_msr_sum(cpu, MSR_PP0_ENERGY_STATUS, &msr)) |
---|
1918 | 2089 | return -14; |
---|
1919 | | - p->energy_cores = msr & 0xFFFFFFFF; |
---|
| 2090 | + p->energy_cores = msr; |
---|
1920 | 2091 | } |
---|
1921 | 2092 | if (do_rapl & RAPL_DRAM) { |
---|
1922 | | - if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr)) |
---|
| 2093 | + if (get_msr_sum(cpu, MSR_DRAM_ENERGY_STATUS, &msr)) |
---|
1923 | 2094 | return -15; |
---|
1924 | | - p->energy_dram = msr & 0xFFFFFFFF; |
---|
| 2095 | + p->energy_dram = msr; |
---|
1925 | 2096 | } |
---|
1926 | 2097 | if (do_rapl & RAPL_GFX) { |
---|
1927 | | - if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr)) |
---|
| 2098 | + if (get_msr_sum(cpu, MSR_PP1_ENERGY_STATUS, &msr)) |
---|
1928 | 2099 | return -16; |
---|
1929 | | - p->energy_gfx = msr & 0xFFFFFFFF; |
---|
| 2100 | + p->energy_gfx = msr; |
---|
1930 | 2101 | } |
---|
1931 | 2102 | if (do_rapl & RAPL_PKG_PERF_STATUS) { |
---|
1932 | | - if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr)) |
---|
| 2103 | + if (get_msr_sum(cpu, MSR_PKG_PERF_STATUS, &msr)) |
---|
1933 | 2104 | return -16; |
---|
1934 | | - p->rapl_pkg_perf_status = msr & 0xFFFFFFFF; |
---|
| 2105 | + p->rapl_pkg_perf_status = msr; |
---|
1935 | 2106 | } |
---|
1936 | 2107 | if (do_rapl & RAPL_DRAM_PERF_STATUS) { |
---|
1937 | | - if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr)) |
---|
| 2108 | + if (get_msr_sum(cpu, MSR_DRAM_PERF_STATUS, &msr)) |
---|
1938 | 2109 | return -16; |
---|
1939 | | - p->rapl_dram_perf_status = msr & 0xFFFFFFFF; |
---|
| 2110 | + p->rapl_dram_perf_status = msr; |
---|
| 2111 | + } |
---|
| 2112 | + if (do_rapl & RAPL_AMD_F17H) { |
---|
| 2113 | + if (get_msr_sum(cpu, MSR_PKG_ENERGY_STAT, &msr)) |
---|
| 2114 | + return -13; |
---|
| 2115 | + p->energy_pkg = msr; |
---|
1940 | 2116 | } |
---|
1941 | 2117 | if (DO_BIC(BIC_PkgTmp)) { |
---|
1942 | 2118 | if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) |
---|
.. | .. |
---|
1949 | 2125 | |
---|
1950 | 2126 | if (DO_BIC(BIC_GFXMHz)) |
---|
1951 | 2127 | p->gfx_mhz = gfx_cur_mhz; |
---|
| 2128 | + |
---|
| 2129 | + if (DO_BIC(BIC_GFXACTMHz)) |
---|
| 2130 | + p->gfx_act_mhz = gfx_act_mhz; |
---|
1952 | 2131 | |
---|
1953 | 2132 | for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { |
---|
1954 | 2133 | if (get_mp(cpu, mp, &p->counter[i])) |
---|
.. | .. |
---|
2110 | 2289 | switch (model) { |
---|
2111 | 2290 | case INTEL_FAM6_ATOM_GOLDMONT: |
---|
2112 | 2291 | case INTEL_FAM6_SKYLAKE_X: |
---|
2113 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: |
---|
| 2292 | + case INTEL_FAM6_ATOM_GOLDMONT_D: |
---|
| 2293 | + case INTEL_FAM6_ATOM_TREMONT_D: |
---|
2114 | 2294 | return 1; |
---|
2115 | 2295 | } |
---|
2116 | 2296 | return 0; |
---|
.. | .. |
---|
2460 | 2640 | |
---|
2461 | 2641 | /* |
---|
2462 | 2642 | * Parse a file containing a single int. |
---|
| 2643 | + * Return 0 if file can not be opened |
---|
| 2644 | + * Exit if file can be opened, but can not be parsed |
---|
2463 | 2645 | */ |
---|
2464 | 2646 | int parse_int_file(const char *fmt, ...) |
---|
2465 | 2647 | { |
---|
.. | .. |
---|
2471 | 2653 | va_start(args, fmt); |
---|
2472 | 2654 | vsnprintf(path, sizeof(path), fmt, args); |
---|
2473 | 2655 | va_end(args); |
---|
2474 | | - filep = fopen_or_die(path, "r"); |
---|
| 2656 | + filep = fopen(path, "r"); |
---|
| 2657 | + if (!filep) |
---|
| 2658 | + return 0; |
---|
2475 | 2659 | if (fscanf(filep, "%d", &value) != 1) |
---|
2476 | 2660 | err(1, "%s: failed to parse number from file", path); |
---|
2477 | 2661 | fclose(filep); |
---|
.. | .. |
---|
2490 | 2674 | int get_physical_package_id(int cpu) |
---|
2491 | 2675 | { |
---|
2492 | 2676 | return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); |
---|
| 2677 | +} |
---|
| 2678 | + |
---|
| 2679 | +int get_die_id(int cpu) |
---|
| 2680 | +{ |
---|
| 2681 | + return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/die_id", cpu); |
---|
2493 | 2682 | } |
---|
2494 | 2683 | |
---|
2495 | 2684 | int get_core_id(int cpu) |
---|
.. | .. |
---|
2579 | 2768 | |
---|
2580 | 2769 | sprintf(path, |
---|
2581 | 2770 | "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu); |
---|
2582 | | - filep = fopen_or_die(path, "r"); |
---|
| 2771 | + filep = fopen(path, "r"); |
---|
| 2772 | + |
---|
| 2773 | + if (!filep) { |
---|
| 2774 | + warnx("%s: open failed", path); |
---|
| 2775 | + return -1; |
---|
| 2776 | + } |
---|
2583 | 2777 | do { |
---|
2584 | 2778 | offset -= BITMASK_SIZE; |
---|
2585 | | - fscanf(filep, "%lx%c", &map, &character); |
---|
| 2779 | + if (fscanf(filep, "%lx%c", &map, &character) != 2) |
---|
| 2780 | + err(1, "%s: failed to parse file", path); |
---|
2586 | 2781 | for (shift = 0; shift < BITMASK_SIZE; shift++) { |
---|
2587 | 2782 | if ((map >> shift) & 0x1) { |
---|
2588 | 2783 | so = shift + offset; |
---|
.. | .. |
---|
2691 | 2886 | { |
---|
2692 | 2887 | free_all_buffers(); |
---|
2693 | 2888 | setup_all_buffers(); |
---|
2694 | | - printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus); |
---|
| 2889 | + fprintf(outf, "turbostat: re-initialized with num_cpus %d\n", topo.num_cpus); |
---|
2695 | 2890 | } |
---|
2696 | 2891 | |
---|
2697 | 2892 | void set_max_cpu_num(void) |
---|
2698 | 2893 | { |
---|
2699 | 2894 | FILE *filep; |
---|
| 2895 | + int base_cpu; |
---|
2700 | 2896 | unsigned long dummy; |
---|
| 2897 | + char pathname[64]; |
---|
2701 | 2898 | |
---|
| 2899 | + base_cpu = sched_getcpu(); |
---|
| 2900 | + if (base_cpu < 0) |
---|
| 2901 | + err(1, "cannot find calling cpu ID"); |
---|
| 2902 | + sprintf(pathname, |
---|
| 2903 | + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", |
---|
| 2904 | + base_cpu); |
---|
| 2905 | + |
---|
| 2906 | + filep = fopen_or_die(pathname, "r"); |
---|
2702 | 2907 | topo.max_cpu_num = 0; |
---|
2703 | | - filep = fopen_or_die( |
---|
2704 | | - "/sys/devices/system/cpu/cpu0/topology/thread_siblings", |
---|
2705 | | - "r"); |
---|
2706 | 2908 | while (fscanf(filep, "%lx,", &dummy) == 1) |
---|
2707 | 2909 | topo.max_cpu_num += BITMASK_SIZE; |
---|
2708 | 2910 | fclose(filep); |
---|
.. | .. |
---|
2844 | 3046 | } |
---|
2845 | 3047 | |
---|
2846 | 3048 | /* |
---|
| 3049 | + * snapshot_gfx_cur_mhz() |
---|
| 3050 | + * |
---|
| 3051 | + * record snapshot of |
---|
| 3052 | + * /sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz |
---|
| 3053 | + * |
---|
| 3054 | + * return 1 if config change requires a restart, else return 0 |
---|
| 3055 | + */ |
---|
| 3056 | +int snapshot_gfx_act_mhz(void) |
---|
| 3057 | +{ |
---|
| 3058 | + static FILE *fp; |
---|
| 3059 | + int retval; |
---|
| 3060 | + |
---|
| 3061 | + if (fp == NULL) |
---|
| 3062 | + fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", "r"); |
---|
| 3063 | + else { |
---|
| 3064 | + rewind(fp); |
---|
| 3065 | + fflush(fp); |
---|
| 3066 | + } |
---|
| 3067 | + |
---|
| 3068 | + retval = fscanf(fp, "%d", &gfx_act_mhz); |
---|
| 3069 | + if (retval != 1) |
---|
| 3070 | + err(1, "GFX ACT MHz"); |
---|
| 3071 | + |
---|
| 3072 | + return 0; |
---|
| 3073 | +} |
---|
| 3074 | + |
---|
| 3075 | +/* |
---|
2847 | 3076 | * snapshot_cpu_lpi() |
---|
2848 | 3077 | * |
---|
2849 | 3078 | * record snapshot of |
---|
.. | .. |
---|
2857 | 3086 | fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r"); |
---|
2858 | 3087 | |
---|
2859 | 3088 | retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us); |
---|
2860 | | - if (retval != 1) |
---|
2861 | | - err(1, "CPU LPI"); |
---|
| 3089 | + if (retval != 1) { |
---|
| 3090 | + fprintf(stderr, "Disabling Low Power Idle CPU output\n"); |
---|
| 3091 | + BIC_NOT_PRESENT(BIC_CPU_LPI); |
---|
| 3092 | + fclose(fp); |
---|
| 3093 | + return -1; |
---|
| 3094 | + } |
---|
2862 | 3095 | |
---|
2863 | 3096 | fclose(fp); |
---|
2864 | 3097 | |
---|
.. | .. |
---|
2877 | 3110 | fp = fopen_or_die(sys_lpi_file, "r"); |
---|
2878 | 3111 | |
---|
2879 | 3112 | retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); |
---|
2880 | | - if (retval != 1) |
---|
2881 | | - err(1, "SYS LPI"); |
---|
2882 | | - |
---|
| 3113 | + if (retval != 1) { |
---|
| 3114 | + fprintf(stderr, "Disabling Low Power Idle System output\n"); |
---|
| 3115 | + BIC_NOT_PRESENT(BIC_SYS_LPI); |
---|
| 3116 | + fclose(fp); |
---|
| 3117 | + return -1; |
---|
| 3118 | + } |
---|
2883 | 3119 | fclose(fp); |
---|
2884 | 3120 | |
---|
2885 | 3121 | return 0; |
---|
.. | .. |
---|
2900 | 3136 | |
---|
2901 | 3137 | if (DO_BIC(BIC_GFXMHz)) |
---|
2902 | 3138 | snapshot_gfx_mhz(); |
---|
| 3139 | + |
---|
| 3140 | + if (DO_BIC(BIC_GFXACTMHz)) |
---|
| 3141 | + snapshot_gfx_act_mhz(); |
---|
2903 | 3142 | |
---|
2904 | 3143 | if (DO_BIC(BIC_CPU_LPI)) |
---|
2905 | 3144 | snapshot_cpu_lpi_us(); |
---|
.. | .. |
---|
2925 | 3164 | fprintf(stderr, "SIGUSR1\n"); |
---|
2926 | 3165 | break; |
---|
2927 | 3166 | } |
---|
2928 | | - /* make sure this manually-invoked interval is at least 1ms long */ |
---|
2929 | | - nanosleep(&one_msec, NULL); |
---|
2930 | 3167 | } |
---|
2931 | 3168 | |
---|
2932 | 3169 | void setup_signal_handler(void) |
---|
.. | .. |
---|
2945 | 3182 | |
---|
2946 | 3183 | void do_sleep(void) |
---|
2947 | 3184 | { |
---|
2948 | | - struct timeval select_timeout; |
---|
| 3185 | + struct timeval tout; |
---|
| 3186 | + struct timespec rest; |
---|
2949 | 3187 | fd_set readfds; |
---|
2950 | 3188 | int retval; |
---|
2951 | 3189 | |
---|
2952 | 3190 | FD_ZERO(&readfds); |
---|
2953 | 3191 | FD_SET(0, &readfds); |
---|
2954 | 3192 | |
---|
2955 | | - if (!isatty(fileno(stdin))) { |
---|
| 3193 | + if (ignore_stdin) { |
---|
2956 | 3194 | nanosleep(&interval_ts, NULL); |
---|
2957 | 3195 | return; |
---|
2958 | 3196 | } |
---|
2959 | 3197 | |
---|
2960 | | - select_timeout = interval_tv; |
---|
2961 | | - retval = select(1, &readfds, NULL, NULL, &select_timeout); |
---|
| 3198 | + tout = interval_tv; |
---|
| 3199 | + retval = select(1, &readfds, NULL, NULL, &tout); |
---|
2962 | 3200 | |
---|
2963 | 3201 | if (retval == 1) { |
---|
2964 | 3202 | switch (getc(stdin)) { |
---|
2965 | 3203 | case 'q': |
---|
2966 | 3204 | exit_requested = 1; |
---|
2967 | 3205 | break; |
---|
| 3206 | + case EOF: |
---|
| 3207 | + /* |
---|
| 3208 | + * 'stdin' is a pipe closed on the other end. There |
---|
| 3209 | + * won't be any further input. |
---|
| 3210 | + */ |
---|
| 3211 | + ignore_stdin = 1; |
---|
| 3212 | + /* Sleep the rest of the time */ |
---|
| 3213 | + rest.tv_sec = (tout.tv_sec + tout.tv_usec / 1000000); |
---|
| 3214 | + rest.tv_nsec = (tout.tv_usec % 1000000) * 1000; |
---|
| 3215 | + nanosleep(&rest, NULL); |
---|
2968 | 3216 | } |
---|
2969 | | - /* make sure this manually-invoked interval is at least 1ms long */ |
---|
2970 | | - nanosleep(&one_msec, NULL); |
---|
2971 | 3217 | } |
---|
2972 | 3218 | } |
---|
2973 | 3219 | |
---|
| 3220 | +int get_msr_sum(int cpu, off_t offset, unsigned long long *msr) |
---|
| 3221 | +{ |
---|
| 3222 | + int ret, idx; |
---|
| 3223 | + unsigned long long msr_cur, msr_last; |
---|
| 3224 | + |
---|
| 3225 | + if (!per_cpu_msr_sum) |
---|
| 3226 | + return 1; |
---|
| 3227 | + |
---|
| 3228 | + idx = offset_to_idx(offset); |
---|
| 3229 | + if (idx < 0) |
---|
| 3230 | + return idx; |
---|
| 3231 | + /* get_msr_sum() = sum + (get_msr() - last) */ |
---|
| 3232 | + ret = get_msr(cpu, offset, &msr_cur); |
---|
| 3233 | + if (ret) |
---|
| 3234 | + return ret; |
---|
| 3235 | + msr_last = per_cpu_msr_sum[cpu].entries[idx].last; |
---|
| 3236 | + DELTA_WRAP32(msr_cur, msr_last); |
---|
| 3237 | + *msr = msr_last + per_cpu_msr_sum[cpu].entries[idx].sum; |
---|
| 3238 | + |
---|
| 3239 | + return 0; |
---|
| 3240 | +} |
---|
| 3241 | + |
---|
| 3242 | +timer_t timerid; |
---|
| 3243 | + |
---|
| 3244 | +/* Timer callback, update the sum of MSRs periodically. */ |
---|
| 3245 | +static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg_data *p) |
---|
| 3246 | +{ |
---|
| 3247 | + int i, ret; |
---|
| 3248 | + int cpu = t->cpu_id; |
---|
| 3249 | + |
---|
| 3250 | + for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) { |
---|
| 3251 | + unsigned long long msr_cur, msr_last; |
---|
| 3252 | + off_t offset; |
---|
| 3253 | + |
---|
| 3254 | + if (!idx_valid(i)) |
---|
| 3255 | + continue; |
---|
| 3256 | + offset = idx_to_offset(i); |
---|
| 3257 | + if (offset < 0) |
---|
| 3258 | + continue; |
---|
| 3259 | + ret = get_msr(cpu, offset, &msr_cur); |
---|
| 3260 | + if (ret) { |
---|
| 3261 | + fprintf(outf, "Can not update msr(0x%llx)\n", |
---|
| 3262 | + (unsigned long long)offset); |
---|
| 3263 | + continue; |
---|
| 3264 | + } |
---|
| 3265 | + |
---|
| 3266 | + msr_last = per_cpu_msr_sum[cpu].entries[i].last; |
---|
| 3267 | + per_cpu_msr_sum[cpu].entries[i].last = msr_cur & 0xffffffff; |
---|
| 3268 | + |
---|
| 3269 | + DELTA_WRAP32(msr_cur, msr_last); |
---|
| 3270 | + per_cpu_msr_sum[cpu].entries[i].sum += msr_last; |
---|
| 3271 | + } |
---|
| 3272 | + return 0; |
---|
| 3273 | +} |
---|
| 3274 | + |
---|
| 3275 | +static void |
---|
| 3276 | +msr_record_handler(union sigval v) |
---|
| 3277 | +{ |
---|
| 3278 | + for_all_cpus(update_msr_sum, EVEN_COUNTERS); |
---|
| 3279 | +} |
---|
| 3280 | + |
---|
| 3281 | +void msr_sum_record(void) |
---|
| 3282 | +{ |
---|
| 3283 | + struct itimerspec its; |
---|
| 3284 | + struct sigevent sev; |
---|
| 3285 | + |
---|
| 3286 | + per_cpu_msr_sum = calloc(topo.max_cpu_num + 1, sizeof(struct msr_sum_array)); |
---|
| 3287 | + if (!per_cpu_msr_sum) { |
---|
| 3288 | + fprintf(outf, "Can not allocate memory for long time MSR.\n"); |
---|
| 3289 | + return; |
---|
| 3290 | + } |
---|
| 3291 | + /* |
---|
| 3292 | + * Signal handler might be restricted, so use thread notifier instead. |
---|
| 3293 | + */ |
---|
| 3294 | + memset(&sev, 0, sizeof(struct sigevent)); |
---|
| 3295 | + sev.sigev_notify = SIGEV_THREAD; |
---|
| 3296 | + sev.sigev_notify_function = msr_record_handler; |
---|
| 3297 | + |
---|
| 3298 | + sev.sigev_value.sival_ptr = &timerid; |
---|
| 3299 | + if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { |
---|
| 3300 | + fprintf(outf, "Can not create timer.\n"); |
---|
| 3301 | + goto release_msr; |
---|
| 3302 | + } |
---|
| 3303 | + |
---|
| 3304 | + its.it_value.tv_sec = 0; |
---|
| 3305 | + its.it_value.tv_nsec = 1; |
---|
| 3306 | + /* |
---|
| 3307 | + * A wraparound time has been calculated early. |
---|
| 3308 | + * Some sources state that the peak power for a |
---|
| 3309 | + * microprocessor is usually 1.5 times the TDP rating, |
---|
| 3310 | + * use 2 * TDP for safety. |
---|
| 3311 | + */ |
---|
| 3312 | + its.it_interval.tv_sec = rapl_joule_counter_range / 2; |
---|
| 3313 | + its.it_interval.tv_nsec = 0; |
---|
| 3314 | + |
---|
| 3315 | + if (timer_settime(timerid, 0, &its, NULL) == -1) { |
---|
| 3316 | + fprintf(outf, "Can not set timer.\n"); |
---|
| 3317 | + goto release_timer; |
---|
| 3318 | + } |
---|
| 3319 | + return; |
---|
| 3320 | + |
---|
| 3321 | + release_timer: |
---|
| 3322 | + timer_delete(timerid); |
---|
| 3323 | + release_msr: |
---|
| 3324 | + free(per_cpu_msr_sum); |
---|
| 3325 | +} |
---|
2974 | 3326 | |
---|
2975 | 3327 | void turbostat_loop() |
---|
2976 | 3328 | { |
---|
.. | .. |
---|
2989 | 3341 | if (retval < -1) { |
---|
2990 | 3342 | exit(retval); |
---|
2991 | 3343 | } else if (retval == -1) { |
---|
2992 | | - if (restarted > 1) { |
---|
| 3344 | + if (restarted > 10) { |
---|
2993 | 3345 | exit(retval); |
---|
2994 | 3346 | } |
---|
2995 | 3347 | re_initialize(); |
---|
.. | .. |
---|
3064 | 3416 | err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); |
---|
3065 | 3417 | } |
---|
3066 | 3418 | |
---|
3067 | | -void check_permissions() |
---|
| 3419 | +/* |
---|
| 3420 | + * check for CAP_SYS_RAWIO |
---|
| 3421 | + * return 0 on success |
---|
| 3422 | + * return 1 on fail |
---|
| 3423 | + */ |
---|
| 3424 | +int check_for_cap_sys_rawio(void) |
---|
3068 | 3425 | { |
---|
3069 | | - struct __user_cap_header_struct cap_header_data; |
---|
3070 | | - cap_user_header_t cap_header = &cap_header_data; |
---|
3071 | | - struct __user_cap_data_struct cap_data_data; |
---|
3072 | | - cap_user_data_t cap_data = &cap_data_data; |
---|
3073 | | - extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); |
---|
| 3426 | + cap_t caps; |
---|
| 3427 | + cap_flag_value_t cap_flag_value; |
---|
| 3428 | + |
---|
| 3429 | + caps = cap_get_proc(); |
---|
| 3430 | + if (caps == NULL) |
---|
| 3431 | + err(-6, "cap_get_proc\n"); |
---|
| 3432 | + |
---|
| 3433 | + if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value)) |
---|
| 3434 | + err(-6, "cap_get\n"); |
---|
| 3435 | + |
---|
| 3436 | + if (cap_flag_value != CAP_SET) { |
---|
| 3437 | + warnx("capget(CAP_SYS_RAWIO) failed," |
---|
| 3438 | + " try \"# setcap cap_sys_rawio=ep %s\"", progname); |
---|
| 3439 | + return 1; |
---|
| 3440 | + } |
---|
| 3441 | + |
---|
| 3442 | + if (cap_free(caps) == -1) |
---|
| 3443 | + err(-6, "cap_free\n"); |
---|
| 3444 | + |
---|
| 3445 | + return 0; |
---|
| 3446 | +} |
---|
| 3447 | +void check_permissions(void) |
---|
| 3448 | +{ |
---|
3074 | 3449 | int do_exit = 0; |
---|
3075 | 3450 | char pathname[32]; |
---|
3076 | 3451 | |
---|
3077 | 3452 | /* check for CAP_SYS_RAWIO */ |
---|
3078 | | - cap_header->pid = getpid(); |
---|
3079 | | - cap_header->version = _LINUX_CAPABILITY_VERSION; |
---|
3080 | | - if (capget(cap_header, cap_data) < 0) |
---|
3081 | | - err(-6, "capget(2) failed"); |
---|
3082 | | - |
---|
3083 | | - if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { |
---|
3084 | | - do_exit++; |
---|
3085 | | - warnx("capget(CAP_SYS_RAWIO) failed," |
---|
3086 | | - " try \"# setcap cap_sys_rawio=ep %s\"", progname); |
---|
3087 | | - } |
---|
| 3453 | + do_exit += check_for_cap_sys_rawio(); |
---|
3088 | 3454 | |
---|
3089 | 3455 | /* test file permissions */ |
---|
3090 | 3456 | sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); |
---|
.. | .. |
---|
3136 | 3502 | bclk = discover_bclk(family, model); |
---|
3137 | 3503 | |
---|
3138 | 3504 | switch (model) { |
---|
3139 | | - case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ |
---|
3140 | 3505 | case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ |
---|
3141 | | - case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
---|
3142 | | - case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */ |
---|
3143 | | - case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */ |
---|
3144 | 3506 | case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ |
---|
3145 | | - case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ |
---|
3146 | 3507 | pkg_cstate_limits = nhm_pkg_cstate_limits; |
---|
3147 | 3508 | break; |
---|
3148 | 3509 | case INTEL_FAM6_SANDYBRIDGE: /* SNB */ |
---|
.. | .. |
---|
3152 | 3513 | pkg_cstate_limits = snb_pkg_cstate_limits; |
---|
3153 | 3514 | has_misc_feature_control = 1; |
---|
3154 | 3515 | break; |
---|
3155 | | - case INTEL_FAM6_HASWELL_CORE: /* HSW */ |
---|
| 3516 | + case INTEL_FAM6_HASWELL: /* HSW */ |
---|
| 3517 | + case INTEL_FAM6_HASWELL_G: /* HSW */ |
---|
3156 | 3518 | case INTEL_FAM6_HASWELL_X: /* HSX */ |
---|
3157 | | - case INTEL_FAM6_HASWELL_ULT: /* HSW */ |
---|
3158 | | - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ |
---|
3159 | | - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ |
---|
3160 | | - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ |
---|
| 3519 | + case INTEL_FAM6_HASWELL_L: /* HSW */ |
---|
| 3520 | + case INTEL_FAM6_BROADWELL: /* BDW */ |
---|
| 3521 | + case INTEL_FAM6_BROADWELL_G: /* BDW */ |
---|
3161 | 3522 | case INTEL_FAM6_BROADWELL_X: /* BDX */ |
---|
3162 | | - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ |
---|
3163 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
3164 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
3165 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
3166 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
3167 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
| 3523 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
| 3524 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
3168 | 3525 | pkg_cstate_limits = hsw_pkg_cstate_limits; |
---|
3169 | 3526 | has_misc_feature_control = 1; |
---|
3170 | 3527 | break; |
---|
.. | .. |
---|
3174 | 3531 | break; |
---|
3175 | 3532 | case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ |
---|
3176 | 3533 | no_MSR_MISC_PWR_MGMT = 1; |
---|
3177 | | - case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */ |
---|
| 3534 | + case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ |
---|
3178 | 3535 | pkg_cstate_limits = slv_pkg_cstate_limits; |
---|
3179 | 3536 | break; |
---|
3180 | 3537 | case INTEL_FAM6_ATOM_AIRMONT: /* AMT */ |
---|
.. | .. |
---|
3182 | 3539 | no_MSR_MISC_PWR_MGMT = 1; |
---|
3183 | 3540 | break; |
---|
3184 | 3541 | case INTEL_FAM6_XEON_PHI_KNL: /* PHI */ |
---|
3185 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
3186 | 3542 | pkg_cstate_limits = phi_pkg_cstate_limits; |
---|
3187 | 3543 | break; |
---|
3188 | 3544 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
---|
3189 | 3545 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
---|
3190 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ |
---|
| 3546 | + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
---|
| 3547 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ |
---|
| 3548 | + case INTEL_FAM6_ATOM_TREMONT_D: /* JVL */ |
---|
3191 | 3549 | pkg_cstate_limits = glm_pkg_cstate_limits; |
---|
3192 | 3550 | break; |
---|
3193 | 3551 | default: |
---|
.. | .. |
---|
3230 | 3588 | return 0; |
---|
3231 | 3589 | |
---|
3232 | 3590 | switch (model) { |
---|
3233 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: |
---|
| 3591 | + case INTEL_FAM6_ATOM_GOLDMONT_D: |
---|
3234 | 3592 | return 1; |
---|
3235 | 3593 | } |
---|
3236 | 3594 | return 0; |
---|
.. | .. |
---|
3243 | 3601 | |
---|
3244 | 3602 | switch (model) { |
---|
3245 | 3603 | case INTEL_FAM6_BROADWELL_X: |
---|
3246 | | - case INTEL_FAM6_BROADWELL_XEON_D: |
---|
3247 | 3604 | return 1; |
---|
3248 | 3605 | } |
---|
3249 | 3606 | return 0; |
---|
.. | .. |
---|
3260 | 3617 | } |
---|
3261 | 3618 | return 0; |
---|
3262 | 3619 | } |
---|
| 3620 | +int is_ehl(unsigned int family, unsigned int model) |
---|
| 3621 | +{ |
---|
| 3622 | + if (!genuine_intel) |
---|
| 3623 | + return 0; |
---|
| 3624 | + |
---|
| 3625 | + switch (model) { |
---|
| 3626 | + case INTEL_FAM6_ATOM_TREMONT: |
---|
| 3627 | + return 1; |
---|
| 3628 | + } |
---|
| 3629 | + return 0; |
---|
| 3630 | +} |
---|
| 3631 | +int is_jvl(unsigned int family, unsigned int model) |
---|
| 3632 | +{ |
---|
| 3633 | + if (!genuine_intel) |
---|
| 3634 | + return 0; |
---|
| 3635 | + |
---|
| 3636 | + switch (model) { |
---|
| 3637 | + case INTEL_FAM6_ATOM_TREMONT_D: |
---|
| 3638 | + return 1; |
---|
| 3639 | + } |
---|
| 3640 | + return 0; |
---|
| 3641 | +} |
---|
3263 | 3642 | |
---|
3264 | 3643 | int has_turbo_ratio_limit(unsigned int family, unsigned int model) |
---|
3265 | 3644 | { |
---|
.. | .. |
---|
3269 | 3648 | switch (model) { |
---|
3270 | 3649 | /* Nehalem compatible, but do not include turbo-ratio limit support */ |
---|
3271 | 3650 | case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ |
---|
3272 | | - case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ |
---|
3273 | 3651 | case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */ |
---|
3274 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
3275 | 3652 | return 0; |
---|
3276 | 3653 | default: |
---|
3277 | 3654 | return 1; |
---|
.. | .. |
---|
3326 | 3703 | |
---|
3327 | 3704 | switch (model) { |
---|
3328 | 3705 | case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ |
---|
3329 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
3330 | 3706 | return 1; |
---|
3331 | 3707 | default: |
---|
3332 | 3708 | return 0; |
---|
.. | .. |
---|
3358 | 3734 | |
---|
3359 | 3735 | switch (model) { |
---|
3360 | 3736 | case INTEL_FAM6_IVYBRIDGE: /* IVB */ |
---|
3361 | | - case INTEL_FAM6_HASWELL_CORE: /* HSW */ |
---|
| 3737 | + case INTEL_FAM6_HASWELL: /* HSW */ |
---|
3362 | 3738 | case INTEL_FAM6_HASWELL_X: /* HSX */ |
---|
3363 | | - case INTEL_FAM6_HASWELL_ULT: /* HSW */ |
---|
3364 | | - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ |
---|
3365 | | - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ |
---|
3366 | | - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ |
---|
| 3739 | + case INTEL_FAM6_HASWELL_L: /* HSW */ |
---|
| 3740 | + case INTEL_FAM6_HASWELL_G: /* HSW */ |
---|
| 3741 | + case INTEL_FAM6_BROADWELL: /* BDW */ |
---|
| 3742 | + case INTEL_FAM6_BROADWELL_G: /* BDW */ |
---|
3367 | 3743 | case INTEL_FAM6_BROADWELL_X: /* BDX */ |
---|
3368 | | - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ |
---|
3369 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
3370 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
3371 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
3372 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
3373 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
| 3744 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
| 3745 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
3374 | 3746 | case INTEL_FAM6_SKYLAKE_X: /* SKX */ |
---|
3375 | 3747 | |
---|
3376 | 3748 | case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ |
---|
3377 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
3378 | 3749 | return 1; |
---|
3379 | 3750 | default: |
---|
3380 | 3751 | return 0; |
---|
3381 | 3752 | } |
---|
| 3753 | +} |
---|
| 3754 | + |
---|
| 3755 | +static void |
---|
| 3756 | +remove_underbar(char *s) |
---|
| 3757 | +{ |
---|
| 3758 | + char *to = s; |
---|
| 3759 | + |
---|
| 3760 | + while (*s) { |
---|
| 3761 | + if (*s != '_') |
---|
| 3762 | + *to++ = *s; |
---|
| 3763 | + s++; |
---|
| 3764 | + } |
---|
| 3765 | + |
---|
| 3766 | + *to = 0; |
---|
3382 | 3767 | } |
---|
3383 | 3768 | |
---|
3384 | 3769 | static void |
---|
.. | .. |
---|
3410 | 3795 | dump_nhm_cst_cfg(); |
---|
3411 | 3796 | } |
---|
3412 | 3797 | |
---|
| 3798 | +static void dump_sysfs_file(char *path) |
---|
| 3799 | +{ |
---|
| 3800 | + FILE *input; |
---|
| 3801 | + char cpuidle_buf[64]; |
---|
| 3802 | + |
---|
| 3803 | + input = fopen(path, "r"); |
---|
| 3804 | + if (input == NULL) { |
---|
| 3805 | + if (debug) |
---|
| 3806 | + fprintf(outf, "NSFOD %s\n", path); |
---|
| 3807 | + return; |
---|
| 3808 | + } |
---|
| 3809 | + if (!fgets(cpuidle_buf, sizeof(cpuidle_buf), input)) |
---|
| 3810 | + err(1, "%s: failed to read file", path); |
---|
| 3811 | + fclose(input); |
---|
| 3812 | + |
---|
| 3813 | + fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf); |
---|
| 3814 | +} |
---|
3413 | 3815 | static void |
---|
3414 | 3816 | dump_sysfs_cstate_config(void) |
---|
3415 | 3817 | { |
---|
.. | .. |
---|
3420 | 3822 | int state; |
---|
3421 | 3823 | char *sp; |
---|
3422 | 3824 | |
---|
3423 | | - if (!DO_BIC(BIC_sysfs)) |
---|
| 3825 | + if (access("/sys/devices/system/cpu/cpuidle", R_OK)) { |
---|
| 3826 | + fprintf(outf, "cpuidle not loaded\n"); |
---|
3424 | 3827 | return; |
---|
| 3828 | + } |
---|
| 3829 | + |
---|
| 3830 | + dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver"); |
---|
| 3831 | + dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor"); |
---|
| 3832 | + dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro"); |
---|
3425 | 3833 | |
---|
3426 | 3834 | for (state = 0; state < 10; ++state) { |
---|
3427 | 3835 | |
---|
.. | .. |
---|
3430 | 3838 | input = fopen(path, "r"); |
---|
3431 | 3839 | if (input == NULL) |
---|
3432 | 3840 | continue; |
---|
3433 | | - fgets(name_buf, sizeof(name_buf), input); |
---|
| 3841 | + if (!fgets(name_buf, sizeof(name_buf), input)) |
---|
| 3842 | + err(1, "%s: failed to read file", path); |
---|
3434 | 3843 | |
---|
3435 | 3844 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ |
---|
3436 | 3845 | sp = strchr(name_buf, '-'); |
---|
3437 | 3846 | if (!sp) |
---|
3438 | 3847 | sp = strchrnul(name_buf, '\n'); |
---|
3439 | 3848 | *sp = '\0'; |
---|
3440 | | - |
---|
3441 | 3849 | fclose(input); |
---|
| 3850 | + |
---|
| 3851 | + remove_underbar(name_buf); |
---|
3442 | 3852 | |
---|
3443 | 3853 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", |
---|
3444 | 3854 | base_cpu, state); |
---|
3445 | 3855 | input = fopen(path, "r"); |
---|
3446 | 3856 | if (input == NULL) |
---|
3447 | 3857 | continue; |
---|
3448 | | - fgets(desc, sizeof(desc), input); |
---|
| 3858 | + if (!fgets(desc, sizeof(desc), input)) |
---|
| 3859 | + err(1, "%s: failed to read file", path); |
---|
3449 | 3860 | |
---|
3450 | 3861 | fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc); |
---|
3451 | 3862 | fclose(input); |
---|
.. | .. |
---|
3464 | 3875 | base_cpu); |
---|
3465 | 3876 | input = fopen(path, "r"); |
---|
3466 | 3877 | if (input == NULL) { |
---|
3467 | | - fprintf(stderr, "NSFOD %s\n", path); |
---|
| 3878 | + fprintf(outf, "NSFOD %s\n", path); |
---|
3468 | 3879 | return; |
---|
3469 | 3880 | } |
---|
3470 | | - fgets(driver_buf, sizeof(driver_buf), input); |
---|
| 3881 | + if (!fgets(driver_buf, sizeof(driver_buf), input)) |
---|
| 3882 | + err(1, "%s: failed to read file", path); |
---|
3471 | 3883 | fclose(input); |
---|
3472 | 3884 | |
---|
3473 | 3885 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", |
---|
3474 | 3886 | base_cpu); |
---|
3475 | 3887 | input = fopen(path, "r"); |
---|
3476 | 3888 | if (input == NULL) { |
---|
3477 | | - fprintf(stderr, "NSFOD %s\n", path); |
---|
| 3889 | + fprintf(outf, "NSFOD %s\n", path); |
---|
3478 | 3890 | return; |
---|
3479 | 3891 | } |
---|
3480 | | - fgets(governor_buf, sizeof(governor_buf), input); |
---|
| 3892 | + if (!fgets(governor_buf, sizeof(governor_buf), input)) |
---|
| 3893 | + err(1, "%s: failed to read file", path); |
---|
3481 | 3894 | fclose(input); |
---|
3482 | 3895 | |
---|
3483 | 3896 | fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf); |
---|
.. | .. |
---|
3486 | 3899 | sprintf(path, "/sys/devices/system/cpu/cpufreq/boost"); |
---|
3487 | 3900 | input = fopen(path, "r"); |
---|
3488 | 3901 | if (input != NULL) { |
---|
3489 | | - fscanf(input, "%d", &turbo); |
---|
| 3902 | + if (fscanf(input, "%d", &turbo) != 1) |
---|
| 3903 | + err(1, "%s: failed to parse number from file", path); |
---|
3490 | 3904 | fprintf(outf, "cpufreq boost: %d\n", turbo); |
---|
3491 | 3905 | fclose(input); |
---|
3492 | 3906 | } |
---|
.. | .. |
---|
3494 | 3908 | sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo"); |
---|
3495 | 3909 | input = fopen(path, "r"); |
---|
3496 | 3910 | if (input != NULL) { |
---|
3497 | | - fscanf(input, "%d", &turbo); |
---|
| 3911 | + if (fscanf(input, "%d", &turbo) != 1) |
---|
| 3912 | + err(1, "%s: failed to parse number from file", path); |
---|
3498 | 3913 | fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo); |
---|
3499 | 3914 | fclose(input); |
---|
3500 | 3915 | } |
---|
.. | .. |
---|
3521 | 3936 | return 0; |
---|
3522 | 3937 | |
---|
3523 | 3938 | if (cpu_migrate(cpu)) { |
---|
3524 | | - fprintf(outf, "Could not migrate to CPU %d\n", cpu); |
---|
| 3939 | + fprintf(outf, "print_epb: Could not migrate to CPU %d\n", cpu); |
---|
3525 | 3940 | return -1; |
---|
3526 | 3941 | } |
---|
3527 | 3942 | |
---|
.. | .. |
---|
3565 | 3980 | return 0; |
---|
3566 | 3981 | |
---|
3567 | 3982 | if (cpu_migrate(cpu)) { |
---|
3568 | | - fprintf(outf, "Could not migrate to CPU %d\n", cpu); |
---|
| 3983 | + fprintf(outf, "print_hwp: Could not migrate to CPU %d\n", cpu); |
---|
3569 | 3984 | return -1; |
---|
3570 | 3985 | } |
---|
3571 | 3986 | |
---|
.. | .. |
---|
3653 | 4068 | return 0; |
---|
3654 | 4069 | |
---|
3655 | 4070 | if (cpu_migrate(cpu)) { |
---|
3656 | | - fprintf(outf, "Could not migrate to CPU %d\n", cpu); |
---|
| 4071 | + fprintf(outf, "print_perf_limit: Could not migrate to CPU %d\n", cpu); |
---|
3657 | 4072 | return -1; |
---|
3658 | 4073 | } |
---|
3659 | 4074 | |
---|
.. | .. |
---|
3738 | 4153 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
---|
3739 | 4154 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
---|
3740 | 4155 | |
---|
3741 | | -double get_tdp(unsigned int model) |
---|
| 4156 | +double get_tdp_intel(unsigned int model) |
---|
3742 | 4157 | { |
---|
3743 | 4158 | unsigned long long msr; |
---|
3744 | 4159 | |
---|
.. | .. |
---|
3748 | 4163 | |
---|
3749 | 4164 | switch (model) { |
---|
3750 | 4165 | case INTEL_FAM6_ATOM_SILVERMONT: |
---|
3751 | | - case INTEL_FAM6_ATOM_SILVERMONT_X: |
---|
| 4166 | + case INTEL_FAM6_ATOM_SILVERMONT_D: |
---|
3752 | 4167 | return 30.0; |
---|
3753 | 4168 | default: |
---|
3754 | 4169 | return 135.0; |
---|
3755 | 4170 | } |
---|
| 4171 | +} |
---|
| 4172 | + |
---|
| 4173 | +double get_tdp_amd(unsigned int family) |
---|
| 4174 | +{ |
---|
| 4175 | + /* This is the max stock TDP of HEDT/Server Fam17h+ chips */ |
---|
| 4176 | + return 280.0; |
---|
3756 | 4177 | } |
---|
3757 | 4178 | |
---|
3758 | 4179 | /* |
---|
.. | .. |
---|
3767 | 4188 | switch (model) { |
---|
3768 | 4189 | case INTEL_FAM6_HASWELL_X: /* HSX */ |
---|
3769 | 4190 | case INTEL_FAM6_BROADWELL_X: /* BDX */ |
---|
3770 | | - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ |
---|
3771 | 4191 | case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ |
---|
3772 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
| 4192 | + case INTEL_FAM6_ICELAKE_X: /* ICX */ |
---|
3773 | 4193 | return (rapl_dram_energy_units = 15.3 / 1000000); |
---|
3774 | 4194 | default: |
---|
3775 | 4195 | return (rapl_energy_units); |
---|
3776 | 4196 | } |
---|
3777 | 4197 | } |
---|
3778 | 4198 | |
---|
3779 | | - |
---|
3780 | | -/* |
---|
3781 | | - * rapl_probe() |
---|
3782 | | - * |
---|
3783 | | - * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units |
---|
3784 | | - */ |
---|
3785 | | -void rapl_probe(unsigned int family, unsigned int model) |
---|
| 4199 | +void rapl_probe_intel(unsigned int family, unsigned int model) |
---|
3786 | 4200 | { |
---|
3787 | 4201 | unsigned long long msr; |
---|
3788 | 4202 | unsigned int time_unit; |
---|
3789 | 4203 | double tdp; |
---|
3790 | | - |
---|
3791 | | - if (!genuine_intel) |
---|
3792 | | - return; |
---|
3793 | 4204 | |
---|
3794 | 4205 | if (family != 6) |
---|
3795 | 4206 | return; |
---|
.. | .. |
---|
3797 | 4208 | switch (model) { |
---|
3798 | 4209 | case INTEL_FAM6_SANDYBRIDGE: |
---|
3799 | 4210 | case INTEL_FAM6_IVYBRIDGE: |
---|
3800 | | - case INTEL_FAM6_HASWELL_CORE: /* HSW */ |
---|
3801 | | - case INTEL_FAM6_HASWELL_ULT: /* HSW */ |
---|
3802 | | - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ |
---|
3803 | | - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ |
---|
3804 | | - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ |
---|
| 4211 | + case INTEL_FAM6_HASWELL: /* HSW */ |
---|
| 4212 | + case INTEL_FAM6_HASWELL_L: /* HSW */ |
---|
| 4213 | + case INTEL_FAM6_HASWELL_G: /* HSW */ |
---|
| 4214 | + case INTEL_FAM6_BROADWELL: /* BDW */ |
---|
| 4215 | + case INTEL_FAM6_BROADWELL_G: /* BDW */ |
---|
3805 | 4216 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; |
---|
3806 | 4217 | if (rapl_joules) { |
---|
3807 | 4218 | BIC_PRESENT(BIC_Pkg_J); |
---|
.. | .. |
---|
3821 | 4232 | else |
---|
3822 | 4233 | BIC_PRESENT(BIC_PkgWatt); |
---|
3823 | 4234 | break; |
---|
3824 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
3825 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
3826 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
3827 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
3828 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
| 4235 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ |
---|
| 4236 | + do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; |
---|
| 4237 | + if (rapl_joules) { |
---|
| 4238 | + BIC_PRESENT(BIC_Pkg_J); |
---|
| 4239 | + BIC_PRESENT(BIC_Cor_J); |
---|
| 4240 | + BIC_PRESENT(BIC_RAM_J); |
---|
| 4241 | + BIC_PRESENT(BIC_GFX_J); |
---|
| 4242 | + } else { |
---|
| 4243 | + BIC_PRESENT(BIC_PkgWatt); |
---|
| 4244 | + BIC_PRESENT(BIC_CorWatt); |
---|
| 4245 | + BIC_PRESENT(BIC_RAMWatt); |
---|
| 4246 | + BIC_PRESENT(BIC_GFXWatt); |
---|
| 4247 | + } |
---|
| 4248 | + break; |
---|
| 4249 | + case INTEL_FAM6_ATOM_TREMONT_D: /* JVL */ |
---|
| 4250 | + do_rapl = RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; |
---|
| 4251 | + BIC_PRESENT(BIC_PKG__); |
---|
| 4252 | + if (rapl_joules) |
---|
| 4253 | + BIC_PRESENT(BIC_Pkg_J); |
---|
| 4254 | + else |
---|
| 4255 | + BIC_PRESENT(BIC_PkgWatt); |
---|
| 4256 | + break; |
---|
| 4257 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
| 4258 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
3829 | 4259 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; |
---|
3830 | 4260 | BIC_PRESENT(BIC_PKG__); |
---|
3831 | 4261 | BIC_PRESENT(BIC_RAM__); |
---|
.. | .. |
---|
3843 | 4273 | break; |
---|
3844 | 4274 | case INTEL_FAM6_HASWELL_X: /* HSX */ |
---|
3845 | 4275 | case INTEL_FAM6_BROADWELL_X: /* BDX */ |
---|
3846 | | - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ |
---|
3847 | 4276 | case INTEL_FAM6_SKYLAKE_X: /* SKX */ |
---|
3848 | 4277 | case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ |
---|
3849 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
3850 | 4278 | do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; |
---|
3851 | 4279 | BIC_PRESENT(BIC_PKG__); |
---|
3852 | 4280 | BIC_PRESENT(BIC_RAM__); |
---|
.. | .. |
---|
3874 | 4302 | } |
---|
3875 | 4303 | break; |
---|
3876 | 4304 | case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ |
---|
3877 | | - case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */ |
---|
| 4305 | + case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ |
---|
3878 | 4306 | do_rapl = RAPL_PKG | RAPL_CORES; |
---|
3879 | 4307 | if (rapl_joules) { |
---|
3880 | 4308 | BIC_PRESENT(BIC_Pkg_J); |
---|
.. | .. |
---|
3884 | 4312 | BIC_PRESENT(BIC_CorWatt); |
---|
3885 | 4313 | } |
---|
3886 | 4314 | break; |
---|
3887 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ |
---|
| 4315 | + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
---|
3888 | 4316 | do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS; |
---|
3889 | 4317 | BIC_PRESENT(BIC_PKG__); |
---|
3890 | 4318 | BIC_PRESENT(BIC_RAM__); |
---|
.. | .. |
---|
3920 | 4348 | |
---|
3921 | 4349 | rapl_time_units = 1.0 / (1 << (time_unit)); |
---|
3922 | 4350 | |
---|
3923 | | - tdp = get_tdp(model); |
---|
| 4351 | + tdp = get_tdp_intel(model); |
---|
3924 | 4352 | |
---|
3925 | 4353 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; |
---|
3926 | 4354 | if (!quiet) |
---|
3927 | 4355 | fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); |
---|
| 4356 | +} |
---|
3928 | 4357 | |
---|
3929 | | - return; |
---|
| 4358 | +void rapl_probe_amd(unsigned int family, unsigned int model) |
---|
| 4359 | +{ |
---|
| 4360 | + unsigned long long msr; |
---|
| 4361 | + unsigned int eax, ebx, ecx, edx; |
---|
| 4362 | + unsigned int has_rapl = 0; |
---|
| 4363 | + double tdp; |
---|
| 4364 | + |
---|
| 4365 | + if (max_extended_level >= 0x80000007) { |
---|
| 4366 | + __cpuid(0x80000007, eax, ebx, ecx, edx); |
---|
| 4367 | + /* RAPL (Fam 17h+) */ |
---|
| 4368 | + has_rapl = edx & (1 << 14); |
---|
| 4369 | + } |
---|
| 4370 | + |
---|
| 4371 | + if (!has_rapl || family < 0x17) |
---|
| 4372 | + return; |
---|
| 4373 | + |
---|
| 4374 | + do_rapl = RAPL_AMD_F17H | RAPL_PER_CORE_ENERGY; |
---|
| 4375 | + if (rapl_joules) { |
---|
| 4376 | + BIC_PRESENT(BIC_Pkg_J); |
---|
| 4377 | + BIC_PRESENT(BIC_Cor_J); |
---|
| 4378 | + } else { |
---|
| 4379 | + BIC_PRESENT(BIC_PkgWatt); |
---|
| 4380 | + BIC_PRESENT(BIC_CorWatt); |
---|
| 4381 | + } |
---|
| 4382 | + |
---|
| 4383 | + if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr)) |
---|
| 4384 | + return; |
---|
| 4385 | + |
---|
| 4386 | + rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf)); |
---|
| 4387 | + rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f)); |
---|
| 4388 | + rapl_power_units = ldexp(1.0, -(msr & 0xf)); |
---|
| 4389 | + |
---|
| 4390 | + tdp = get_tdp_amd(family); |
---|
| 4391 | + |
---|
| 4392 | + rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; |
---|
| 4393 | + if (!quiet) |
---|
| 4394 | + fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); |
---|
| 4395 | +} |
---|
| 4396 | + |
---|
| 4397 | +/* |
---|
| 4398 | + * rapl_probe() |
---|
| 4399 | + * |
---|
| 4400 | + * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units |
---|
| 4401 | + */ |
---|
| 4402 | +void rapl_probe(unsigned int family, unsigned int model) |
---|
| 4403 | +{ |
---|
| 4404 | + if (genuine_intel) |
---|
| 4405 | + rapl_probe_intel(family, model); |
---|
| 4406 | + if (authentic_amd || hygon_genuine) |
---|
| 4407 | + rapl_probe_amd(family, model); |
---|
3930 | 4408 | } |
---|
3931 | 4409 | |
---|
3932 | 4410 | void perf_limit_reasons_probe(unsigned int family, unsigned int model) |
---|
.. | .. |
---|
3938 | 4416 | return; |
---|
3939 | 4417 | |
---|
3940 | 4418 | switch (model) { |
---|
3941 | | - case INTEL_FAM6_HASWELL_CORE: /* HSW */ |
---|
3942 | | - case INTEL_FAM6_HASWELL_ULT: /* HSW */ |
---|
3943 | | - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ |
---|
| 4419 | + case INTEL_FAM6_HASWELL: /* HSW */ |
---|
| 4420 | + case INTEL_FAM6_HASWELL_L: /* HSW */ |
---|
| 4421 | + case INTEL_FAM6_HASWELL_G: /* HSW */ |
---|
3944 | 4422 | do_gfx_perf_limit_reasons = 1; |
---|
3945 | 4423 | case INTEL_FAM6_HASWELL_X: /* HSX */ |
---|
3946 | 4424 | do_core_perf_limit_reasons = 1; |
---|
.. | .. |
---|
3972 | 4450 | return 0; |
---|
3973 | 4451 | |
---|
3974 | 4452 | if (cpu_migrate(cpu)) { |
---|
3975 | | - fprintf(outf, "Could not migrate to CPU %d\n", cpu); |
---|
| 4453 | + fprintf(outf, "print_thermal: Could not migrate to CPU %d\n", cpu); |
---|
3976 | 4454 | return -1; |
---|
3977 | 4455 | } |
---|
3978 | 4456 | |
---|
.. | .. |
---|
4032 | 4510 | int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) |
---|
4033 | 4511 | { |
---|
4034 | 4512 | unsigned long long msr; |
---|
| 4513 | + const char *msr_name; |
---|
4035 | 4514 | int cpu; |
---|
4036 | 4515 | |
---|
4037 | 4516 | if (!do_rapl) |
---|
.. | .. |
---|
4043 | 4522 | |
---|
4044 | 4523 | cpu = t->cpu_id; |
---|
4045 | 4524 | if (cpu_migrate(cpu)) { |
---|
4046 | | - fprintf(outf, "Could not migrate to CPU %d\n", cpu); |
---|
| 4525 | + fprintf(outf, "print_rapl: Could not migrate to CPU %d\n", cpu); |
---|
4047 | 4526 | return -1; |
---|
4048 | 4527 | } |
---|
4049 | 4528 | |
---|
4050 | | - if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) |
---|
4051 | | - return -1; |
---|
| 4529 | + if (do_rapl & RAPL_AMD_F17H) { |
---|
| 4530 | + msr_name = "MSR_RAPL_PWR_UNIT"; |
---|
| 4531 | + if (get_msr(cpu, MSR_RAPL_PWR_UNIT, &msr)) |
---|
| 4532 | + return -1; |
---|
| 4533 | + } else { |
---|
| 4534 | + msr_name = "MSR_RAPL_POWER_UNIT"; |
---|
| 4535 | + if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) |
---|
| 4536 | + return -1; |
---|
| 4537 | + } |
---|
4052 | 4538 | |
---|
4053 | | - fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr, |
---|
| 4539 | + fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr, |
---|
4054 | 4540 | rapl_power_units, rapl_energy_units, rapl_time_units); |
---|
4055 | 4541 | |
---|
4056 | 4542 | if (do_rapl & RAPL_PKG_POWER_INFO) { |
---|
.. | .. |
---|
4147 | 4633 | switch (model) { |
---|
4148 | 4634 | case INTEL_FAM6_SANDYBRIDGE: |
---|
4149 | 4635 | case INTEL_FAM6_SANDYBRIDGE_X: |
---|
4150 | | - case INTEL_FAM6_IVYBRIDGE: /* IVB */ |
---|
4151 | | - case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ |
---|
4152 | | - case INTEL_FAM6_HASWELL_CORE: /* HSW */ |
---|
4153 | | - case INTEL_FAM6_HASWELL_X: /* HSW */ |
---|
4154 | | - case INTEL_FAM6_HASWELL_ULT: /* HSW */ |
---|
4155 | | - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ |
---|
4156 | | - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ |
---|
4157 | | - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ |
---|
4158 | | - case INTEL_FAM6_BROADWELL_X: /* BDX */ |
---|
4159 | | - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ |
---|
4160 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
4161 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
4162 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
4163 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
4164 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
4165 | | - case INTEL_FAM6_SKYLAKE_X: /* SKX */ |
---|
4166 | | - case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
---|
| 4636 | + case INTEL_FAM6_IVYBRIDGE: /* IVB */ |
---|
| 4637 | + case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ |
---|
| 4638 | + case INTEL_FAM6_HASWELL: /* HSW */ |
---|
| 4639 | + case INTEL_FAM6_HASWELL_X: /* HSW */ |
---|
| 4640 | + case INTEL_FAM6_HASWELL_L: /* HSW */ |
---|
| 4641 | + case INTEL_FAM6_HASWELL_G: /* HSW */ |
---|
| 4642 | + case INTEL_FAM6_BROADWELL: /* BDW */ |
---|
| 4643 | + case INTEL_FAM6_BROADWELL_G: /* BDW */ |
---|
| 4644 | + case INTEL_FAM6_BROADWELL_X: /* BDX */ |
---|
| 4645 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
| 4646 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
| 4647 | + case INTEL_FAM6_SKYLAKE_X: /* SKX */ |
---|
| 4648 | + case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
---|
4167 | 4649 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
---|
4168 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ |
---|
| 4650 | + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
---|
| 4651 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ |
---|
| 4652 | + case INTEL_FAM6_ATOM_TREMONT_D: /* JVL */ |
---|
4169 | 4653 | return 1; |
---|
4170 | 4654 | } |
---|
4171 | 4655 | return 0; |
---|
4172 | 4656 | } |
---|
4173 | 4657 | |
---|
4174 | 4658 | /* |
---|
4175 | | - * HSW adds support for additional MSRs: |
---|
| 4659 | + * HSW ULT added support for C8/C9/C10 MSRs: |
---|
4176 | 4660 | * |
---|
4177 | 4661 | * MSR_PKG_C8_RESIDENCY 0x00000630 |
---|
4178 | 4662 | * MSR_PKG_C9_RESIDENCY 0x00000631 |
---|
.. | .. |
---|
4183 | 4667 | * MSR_PKGC10_IRTL 0x00000635 |
---|
4184 | 4668 | * |
---|
4185 | 4669 | */ |
---|
4186 | | -int has_hsw_msrs(unsigned int family, unsigned int model) |
---|
| 4670 | +int has_c8910_msrs(unsigned int family, unsigned int model) |
---|
4187 | 4671 | { |
---|
4188 | 4672 | if (!genuine_intel) |
---|
4189 | 4673 | return 0; |
---|
4190 | 4674 | |
---|
4191 | 4675 | switch (model) { |
---|
4192 | | - case INTEL_FAM6_HASWELL_ULT: /* HSW */ |
---|
4193 | | - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ |
---|
4194 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
4195 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
4196 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
4197 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
4198 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
| 4676 | + case INTEL_FAM6_HASWELL_L: /* HSW */ |
---|
| 4677 | + case INTEL_FAM6_BROADWELL: /* BDW */ |
---|
| 4678 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
| 4679 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
4199 | 4680 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
---|
4200 | 4681 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
---|
| 4682 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ |
---|
4201 | 4683 | return 1; |
---|
4202 | 4684 | } |
---|
4203 | 4685 | return 0; |
---|
.. | .. |
---|
4217 | 4699 | return 0; |
---|
4218 | 4700 | |
---|
4219 | 4701 | switch (model) { |
---|
4220 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
4221 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
4222 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
4223 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
4224 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
| 4702 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
| 4703 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
4225 | 4704 | return 1; |
---|
4226 | 4705 | } |
---|
4227 | 4706 | return 0; |
---|
.. | .. |
---|
4233 | 4712 | return 0; |
---|
4234 | 4713 | switch (model) { |
---|
4235 | 4714 | case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ |
---|
4236 | | - case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */ |
---|
| 4715 | + case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ |
---|
4237 | 4716 | return 1; |
---|
4238 | 4717 | } |
---|
4239 | 4718 | return 0; |
---|
.. | .. |
---|
4245 | 4724 | return 0; |
---|
4246 | 4725 | switch (model) { |
---|
4247 | 4726 | case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ |
---|
4248 | | - case INTEL_FAM6_XEON_PHI_KNM: |
---|
4249 | 4727 | return 1; |
---|
4250 | 4728 | } |
---|
4251 | 4729 | return 0; |
---|
.. | .. |
---|
4257 | 4735 | return 0; |
---|
4258 | 4736 | |
---|
4259 | 4737 | switch (model) { |
---|
4260 | | - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ |
---|
| 4738 | + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
---|
4261 | 4739 | return 1; |
---|
4262 | 4740 | } |
---|
4263 | 4741 | |
---|
.. | .. |
---|
4377 | 4855 | { |
---|
4378 | 4856 | unsigned long long msr; |
---|
4379 | 4857 | |
---|
4380 | | - if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr)) |
---|
| 4858 | + if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr)) |
---|
4381 | 4859 | fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n", |
---|
4382 | 4860 | base_cpu, msr, |
---|
4383 | | - msr & FEATURE_CONTROL_LOCKED ? "" : "UN-", |
---|
| 4861 | + msr & FEAT_CTL_LOCKED ? "" : "UN-", |
---|
4384 | 4862 | msr & (1 << 18) ? "SGX" : ""); |
---|
4385 | 4863 | } |
---|
4386 | 4864 | |
---|
.. | .. |
---|
4459 | 4937 | base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS"); |
---|
4460 | 4938 | } |
---|
4461 | 4939 | |
---|
| 4940 | +/* |
---|
| 4941 | + * When models are the same, for the purpose of turbostat, reuse |
---|
| 4942 | + */ |
---|
| 4943 | +unsigned int intel_model_duplicates(unsigned int model) |
---|
| 4944 | +{ |
---|
| 4945 | + |
---|
| 4946 | + switch(model) { |
---|
| 4947 | + case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ |
---|
| 4948 | + case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ |
---|
| 4949 | + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
---|
| 4950 | + case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */ |
---|
| 4951 | + case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */ |
---|
| 4952 | + return INTEL_FAM6_NEHALEM; |
---|
| 4953 | + |
---|
| 4954 | + case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ |
---|
| 4955 | + case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ |
---|
| 4956 | + return INTEL_FAM6_NEHALEM_EX; |
---|
| 4957 | + |
---|
| 4958 | + case INTEL_FAM6_XEON_PHI_KNM: |
---|
| 4959 | + return INTEL_FAM6_XEON_PHI_KNL; |
---|
| 4960 | + |
---|
| 4961 | + case INTEL_FAM6_BROADWELL_X: |
---|
| 4962 | + case INTEL_FAM6_BROADWELL_D: /* BDX-DE */ |
---|
| 4963 | + return INTEL_FAM6_BROADWELL_X; |
---|
| 4964 | + |
---|
| 4965 | + case INTEL_FAM6_SKYLAKE_L: |
---|
| 4966 | + case INTEL_FAM6_SKYLAKE: |
---|
| 4967 | + case INTEL_FAM6_KABYLAKE_L: |
---|
| 4968 | + case INTEL_FAM6_KABYLAKE: |
---|
| 4969 | + case INTEL_FAM6_COMETLAKE_L: |
---|
| 4970 | + case INTEL_FAM6_COMETLAKE: |
---|
| 4971 | + return INTEL_FAM6_SKYLAKE_L; |
---|
| 4972 | + |
---|
| 4973 | + case INTEL_FAM6_ICELAKE_L: |
---|
| 4974 | + case INTEL_FAM6_ICELAKE_NNPI: |
---|
| 4975 | + case INTEL_FAM6_TIGERLAKE_L: |
---|
| 4976 | + case INTEL_FAM6_TIGERLAKE: |
---|
| 4977 | + case INTEL_FAM6_ROCKETLAKE: |
---|
| 4978 | + case INTEL_FAM6_LAKEFIELD: |
---|
| 4979 | + case INTEL_FAM6_ALDERLAKE: |
---|
| 4980 | + return INTEL_FAM6_CANNONLAKE_L; |
---|
| 4981 | + |
---|
| 4982 | + case INTEL_FAM6_ATOM_TREMONT_L: |
---|
| 4983 | + return INTEL_FAM6_ATOM_TREMONT; |
---|
| 4984 | + |
---|
| 4985 | + case INTEL_FAM6_ICELAKE_X: |
---|
| 4986 | + case INTEL_FAM6_SAPPHIRERAPIDS_X: |
---|
| 4987 | + return INTEL_FAM6_SKYLAKE_X; |
---|
| 4988 | + } |
---|
| 4989 | + return model; |
---|
| 4990 | +} |
---|
| 4991 | + |
---|
| 4992 | +void print_dev_latency(void) |
---|
| 4993 | +{ |
---|
| 4994 | + char *path = "/dev/cpu_dma_latency"; |
---|
| 4995 | + int fd; |
---|
| 4996 | + int value; |
---|
| 4997 | + int retval; |
---|
| 4998 | + |
---|
| 4999 | + fd = open(path, O_RDONLY); |
---|
| 5000 | + if (fd < 0) { |
---|
| 5001 | + warn("fopen %s\n", path); |
---|
| 5002 | + return; |
---|
| 5003 | + } |
---|
| 5004 | + |
---|
| 5005 | + retval = read(fd, (void *)&value, sizeof(int)); |
---|
| 5006 | + if (retval != sizeof(int)) { |
---|
| 5007 | + warn("read failed %s\n", path); |
---|
| 5008 | + close(fd); |
---|
| 5009 | + return; |
---|
| 5010 | + } |
---|
| 5011 | + fprintf(outf, "/dev/cpu_dma_latency: %d usec (%s)\n", |
---|
| 5012 | + value, value == 2000000000 ? "default" : "constrained"); |
---|
| 5013 | + |
---|
| 5014 | + close(fd); |
---|
| 5015 | +} |
---|
| 5016 | + |
---|
4462 | 5017 | void process_cpuid() |
---|
4463 | 5018 | { |
---|
4464 | 5019 | unsigned int eax, ebx, ecx, edx; |
---|
.. | .. |
---|
4473 | 5028 | genuine_intel = 1; |
---|
4474 | 5029 | else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) |
---|
4475 | 5030 | authentic_amd = 1; |
---|
| 5031 | + else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e) |
---|
| 5032 | + hygon_genuine = 1; |
---|
4476 | 5033 | |
---|
4477 | 5034 | if (!quiet) |
---|
4478 | 5035 | fprintf(outf, "CPUID(0): %.4s%.4s%.4s ", |
---|
.. | .. |
---|
4512 | 5069 | edx_flags & (1 << 28) ? "HT" : "-", |
---|
4513 | 5070 | edx_flags & (1 << 29) ? "TM" : "-"); |
---|
4514 | 5071 | } |
---|
| 5072 | + if (genuine_intel) |
---|
| 5073 | + model = intel_model_duplicates(model); |
---|
4515 | 5074 | |
---|
4516 | 5075 | if (!(edx_flags & (1 << 5))) |
---|
4517 | 5076 | errx(1, "CPUID: no MSR"); |
---|
.. | .. |
---|
4602 | 5161 | |
---|
4603 | 5162 | if (crystal_hz == 0) |
---|
4604 | 5163 | switch(model) { |
---|
4605 | | - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ |
---|
4606 | | - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ |
---|
4607 | | - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ |
---|
4608 | | - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ |
---|
| 5164 | + case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
---|
4609 | 5165 | crystal_hz = 24000000; /* 24.0 MHz */ |
---|
4610 | 5166 | break; |
---|
4611 | | - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ |
---|
| 5167 | + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
---|
4612 | 5168 | crystal_hz = 25000000; /* 25.0 MHz */ |
---|
4613 | 5169 | break; |
---|
4614 | 5170 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
---|
.. | .. |
---|
4676 | 5232 | BIC_PRESENT(BIC_Mod_c6); |
---|
4677 | 5233 | use_c1_residency_msr = 1; |
---|
4678 | 5234 | } |
---|
| 5235 | + if (is_jvl(family, model)) { |
---|
| 5236 | + BIC_NOT_PRESENT(BIC_CPU_c3); |
---|
| 5237 | + BIC_NOT_PRESENT(BIC_CPU_c7); |
---|
| 5238 | + BIC_NOT_PRESENT(BIC_Pkgpc2); |
---|
| 5239 | + BIC_NOT_PRESENT(BIC_Pkgpc3); |
---|
| 5240 | + BIC_NOT_PRESENT(BIC_Pkgpc6); |
---|
| 5241 | + BIC_NOT_PRESENT(BIC_Pkgpc7); |
---|
| 5242 | + } |
---|
4679 | 5243 | if (is_dnv(family, model)) { |
---|
4680 | 5244 | BIC_PRESENT(BIC_CPU_c1); |
---|
4681 | 5245 | BIC_NOT_PRESENT(BIC_CPU_c3); |
---|
.. | .. |
---|
4694 | 5258 | BIC_NOT_PRESENT(BIC_CPU_c7); |
---|
4695 | 5259 | BIC_NOT_PRESENT(BIC_Pkgpc7); |
---|
4696 | 5260 | } |
---|
4697 | | - if (has_hsw_msrs(family, model)) { |
---|
4698 | | - BIC_PRESENT(BIC_Pkgpc8); |
---|
4699 | | - BIC_PRESENT(BIC_Pkgpc9); |
---|
4700 | | - BIC_PRESENT(BIC_Pkgpc10); |
---|
| 5261 | + if (has_c8910_msrs(family, model)) { |
---|
| 5262 | + if (pkg_cstate_limit >= PCL__8) |
---|
| 5263 | + BIC_PRESENT(BIC_Pkgpc8); |
---|
| 5264 | + if (pkg_cstate_limit >= PCL__9) |
---|
| 5265 | + BIC_PRESENT(BIC_Pkgpc9); |
---|
| 5266 | + if (pkg_cstate_limit >= PCL_10) |
---|
| 5267 | + BIC_PRESENT(BIC_Pkgpc10); |
---|
4701 | 5268 | } |
---|
4702 | | - do_irtl_hsw = has_hsw_msrs(family, model); |
---|
| 5269 | + do_irtl_hsw = has_c8910_msrs(family, model); |
---|
4703 | 5270 | if (has_skl_msrs(family, model)) { |
---|
4704 | 5271 | BIC_PRESENT(BIC_Totl_c0); |
---|
4705 | 5272 | BIC_PRESENT(BIC_Any_c0); |
---|
.. | .. |
---|
4708 | 5275 | } |
---|
4709 | 5276 | do_slm_cstates = is_slm(family, model); |
---|
4710 | 5277 | do_knl_cstates = is_knl(family, model); |
---|
4711 | | - do_cnl_cstates = is_cnl(family, model); |
---|
| 5278 | + |
---|
| 5279 | + if (do_slm_cstates || do_knl_cstates || is_cnl(family, model) || |
---|
| 5280 | + is_ehl(family, model)) |
---|
| 5281 | + BIC_NOT_PRESENT(BIC_CPU_c3); |
---|
4712 | 5282 | |
---|
4713 | 5283 | if (!quiet) |
---|
4714 | 5284 | decode_misc_pwr_mgmt_msr(); |
---|
.. | .. |
---|
4724 | 5294 | dump_cstate_pstate_config_info(family, model); |
---|
4725 | 5295 | |
---|
4726 | 5296 | if (!quiet) |
---|
| 5297 | + print_dev_latency(); |
---|
| 5298 | + if (!quiet) |
---|
4727 | 5299 | dump_sysfs_cstate_config(); |
---|
4728 | 5300 | if (!quiet) |
---|
4729 | 5301 | dump_sysfs_pstate_config(); |
---|
.. | .. |
---|
4736 | 5308 | |
---|
4737 | 5309 | if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK)) |
---|
4738 | 5310 | BIC_PRESENT(BIC_GFXMHz); |
---|
| 5311 | + |
---|
| 5312 | + if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", R_OK)) |
---|
| 5313 | + BIC_PRESENT(BIC_GFXACTMHz); |
---|
4739 | 5314 | |
---|
4740 | 5315 | if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK)) |
---|
4741 | 5316 | BIC_PRESENT(BIC_CPU_LPI); |
---|
.. | .. |
---|
4781 | 5356 | int i; |
---|
4782 | 5357 | int max_core_id = 0; |
---|
4783 | 5358 | int max_package_id = 0; |
---|
| 5359 | + int max_die_id = 0; |
---|
4784 | 5360 | int max_siblings = 0; |
---|
4785 | 5361 | |
---|
4786 | 5362 | /* Initialize num_cpus, max_cpu_num */ |
---|
.. | .. |
---|
4847 | 5423 | if (cpus[i].physical_package_id > max_package_id) |
---|
4848 | 5424 | max_package_id = cpus[i].physical_package_id; |
---|
4849 | 5425 | |
---|
| 5426 | + /* get die information */ |
---|
| 5427 | + cpus[i].die_id = get_die_id(i); |
---|
| 5428 | + if (cpus[i].die_id > max_die_id) |
---|
| 5429 | + max_die_id = cpus[i].die_id; |
---|
| 5430 | + |
---|
4850 | 5431 | /* get numa node information */ |
---|
4851 | 5432 | cpus[i].physical_node_id = get_physical_node_id(&cpus[i]); |
---|
4852 | 5433 | if (cpus[i].physical_node_id > topo.max_node_num) |
---|
.. | .. |
---|
4872 | 5453 | if (!summary_only && topo.cores_per_node > 1) |
---|
4873 | 5454 | BIC_PRESENT(BIC_Core); |
---|
4874 | 5455 | |
---|
| 5456 | + topo.num_die = max_die_id + 1; |
---|
| 5457 | + if (debug > 1) |
---|
| 5458 | + fprintf(outf, "max_die_id %d, sizing for %d die\n", |
---|
| 5459 | + max_die_id, topo.num_die); |
---|
| 5460 | + if (!summary_only && topo.num_die > 1) |
---|
| 5461 | + BIC_PRESENT(BIC_Die); |
---|
| 5462 | + |
---|
4875 | 5463 | topo.num_packages = max_package_id + 1; |
---|
4876 | 5464 | if (debug > 1) |
---|
4877 | 5465 | fprintf(outf, "max_package_id %d, sizing for %d packages\n", |
---|
.. | .. |
---|
4893 | 5481 | return; |
---|
4894 | 5482 | |
---|
4895 | 5483 | for (i = 0; i <= topo.max_cpu_num; ++i) { |
---|
| 5484 | + if (cpu_is_not_present(i)) |
---|
| 5485 | + continue; |
---|
4896 | 5486 | fprintf(outf, |
---|
4897 | | - "cpu %d pkg %d node %d lnode %d core %d thread %d\n", |
---|
4898 | | - i, cpus[i].physical_package_id, |
---|
| 5487 | + "cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n", |
---|
| 5488 | + i, cpus[i].physical_package_id, cpus[i].die_id, |
---|
4899 | 5489 | cpus[i].physical_node_id, |
---|
4900 | 5490 | cpus[i].logical_node_id, |
---|
4901 | 5491 | cpus[i].physical_core_id, |
---|
.. | .. |
---|
5132 | 5722 | } |
---|
5133 | 5723 | |
---|
5134 | 5724 | void print_version() { |
---|
5135 | | - fprintf(outf, "turbostat version 18.07.27" |
---|
| 5725 | + fprintf(outf, "turbostat version 20.09.30" |
---|
5136 | 5726 | " - Len Brown <lenb@kernel.org>\n"); |
---|
5137 | 5727 | } |
---|
5138 | 5728 | |
---|
.. | .. |
---|
5329 | 5919 | input = fopen(path, "r"); |
---|
5330 | 5920 | if (input == NULL) |
---|
5331 | 5921 | continue; |
---|
5332 | | - fgets(name_buf, sizeof(name_buf), input); |
---|
| 5922 | + if (!fgets(name_buf, sizeof(name_buf), input)) |
---|
| 5923 | + err(1, "%s: failed to read file", path); |
---|
5333 | 5924 | |
---|
5334 | 5925 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ |
---|
5335 | 5926 | sp = strchr(name_buf, '-'); |
---|
.. | .. |
---|
5337 | 5928 | sp = strchrnul(name_buf, '\n'); |
---|
5338 | 5929 | *sp = '%'; |
---|
5339 | 5930 | *(sp + 1) = '\0'; |
---|
| 5931 | + |
---|
| 5932 | + remove_underbar(name_buf); |
---|
5340 | 5933 | |
---|
5341 | 5934 | fclose(input); |
---|
5342 | 5935 | |
---|
.. | .. |
---|
5356 | 5949 | input = fopen(path, "r"); |
---|
5357 | 5950 | if (input == NULL) |
---|
5358 | 5951 | continue; |
---|
5359 | | - fgets(name_buf, sizeof(name_buf), input); |
---|
| 5952 | + if (!fgets(name_buf, sizeof(name_buf), input)) |
---|
| 5953 | + err(1, "%s: failed to read file", path); |
---|
5360 | 5954 | /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ |
---|
5361 | 5955 | sp = strchr(name_buf, '-'); |
---|
5362 | 5956 | if (!sp) |
---|
5363 | 5957 | sp = strchrnul(name_buf, '\n'); |
---|
5364 | 5958 | *sp = '\0'; |
---|
5365 | 5959 | fclose(input); |
---|
| 5960 | + |
---|
| 5961 | + remove_underbar(name_buf); |
---|
5366 | 5962 | |
---|
5367 | 5963 | sprintf(path, "cpuidle/state%d/usage", state); |
---|
5368 | 5964 | |
---|
.. | .. |
---|
5608 | 6204 | return 0; |
---|
5609 | 6205 | } |
---|
5610 | 6206 | |
---|
| 6207 | + msr_sum_record(); |
---|
5611 | 6208 | /* |
---|
5612 | 6209 | * if any params left, it must be a command to fork |
---|
5613 | 6210 | */ |
---|