hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/tools/power/x86/turbostat/turbostat.c
....@@ -1,22 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * turbostat -- show CPU frequency and C-state residency
34 * on modern Intel and AMD processors.
45 *
56 * Copyright (c) 2013 Intel Corporation.
67 * 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.
208 */
219
2210 #define _GNU_SOURCE
....@@ -42,15 +30,15 @@
4230 #include <sched.h>
4331 #include <time.h>
4432 #include <cpuid.h>
45
-#include <linux/capability.h>
33
+#include <sys/capability.h>
4634 #include <errno.h>
35
+#include <math.h>
4736
4837 char *proc_stat = "/proc/stat";
4938 FILE *outf;
5039 int *fd_percpu;
5140 struct timeval interval_tv = {5, 0};
5241 struct timespec interval_ts = {5, 0};
53
-struct timespec one_msec = {0, 1000000};
5442 unsigned int num_iterations;
5543 unsigned int debug;
5644 unsigned int quiet;
....@@ -63,7 +51,6 @@
6351 unsigned int do_snb_cstates;
6452 unsigned int do_knl_cstates;
6553 unsigned int do_slm_cstates;
66
-unsigned int do_cnl_cstates;
6754 unsigned int use_c1_residency_msr;
6855 unsigned int has_aperf;
6956 unsigned int has_epb;
....@@ -72,6 +59,7 @@
7259 unsigned int units = 1000000; /* MHz etc */
7360 unsigned int genuine_intel;
7461 unsigned int authentic_amd;
62
+unsigned int hygon_genuine;
7563 unsigned int max_level, max_extended_level;
7664 unsigned int has_invariant_tsc;
7765 unsigned int do_nhm_platform_info;
....@@ -91,6 +79,7 @@
9179 unsigned long long cpuidle_cur_cpu_lpi_us;
9280 unsigned long long cpuidle_cur_sys_lpi_us;
9381 unsigned int gfx_cur_mhz;
82
+unsigned int gfx_act_mhz;
9483 unsigned int tcc_activation_temp;
9584 unsigned int tcc_activation_temp_override;
9685 double rapl_power_units, rapl_time_units;
....@@ -112,6 +101,7 @@
112101 unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
113102 unsigned int has_misc_feature_control;
114103 unsigned int first_counter_read = 1;
104
+int ignore_stdin;
115105
116106 #define RAPL_PKG (1 << 0)
117107 /* 0x610 MSR_PKG_POWER_LIMIT */
....@@ -141,8 +131,20 @@
141131
142132 #define RAPL_CORES_ENERGY_STATUS (1 << 9)
143133 /* 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 */
144141 #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
145142 #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
146148
147149 #define MAX(a, b) ((a) > (b) ? (a) : (b))
148150
....@@ -166,6 +168,7 @@
166168 struct thread_data {
167169 struct timeval tv_begin;
168170 struct timeval tv_end;
171
+ struct timeval tv_delta;
169172 unsigned long long tsc;
170173 unsigned long long aperf;
171174 unsigned long long mperf;
....@@ -187,6 +190,7 @@
187190 unsigned long long c7;
188191 unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */
189192 unsigned int core_temp_c;
193
+ unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */
190194 unsigned int core_id;
191195 unsigned long long counter[MAX_ADDED_COUNTERS];
192196 } *core_even, *core_odd;
....@@ -207,13 +211,14 @@
207211 unsigned long long pkg_both_core_gfxe_c0;
208212 long long gfx_rc6_ms;
209213 unsigned int gfx_mhz;
214
+ unsigned int gfx_act_mhz;
210215 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 */
217222 unsigned int pkg_temp_c;
218223 unsigned long long counter[MAX_ADDED_COUNTERS];
219224 } *package_even, *package_odd;
....@@ -256,6 +261,117 @@
256261 #define SYSFS_PERCPU (1 << 1)
257262 };
258263
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
+}
259375 struct sys_counters {
260376 unsigned int added_thread_counters;
261377 unsigned int added_core_counters;
....@@ -273,6 +389,7 @@
273389
274390 struct cpu_topology {
275391 int physical_package_id;
392
+ int die_id;
276393 int logical_cpu_id;
277394 int physical_node_id;
278395 int logical_node_id; /* 0-based count within the package */
....@@ -283,6 +400,7 @@
283400
284401 struct topo_params {
285402 int num_packages;
403
+ int num_die;
286404 int num_cpus;
287405 int num_cores;
288406 int max_cpu_num;
....@@ -318,9 +436,8 @@
318436 int retval, pkg_no, core_no, thread_no, node_no;
319437
320438 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) {
324441 for (thread_no = 0; thread_no <
325442 topo.threads_per_core; ++thread_no) {
326443 struct thread_data *t;
....@@ -446,6 +563,8 @@
446563 { 0x0, "CPU" },
447564 { 0x0, "APIC" },
448565 { 0x0, "X2APIC" },
566
+ { 0x0, "Die" },
567
+ { 0x0, "GFXAMHz" },
449568 };
450569
451570 #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
....@@ -499,6 +618,8 @@
499618 #define BIC_CPU (1ULL << 47)
500619 #define BIC_APIC (1ULL << 48)
501620 #define BIC_X2APIC (1ULL << 49)
621
+#define BIC_Die (1ULL << 50)
622
+#define BIC_GFXACTMHz (1ULL << 51)
502623
503624 #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
504625
....@@ -506,6 +627,7 @@
506627 unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
507628
508629 #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
630
+#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
509631 #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
510632 #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
511633 #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
....@@ -625,6 +747,8 @@
625747 outp += sprintf(outp, "%sTime_Of_Day_Seconds", (printed++ ? delim : ""));
626748 if (DO_BIC(BIC_Package))
627749 outp += sprintf(outp, "%sPackage", (printed++ ? delim : ""));
750
+ if (DO_BIC(BIC_Die))
751
+ outp += sprintf(outp, "%sDie", (printed++ ? delim : ""));
628752 if (DO_BIC(BIC_Node))
629753 outp += sprintf(outp, "%sNode", (printed++ ? delim : ""));
630754 if (DO_BIC(BIC_Core))
....@@ -671,7 +795,7 @@
671795
672796 if (DO_BIC(BIC_CPU_c1))
673797 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))
675799 outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : ""));
676800 if (DO_BIC(BIC_CPU_c6))
677801 outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : ""));
....@@ -683,6 +807,14 @@
683807
684808 if (DO_BIC(BIC_CoreTmp))
685809 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
+ }
686818
687819 for (mp = sys.cp; mp; mp = mp->next) {
688820 if (mp->format == FORMAT_RAW) {
....@@ -706,6 +838,9 @@
706838
707839 if (DO_BIC(BIC_GFXMHz))
708840 outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : ""));
841
+
842
+ if (DO_BIC(BIC_GFXACTMHz))
843
+ outp += sprintf(outp, "%sGFXAMHz", (printed++ ? delim : ""));
709844
710845 if (DO_BIC(BIC_Totl_c0))
711846 outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : ""));
....@@ -738,7 +873,7 @@
738873 if (do_rapl && !rapl_joules) {
739874 if (DO_BIC(BIC_PkgWatt))
740875 outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : ""));
741
- if (DO_BIC(BIC_CorWatt))
876
+ if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY))
742877 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
743878 if (DO_BIC(BIC_GFXWatt))
744879 outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : ""));
....@@ -751,7 +886,7 @@
751886 } else if (do_rapl && rapl_joules) {
752887 if (DO_BIC(BIC_Pkg_J))
753888 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))
755890 outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
756891 if (DO_BIC(BIC_GFX_J))
757892 outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : ""));
....@@ -812,6 +947,7 @@
812947 outp += sprintf(outp, "c6: %016llX\n", c->c6);
813948 outp += sprintf(outp, "c7: %016llX\n", c->c7);
814949 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
950
+ outp += sprintf(outp, "Joules: %0X\n", c->core_energy);
815951
816952 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
817953 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n",
....@@ -838,16 +974,15 @@
838974 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
839975 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
840976 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
841
- outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
842977 outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi);
843978 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",
849984 p->rapl_pkg_perf_status);
850
- outp += sprintf(outp, "Throttle RAM: %0X\n",
985
+ outp += sprintf(outp, "Throttle RAM: %0llX\n",
851986 p->rapl_dram_perf_status);
852987 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
853988
....@@ -900,13 +1035,15 @@
9001035 if (DO_BIC(BIC_TOD))
9011036 outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
9021037
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;
9041039
9051040 tsc = t->tsc * tsc_tweak;
9061041
9071042 /* topo columns, print blanks on 1st (average) line */
9081043 if (t == &average.threads) {
9091044 if (DO_BIC(BIC_Package))
1045
+ outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
1046
+ if (DO_BIC(BIC_Die))
9101047 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
9111048 if (DO_BIC(BIC_Node))
9121049 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
....@@ -922,6 +1059,12 @@
9221059 if (DO_BIC(BIC_Package)) {
9231060 if (p)
9241061 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);
9251068 else
9261069 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
9271070 }
....@@ -1007,7 +1150,7 @@
10071150 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
10081151 goto done;
10091152
1010
- if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates && !do_cnl_cstates)
1153
+ if (DO_BIC(BIC_CPU_c3))
10111154 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc);
10121155 if (DO_BIC(BIC_CPU_c6))
10131156 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc);
....@@ -1037,6 +1180,13 @@
10371180 }
10381181 }
10391182
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
+
10401190 /* print per-package data only for 1st core in package */
10411191 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
10421192 goto done;
....@@ -1058,6 +1208,10 @@
10581208 /* GFXMHz */
10591209 if (DO_BIC(BIC_GFXMHz))
10601210 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);
10611215
10621216 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
10631217 if (DO_BIC(BIC_Totl_c0))
....@@ -1089,18 +1243,9 @@
10891243 if (DO_BIC(BIC_SYS_LPI))
10901244 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float);
10911245
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
-
11011246 if (DO_BIC(BIC_PkgWatt))
11021247 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))
11041249 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
11051250 if (DO_BIC(BIC_GFXWatt))
11061251 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float);
....@@ -1108,7 +1253,7 @@
11081253 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float);
11091254 if (DO_BIC(BIC_Pkg_J))
11101255 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))
11121257 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units);
11131258 if (DO_BIC(BIC_GFX_J))
11141259 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units);
....@@ -1180,11 +1325,7 @@
11801325 }
11811326
11821327 #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);
11881329
11891330 int
11901331 delta_package(struct pkg_data *new, struct pkg_data *old)
....@@ -1223,13 +1364,14 @@
12231364 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
12241365
12251366 old->gfx_mhz = new->gfx_mhz;
1367
+ old->gfx_act_mhz = new->gfx_act_mhz;
12261368
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;
12331375
12341376 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
12351377 if (mp->format == FORMAT_RAW)
....@@ -1253,12 +1395,22 @@
12531395 old->core_temp_c = new->core_temp_c;
12541396 old->mc6_us = new->mc6_us - old->mc6_us;
12551397
1398
+ DELTA_WRAP32(new->core_energy, old->core_energy);
1399
+
12561400 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
12571401 if (mp->format == FORMAT_RAW)
12581402 old->counter[i] = new->counter[i];
12591403 else
12601404 old->counter[i] = new->counter[i] - old->counter[i];
12611405 }
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);
12621414 }
12631415
12641416 /*
....@@ -1283,6 +1435,7 @@
12831435 * over-write old w/ new so we can print end of interval values
12841436 */
12851437
1438
+ timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta);
12861439 old->tv_begin = new->tv_begin;
12871440 old->tv_end = new->tv_end;
12881441
....@@ -1296,7 +1449,8 @@
12961449
12971450 old->c1 = new->c1 - old->c1;
12981451
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)) {
13001454 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
13011455 old->aperf = new->aperf - old->aperf;
13021456 old->mperf = new->mperf - old->mperf;
....@@ -1378,6 +1532,8 @@
13781532 t->tv_begin.tv_usec = 0;
13791533 t->tv_end.tv_sec = 0;
13801534 t->tv_end.tv_usec = 0;
1535
+ t->tv_delta.tv_sec = 0;
1536
+ t->tv_delta.tv_usec = 0;
13811537
13821538 t->tsc = 0;
13831539 t->aperf = 0;
....@@ -1395,6 +1551,7 @@
13951551 c->c7 = 0;
13961552 c->mc6_us = 0;
13971553 c->core_temp_c = 0;
1554
+ c->core_energy = 0;
13981555
13991556 p->pkg_wtd_core_c0 = 0;
14001557 p->pkg_any_core_c0 = 0;
....@@ -1424,6 +1581,7 @@
14241581
14251582 p->gfx_rc6_ms = 0;
14261583 p->gfx_mhz = 0;
1584
+ p->gfx_act_mhz = 0;
14271585 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
14281586 t->counter[i] = 0;
14291587
....@@ -1477,6 +1635,8 @@
14771635
14781636 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
14791637
1638
+ average.cores.core_energy += c->core_energy;
1639
+
14801640 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
14811641 if (mp->format == FORMAT_RAW)
14821642 continue;
....@@ -1517,6 +1677,7 @@
15171677
15181678 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
15191679 average.packages.gfx_mhz = p->gfx_mhz;
1680
+ average.packages.gfx_act_mhz = p->gfx_act_mhz;
15201681
15211682 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
15221683
....@@ -1543,6 +1704,9 @@
15431704 clear_counters(&average.threads, &average.cores, &average.packages);
15441705
15451706 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;
15461710
15471711 average.threads.tsc /= topo.num_cpus;
15481712 average.threads.aperf /= topo.num_cpus;
....@@ -1685,7 +1849,7 @@
16851849 if (!DO_BIC(BIC_X2APIC))
16861850 return;
16871851
1688
- if (authentic_amd) {
1852
+ if (authentic_amd || hygon_genuine) {
16891853 unsigned int topology_extensions;
16901854
16911855 if (max_extended_level < 0x8000001e)
....@@ -1733,19 +1897,20 @@
17331897 struct msr_counter *mp;
17341898 int i;
17351899
1736
- gettimeofday(&t->tv_begin, (struct timezone *)NULL);
1737
-
17381900 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);
17401902 return -1;
17411903 }
1904
+
1905
+ gettimeofday(&t->tv_begin, (struct timezone *)NULL);
17421906
17431907 if (first_counter_read)
17441908 get_apic_id(t);
17451909 retry:
17461910 t->tsc = rdtsc(); /* we are running on local CPU of interest */
17471911
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)) {
17491914 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
17501915
17511916 /*
....@@ -1822,20 +1987,20 @@
18221987 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
18231988 goto done;
18241989
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)) {
18261991 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
18271992 return -6;
18281993 }
18291994
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) {
18311996 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
18321997 return -7;
1833
- } else if (do_knl_cstates) {
1998
+ } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) {
18341999 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
18352000 return -7;
18362001 }
18372002
1838
- if (DO_BIC(BIC_CPU_c7))
2003
+ if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7))
18392004 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
18402005 return -8;
18412006
....@@ -1847,6 +2012,12 @@
18472012 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
18482013 return -9;
18492014 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;
18502021 }
18512022
18522023 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
....@@ -1909,34 +2080,39 @@
19092080 p->sys_lpi = cpuidle_cur_sys_lpi_us;
19102081
19112082 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))
19132084 return -13;
1914
- p->energy_pkg = msr & 0xFFFFFFFF;
2085
+ p->energy_pkg = msr;
19152086 }
19162087 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))
19182089 return -14;
1919
- p->energy_cores = msr & 0xFFFFFFFF;
2090
+ p->energy_cores = msr;
19202091 }
19212092 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))
19232094 return -15;
1924
- p->energy_dram = msr & 0xFFFFFFFF;
2095
+ p->energy_dram = msr;
19252096 }
19262097 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))
19282099 return -16;
1929
- p->energy_gfx = msr & 0xFFFFFFFF;
2100
+ p->energy_gfx = msr;
19302101 }
19312102 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))
19332104 return -16;
1934
- p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
2105
+ p->rapl_pkg_perf_status = msr;
19352106 }
19362107 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))
19382109 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;
19402116 }
19412117 if (DO_BIC(BIC_PkgTmp)) {
19422118 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
....@@ -1949,6 +2125,9 @@
19492125
19502126 if (DO_BIC(BIC_GFXMHz))
19512127 p->gfx_mhz = gfx_cur_mhz;
2128
+
2129
+ if (DO_BIC(BIC_GFXACTMHz))
2130
+ p->gfx_act_mhz = gfx_act_mhz;
19522131
19532132 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
19542133 if (get_mp(cpu, mp, &p->counter[i]))
....@@ -2110,7 +2289,8 @@
21102289 switch (model) {
21112290 case INTEL_FAM6_ATOM_GOLDMONT:
21122291 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:
21142294 return 1;
21152295 }
21162296 return 0;
....@@ -2460,6 +2640,8 @@
24602640
24612641 /*
24622642 * 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
24632645 */
24642646 int parse_int_file(const char *fmt, ...)
24652647 {
....@@ -2471,7 +2653,9 @@
24712653 va_start(args, fmt);
24722654 vsnprintf(path, sizeof(path), fmt, args);
24732655 va_end(args);
2474
- filep = fopen_or_die(path, "r");
2656
+ filep = fopen(path, "r");
2657
+ if (!filep)
2658
+ return 0;
24752659 if (fscanf(filep, "%d", &value) != 1)
24762660 err(1, "%s: failed to parse number from file", path);
24772661 fclose(filep);
....@@ -2490,6 +2674,11 @@
24902674 int get_physical_package_id(int cpu)
24912675 {
24922676 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);
24932682 }
24942683
24952684 int get_core_id(int cpu)
....@@ -2579,10 +2768,16 @@
25792768
25802769 sprintf(path,
25812770 "/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
+ }
25832777 do {
25842778 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);
25862781 for (shift = 0; shift < BITMASK_SIZE; shift++) {
25872782 if ((map >> shift) & 0x1) {
25882783 so = shift + offset;
....@@ -2691,18 +2886,25 @@
26912886 {
26922887 free_all_buffers();
26932888 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);
26952890 }
26962891
26972892 void set_max_cpu_num(void)
26982893 {
26992894 FILE *filep;
2895
+ int base_cpu;
27002896 unsigned long dummy;
2897
+ char pathname[64];
27012898
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");
27022907 topo.max_cpu_num = 0;
2703
- filep = fopen_or_die(
2704
- "/sys/devices/system/cpu/cpu0/topology/thread_siblings",
2705
- "r");
27062908 while (fscanf(filep, "%lx,", &dummy) == 1)
27072909 topo.max_cpu_num += BITMASK_SIZE;
27082910 fclose(filep);
....@@ -2844,6 +3046,33 @@
28443046 }
28453047
28463048 /*
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
+/*
28473076 * snapshot_cpu_lpi()
28483077 *
28493078 * record snapshot of
....@@ -2857,8 +3086,12 @@
28573086 fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
28583087
28593088 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
+ }
28623095
28633096 fclose(fp);
28643097
....@@ -2877,9 +3110,12 @@
28773110 fp = fopen_or_die(sys_lpi_file, "r");
28783111
28793112 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
+ }
28833119 fclose(fp);
28843120
28853121 return 0;
....@@ -2900,6 +3136,9 @@
29003136
29013137 if (DO_BIC(BIC_GFXMHz))
29023138 snapshot_gfx_mhz();
3139
+
3140
+ if (DO_BIC(BIC_GFXACTMHz))
3141
+ snapshot_gfx_act_mhz();
29033142
29043143 if (DO_BIC(BIC_CPU_LPI))
29053144 snapshot_cpu_lpi_us();
....@@ -2925,8 +3164,6 @@
29253164 fprintf(stderr, "SIGUSR1\n");
29263165 break;
29273166 }
2928
- /* make sure this manually-invoked interval is at least 1ms long */
2929
- nanosleep(&one_msec, NULL);
29303167 }
29313168
29323169 void setup_signal_handler(void)
....@@ -2945,32 +3182,147 @@
29453182
29463183 void do_sleep(void)
29473184 {
2948
- struct timeval select_timeout;
3185
+ struct timeval tout;
3186
+ struct timespec rest;
29493187 fd_set readfds;
29503188 int retval;
29513189
29523190 FD_ZERO(&readfds);
29533191 FD_SET(0, &readfds);
29543192
2955
- if (!isatty(fileno(stdin))) {
3193
+ if (ignore_stdin) {
29563194 nanosleep(&interval_ts, NULL);
29573195 return;
29583196 }
29593197
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);
29623200
29633201 if (retval == 1) {
29643202 switch (getc(stdin)) {
29653203 case 'q':
29663204 exit_requested = 1;
29673205 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);
29683216 }
2969
- /* make sure this manually-invoked interval is at least 1ms long */
2970
- nanosleep(&one_msec, NULL);
29713217 }
29723218 }
29733219
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
+}
29743326
29753327 void turbostat_loop()
29763328 {
....@@ -2989,7 +3341,7 @@
29893341 if (retval < -1) {
29903342 exit(retval);
29913343 } else if (retval == -1) {
2992
- if (restarted > 1) {
3344
+ if (restarted > 10) {
29933345 exit(retval);
29943346 }
29953347 re_initialize();
....@@ -3064,27 +3416,41 @@
30643416 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
30653417 }
30663418
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)
30683425 {
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
+{
30743449 int do_exit = 0;
30753450 char pathname[32];
30763451
30773452 /* 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();
30883454
30893455 /* test file permissions */
30903456 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
....@@ -3136,13 +3502,8 @@
31363502 bclk = discover_bclk(family, model);
31373503
31383504 switch (model) {
3139
- case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
31403505 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 */
31443506 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
3145
- case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
31463507 pkg_cstate_limits = nhm_pkg_cstate_limits;
31473508 break;
31483509 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
....@@ -3152,19 +3513,15 @@
31523513 pkg_cstate_limits = snb_pkg_cstate_limits;
31533514 has_misc_feature_control = 1;
31543515 break;
3155
- case INTEL_FAM6_HASWELL_CORE: /* HSW */
3516
+ case INTEL_FAM6_HASWELL: /* HSW */
3517
+ case INTEL_FAM6_HASWELL_G: /* HSW */
31563518 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 */
31613522 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 */
31683525 pkg_cstate_limits = hsw_pkg_cstate_limits;
31693526 has_misc_feature_control = 1;
31703527 break;
....@@ -3174,7 +3531,7 @@
31743531 break;
31753532 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
31763533 no_MSR_MISC_PWR_MGMT = 1;
3177
- case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */
3534
+ case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
31783535 pkg_cstate_limits = slv_pkg_cstate_limits;
31793536 break;
31803537 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
....@@ -3182,12 +3539,13 @@
31823539 no_MSR_MISC_PWR_MGMT = 1;
31833540 break;
31843541 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
3185
- case INTEL_FAM6_XEON_PHI_KNM:
31863542 pkg_cstate_limits = phi_pkg_cstate_limits;
31873543 break;
31883544 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
31893545 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 */
31913549 pkg_cstate_limits = glm_pkg_cstate_limits;
31923550 break;
31933551 default:
....@@ -3230,7 +3588,7 @@
32303588 return 0;
32313589
32323590 switch (model) {
3233
- case INTEL_FAM6_ATOM_GOLDMONT_X:
3591
+ case INTEL_FAM6_ATOM_GOLDMONT_D:
32343592 return 1;
32353593 }
32363594 return 0;
....@@ -3243,7 +3601,6 @@
32433601
32443602 switch (model) {
32453603 case INTEL_FAM6_BROADWELL_X:
3246
- case INTEL_FAM6_BROADWELL_XEON_D:
32473604 return 1;
32483605 }
32493606 return 0;
....@@ -3260,6 +3617,28 @@
32603617 }
32613618 return 0;
32623619 }
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
+}
32633642
32643643 int has_turbo_ratio_limit(unsigned int family, unsigned int model)
32653644 {
....@@ -3269,9 +3648,7 @@
32693648 switch (model) {
32703649 /* Nehalem compatible, but do not include turbo-ratio limit support */
32713650 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
3272
- case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
32733651 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
3274
- case INTEL_FAM6_XEON_PHI_KNM:
32753652 return 0;
32763653 default:
32773654 return 1;
....@@ -3326,7 +3703,6 @@
33263703
33273704 switch (model) {
33283705 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
3329
- case INTEL_FAM6_XEON_PHI_KNM:
33303706 return 1;
33313707 default:
33323708 return 0;
....@@ -3358,27 +3734,36 @@
33583734
33593735 switch (model) {
33603736 case INTEL_FAM6_IVYBRIDGE: /* IVB */
3361
- case INTEL_FAM6_HASWELL_CORE: /* HSW */
3737
+ case INTEL_FAM6_HASWELL: /* HSW */
33623738 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 */
33673743 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 */
33743746 case INTEL_FAM6_SKYLAKE_X: /* SKX */
33753747
33763748 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
3377
- case INTEL_FAM6_XEON_PHI_KNM:
33783749 return 1;
33793750 default:
33803751 return 0;
33813752 }
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;
33823767 }
33833768
33843769 static void
....@@ -3410,6 +3795,23 @@
34103795 dump_nhm_cst_cfg();
34113796 }
34123797
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
+}
34133815 static void
34143816 dump_sysfs_cstate_config(void)
34153817 {
....@@ -3420,8 +3822,14 @@
34203822 int state;
34213823 char *sp;
34223824
3423
- if (!DO_BIC(BIC_sysfs))
3825
+ if (access("/sys/devices/system/cpu/cpuidle", R_OK)) {
3826
+ fprintf(outf, "cpuidle not loaded\n");
34243827 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");
34253833
34263834 for (state = 0; state < 10; ++state) {
34273835
....@@ -3430,22 +3838,25 @@
34303838 input = fopen(path, "r");
34313839 if (input == NULL)
34323840 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);
34343843
34353844 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
34363845 sp = strchr(name_buf, '-');
34373846 if (!sp)
34383847 sp = strchrnul(name_buf, '\n');
34393848 *sp = '\0';
3440
-
34413849 fclose(input);
3850
+
3851
+ remove_underbar(name_buf);
34423852
34433853 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
34443854 base_cpu, state);
34453855 input = fopen(path, "r");
34463856 if (input == NULL)
34473857 continue;
3448
- fgets(desc, sizeof(desc), input);
3858
+ if (!fgets(desc, sizeof(desc), input))
3859
+ err(1, "%s: failed to read file", path);
34493860
34503861 fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
34513862 fclose(input);
....@@ -3464,20 +3875,22 @@
34643875 base_cpu);
34653876 input = fopen(path, "r");
34663877 if (input == NULL) {
3467
- fprintf(stderr, "NSFOD %s\n", path);
3878
+ fprintf(outf, "NSFOD %s\n", path);
34683879 return;
34693880 }
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);
34713883 fclose(input);
34723884
34733885 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
34743886 base_cpu);
34753887 input = fopen(path, "r");
34763888 if (input == NULL) {
3477
- fprintf(stderr, "NSFOD %s\n", path);
3889
+ fprintf(outf, "NSFOD %s\n", path);
34783890 return;
34793891 }
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);
34813894 fclose(input);
34823895
34833896 fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
....@@ -3486,7 +3899,8 @@
34863899 sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
34873900 input = fopen(path, "r");
34883901 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);
34903904 fprintf(outf, "cpufreq boost: %d\n", turbo);
34913905 fclose(input);
34923906 }
....@@ -3494,7 +3908,8 @@
34943908 sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
34953909 input = fopen(path, "r");
34963910 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);
34983913 fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
34993914 fclose(input);
35003915 }
....@@ -3521,7 +3936,7 @@
35213936 return 0;
35223937
35233938 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);
35253940 return -1;
35263941 }
35273942
....@@ -3565,7 +3980,7 @@
35653980 return 0;
35663981
35673982 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);
35693984 return -1;
35703985 }
35713986
....@@ -3653,7 +4068,7 @@
36534068 return 0;
36544069
36554070 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);
36574072 return -1;
36584073 }
36594074
....@@ -3738,7 +4153,7 @@
37384153 #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
37394154 #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
37404155
3741
-double get_tdp(unsigned int model)
4156
+double get_tdp_intel(unsigned int model)
37424157 {
37434158 unsigned long long msr;
37444159
....@@ -3748,11 +4163,17 @@
37484163
37494164 switch (model) {
37504165 case INTEL_FAM6_ATOM_SILVERMONT:
3751
- case INTEL_FAM6_ATOM_SILVERMONT_X:
4166
+ case INTEL_FAM6_ATOM_SILVERMONT_D:
37524167 return 30.0;
37534168 default:
37544169 return 135.0;
37554170 }
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;
37564177 }
37574178
37584179 /*
....@@ -3767,29 +4188,19 @@
37674188 switch (model) {
37684189 case INTEL_FAM6_HASWELL_X: /* HSX */
37694190 case INTEL_FAM6_BROADWELL_X: /* BDX */
3770
- case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
37714191 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
3772
- case INTEL_FAM6_XEON_PHI_KNM:
4192
+ case INTEL_FAM6_ICELAKE_X: /* ICX */
37734193 return (rapl_dram_energy_units = 15.3 / 1000000);
37744194 default:
37754195 return (rapl_energy_units);
37764196 }
37774197 }
37784198
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)
37864200 {
37874201 unsigned long long msr;
37884202 unsigned int time_unit;
37894203 double tdp;
3790
-
3791
- if (!genuine_intel)
3792
- return;
37934204
37944205 if (family != 6)
37954206 return;
....@@ -3797,11 +4208,11 @@
37974208 switch (model) {
37984209 case INTEL_FAM6_SANDYBRIDGE:
37994210 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 */
38054216 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
38064217 if (rapl_joules) {
38074218 BIC_PRESENT(BIC_Pkg_J);
....@@ -3821,11 +4232,30 @@
38214232 else
38224233 BIC_PRESENT(BIC_PkgWatt);
38234234 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 */
38294259 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;
38304260 BIC_PRESENT(BIC_PKG__);
38314261 BIC_PRESENT(BIC_RAM__);
....@@ -3843,10 +4273,8 @@
38434273 break;
38444274 case INTEL_FAM6_HASWELL_X: /* HSX */
38454275 case INTEL_FAM6_BROADWELL_X: /* BDX */
3846
- case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
38474276 case INTEL_FAM6_SKYLAKE_X: /* SKX */
38484277 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
3849
- case INTEL_FAM6_XEON_PHI_KNM:
38504278 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
38514279 BIC_PRESENT(BIC_PKG__);
38524280 BIC_PRESENT(BIC_RAM__);
....@@ -3874,7 +4302,7 @@
38744302 }
38754303 break;
38764304 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
3877
- case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */
4305
+ case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
38784306 do_rapl = RAPL_PKG | RAPL_CORES;
38794307 if (rapl_joules) {
38804308 BIC_PRESENT(BIC_Pkg_J);
....@@ -3884,7 +4312,7 @@
38844312 BIC_PRESENT(BIC_CorWatt);
38854313 }
38864314 break;
3887
- case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */
4315
+ case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */
38884316 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;
38894317 BIC_PRESENT(BIC_PKG__);
38904318 BIC_PRESENT(BIC_RAM__);
....@@ -3920,13 +4348,63 @@
39204348
39214349 rapl_time_units = 1.0 / (1 << (time_unit));
39224350
3923
- tdp = get_tdp(model);
4351
+ tdp = get_tdp_intel(model);
39244352
39254353 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
39264354 if (!quiet)
39274355 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
4356
+}
39284357
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);
39304408 }
39314409
39324410 void perf_limit_reasons_probe(unsigned int family, unsigned int model)
....@@ -3938,9 +4416,9 @@
39384416 return;
39394417
39404418 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 */
39444422 do_gfx_perf_limit_reasons = 1;
39454423 case INTEL_FAM6_HASWELL_X: /* HSX */
39464424 do_core_perf_limit_reasons = 1;
....@@ -3972,7 +4450,7 @@
39724450 return 0;
39734451
39744452 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);
39764454 return -1;
39774455 }
39784456
....@@ -4032,6 +4510,7 @@
40324510 int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
40334511 {
40344512 unsigned long long msr;
4513
+ const char *msr_name;
40354514 int cpu;
40364515
40374516 if (!do_rapl)
....@@ -4043,14 +4522,21 @@
40434522
40444523 cpu = t->cpu_id;
40454524 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);
40474526 return -1;
40484527 }
40494528
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
+ }
40524538
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,
40544540 rapl_power_units, rapl_energy_units, rapl_time_units);
40554541
40564542 if (do_rapl & RAPL_PKG_POWER_INFO) {
....@@ -4147,32 +4633,30 @@
41474633 switch (model) {
41484634 case INTEL_FAM6_SANDYBRIDGE:
41494635 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 */
41674649 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 */
41694653 return 1;
41704654 }
41714655 return 0;
41724656 }
41734657
41744658 /*
4175
- * HSW adds support for additional MSRs:
4659
+ * HSW ULT added support for C8/C9/C10 MSRs:
41764660 *
41774661 * MSR_PKG_C8_RESIDENCY 0x00000630
41784662 * MSR_PKG_C9_RESIDENCY 0x00000631
....@@ -4183,21 +4667,19 @@
41834667 * MSR_PKGC10_IRTL 0x00000635
41844668 *
41854669 */
4186
-int has_hsw_msrs(unsigned int family, unsigned int model)
4670
+int has_c8910_msrs(unsigned int family, unsigned int model)
41874671 {
41884672 if (!genuine_intel)
41894673 return 0;
41904674
41914675 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 */
41994680 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
42004681 case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
4682
+ case INTEL_FAM6_ATOM_TREMONT: /* EHL */
42014683 return 1;
42024684 }
42034685 return 0;
....@@ -4217,11 +4699,8 @@
42174699 return 0;
42184700
42194701 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 */
42254704 return 1;
42264705 }
42274706 return 0;
....@@ -4233,7 +4712,7 @@
42334712 return 0;
42344713 switch (model) {
42354714 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
4236
- case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */
4715
+ case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
42374716 return 1;
42384717 }
42394718 return 0;
....@@ -4245,7 +4724,6 @@
42454724 return 0;
42464725 switch (model) {
42474726 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
4248
- case INTEL_FAM6_XEON_PHI_KNM:
42494727 return 1;
42504728 }
42514729 return 0;
....@@ -4257,7 +4735,7 @@
42574735 return 0;
42584736
42594737 switch (model) {
4260
- case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */
4738
+ case INTEL_FAM6_CANNONLAKE_L: /* CNL */
42614739 return 1;
42624740 }
42634741
....@@ -4377,10 +4855,10 @@
43774855 {
43784856 unsigned long long msr;
43794857
4380
- if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
4858
+ if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr))
43814859 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
43824860 base_cpu, msr,
4383
- msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
4861
+ msr & FEAT_CTL_LOCKED ? "" : "UN-",
43844862 msr & (1 << 18) ? "SGX" : "");
43854863 }
43864864
....@@ -4459,6 +4937,83 @@
44594937 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
44604938 }
44614939
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
+
44625017 void process_cpuid()
44635018 {
44645019 unsigned int eax, ebx, ecx, edx;
....@@ -4473,6 +5028,8 @@
44735028 genuine_intel = 1;
44745029 else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
44755030 authentic_amd = 1;
5031
+ else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e)
5032
+ hygon_genuine = 1;
44765033
44775034 if (!quiet)
44785035 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
....@@ -4512,6 +5069,8 @@
45125069 edx_flags & (1 << 28) ? "HT" : "-",
45135070 edx_flags & (1 << 29) ? "TM" : "-");
45145071 }
5072
+ if (genuine_intel)
5073
+ model = intel_model_duplicates(model);
45155074
45165075 if (!(edx_flags & (1 << 5)))
45175076 errx(1, "CPUID: no MSR");
....@@ -4602,13 +5161,10 @@
46025161
46035162 if (crystal_hz == 0)
46045163 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 */
46095165 crystal_hz = 24000000; /* 24.0 MHz */
46105166 break;
4611
- case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */
5167
+ case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */
46125168 crystal_hz = 25000000; /* 25.0 MHz */
46135169 break;
46145170 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
....@@ -4676,6 +5232,14 @@
46765232 BIC_PRESENT(BIC_Mod_c6);
46775233 use_c1_residency_msr = 1;
46785234 }
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
+ }
46795243 if (is_dnv(family, model)) {
46805244 BIC_PRESENT(BIC_CPU_c1);
46815245 BIC_NOT_PRESENT(BIC_CPU_c3);
....@@ -4694,12 +5258,15 @@
46945258 BIC_NOT_PRESENT(BIC_CPU_c7);
46955259 BIC_NOT_PRESENT(BIC_Pkgpc7);
46965260 }
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);
47015268 }
4702
- do_irtl_hsw = has_hsw_msrs(family, model);
5269
+ do_irtl_hsw = has_c8910_msrs(family, model);
47035270 if (has_skl_msrs(family, model)) {
47045271 BIC_PRESENT(BIC_Totl_c0);
47055272 BIC_PRESENT(BIC_Any_c0);
....@@ -4708,7 +5275,10 @@
47085275 }
47095276 do_slm_cstates = is_slm(family, model);
47105277 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);
47125282
47135283 if (!quiet)
47145284 decode_misc_pwr_mgmt_msr();
....@@ -4724,6 +5294,8 @@
47245294 dump_cstate_pstate_config_info(family, model);
47255295
47265296 if (!quiet)
5297
+ print_dev_latency();
5298
+ if (!quiet)
47275299 dump_sysfs_cstate_config();
47285300 if (!quiet)
47295301 dump_sysfs_pstate_config();
....@@ -4736,6 +5308,9 @@
47365308
47375309 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
47385310 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);
47395314
47405315 if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK))
47415316 BIC_PRESENT(BIC_CPU_LPI);
....@@ -4781,6 +5356,7 @@
47815356 int i;
47825357 int max_core_id = 0;
47835358 int max_package_id = 0;
5359
+ int max_die_id = 0;
47845360 int max_siblings = 0;
47855361
47865362 /* Initialize num_cpus, max_cpu_num */
....@@ -4847,6 +5423,11 @@
48475423 if (cpus[i].physical_package_id > max_package_id)
48485424 max_package_id = cpus[i].physical_package_id;
48495425
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
+
48505431 /* get numa node information */
48515432 cpus[i].physical_node_id = get_physical_node_id(&cpus[i]);
48525433 if (cpus[i].physical_node_id > topo.max_node_num)
....@@ -4872,6 +5453,13 @@
48725453 if (!summary_only && topo.cores_per_node > 1)
48735454 BIC_PRESENT(BIC_Core);
48745455
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
+
48755463 topo.num_packages = max_package_id + 1;
48765464 if (debug > 1)
48775465 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
....@@ -4893,9 +5481,11 @@
48935481 return;
48945482
48955483 for (i = 0; i <= topo.max_cpu_num; ++i) {
5484
+ if (cpu_is_not_present(i))
5485
+ continue;
48965486 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,
48995489 cpus[i].physical_node_id,
49005490 cpus[i].logical_node_id,
49015491 cpus[i].physical_core_id,
....@@ -5132,7 +5722,7 @@
51325722 }
51335723
51345724 void print_version() {
5135
- fprintf(outf, "turbostat version 18.07.27"
5725
+ fprintf(outf, "turbostat version 20.09.30"
51365726 " - Len Brown <lenb@kernel.org>\n");
51375727 }
51385728
....@@ -5329,7 +5919,8 @@
53295919 input = fopen(path, "r");
53305920 if (input == NULL)
53315921 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);
53335924
53345925 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
53355926 sp = strchr(name_buf, '-');
....@@ -5337,6 +5928,8 @@
53375928 sp = strchrnul(name_buf, '\n');
53385929 *sp = '%';
53395930 *(sp + 1) = '\0';
5931
+
5932
+ remove_underbar(name_buf);
53405933
53415934 fclose(input);
53425935
....@@ -5356,13 +5949,16 @@
53565949 input = fopen(path, "r");
53575950 if (input == NULL)
53585951 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);
53605954 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
53615955 sp = strchr(name_buf, '-');
53625956 if (!sp)
53635957 sp = strchrnul(name_buf, '\n');
53645958 *sp = '\0';
53655959 fclose(input);
5960
+
5961
+ remove_underbar(name_buf);
53665962
53675963 sprintf(path, "cpuidle/state%d/usage", state);
53685964
....@@ -5608,6 +6204,7 @@
56086204 return 0;
56096205 }
56106206
6207
+ msr_sum_record();
56116208 /*
56126209 * if any params left, it must be a command to fork
56136210 */