blob: 10ae4ffe137c76975275c1c15e4ee6c4bff8bf5d [file] [log] [blame]
Len Brown103a8fe2010-10-22 23:53:03 -04001/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
Len Brown144b44b2013-11-09 00:30:16 -05005 * Copyright (c) 2013 Intel Corporation.
Len Brown103a8fe2010-10-22 23:53:03 -04006 * 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 */
21
Len Brown88c32812012-03-29 21:44:40 -040022#define _GNU_SOURCE
Josh Triplettb731f312013-08-20 17:20:12 -070023#include MSRHEADER
Len Brown869ce692016-06-16 23:22:37 -040024#include INTEL_FAMILY_HEADER
Josh Triplett95aebc42013-08-20 17:20:16 -070025#include <stdarg.h>
Len Brown103a8fe2010-10-22 23:53:03 -040026#include <stdio.h>
Josh Triplettb2c95d92013-08-20 17:20:18 -070027#include <err.h>
Len Brown103a8fe2010-10-22 23:53:03 -040028#include <unistd.h>
29#include <sys/types.h>
30#include <sys/wait.h>
31#include <sys/stat.h>
32#include <sys/resource.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <sys/time.h>
36#include <stdlib.h>
Len Brownd8af6f52015-02-10 01:56:38 -050037#include <getopt.h>
Len Brown103a8fe2010-10-22 23:53:03 -040038#include <dirent.h>
39#include <string.h>
40#include <ctype.h>
Len Brown88c32812012-03-29 21:44:40 -040041#include <sched.h>
Len Brown2a0609c2016-02-12 22:44:48 -050042#include <time.h>
Josh Triplett2b928652013-08-20 17:20:14 -070043#include <cpuid.h>
Len Brown98481e72014-08-15 00:36:50 -040044#include <linux/capability.h>
45#include <errno.h>
Len Brown103a8fe2010-10-22 23:53:03 -040046
Len Brown103a8fe2010-10-22 23:53:03 -040047char *proc_stat = "/proc/stat";
Len Brownb7d8c142016-02-13 23:36:17 -050048FILE *outf;
Len Brown36229892016-02-26 20:51:02 -050049int *fd_percpu;
Len Brown2a0609c2016-02-12 22:44:48 -050050struct timespec interval_ts = {5, 0};
Len Brownd8af6f52015-02-10 01:56:38 -050051unsigned int debug;
52unsigned int rapl_joules;
53unsigned int summary_only;
54unsigned int dump_only;
Len Brown103a8fe2010-10-22 23:53:03 -040055unsigned int do_nhm_cstates;
56unsigned int do_snb_cstates;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -070057unsigned int do_knl_cstates;
Len Brownee7e38e2015-02-09 23:39:45 -050058unsigned int do_pc2;
59unsigned int do_pc3;
60unsigned int do_pc6;
61unsigned int do_pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -080062unsigned int do_c8_c9_c10;
Len Brown0b2bb692015-03-26 00:50:30 -040063unsigned int do_skl_residency;
Len Brown144b44b2013-11-09 00:30:16 -050064unsigned int do_slm_cstates;
65unsigned int use_c1_residency_msr;
Len Brown103a8fe2010-10-22 23:53:03 -040066unsigned int has_aperf;
Len Brown889facb2012-11-08 00:48:57 -050067unsigned int has_epb;
Len Brown5a634262016-04-06 17:15:55 -040068unsigned int do_irtl_snb;
69unsigned int do_irtl_hsw;
Len Brownfc04cc62014-02-06 00:55:19 -050070unsigned int units = 1000000; /* MHz etc */
Len Brown103a8fe2010-10-22 23:53:03 -040071unsigned int genuine_intel;
72unsigned int has_invariant_tsc;
Len Brownd7899442015-01-23 00:12:33 -050073unsigned int do_nhm_platform_info;
Len Brown2f32edf2012-09-21 23:45:46 -040074unsigned int extra_msr_offset32;
75unsigned int extra_msr_offset64;
Len Brown8e180f32012-09-22 01:25:08 -040076unsigned int extra_delta_offset32;
77unsigned int extra_delta_offset64;
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +020078unsigned int aperf_mperf_multiplier = 1;
Len Brown562a2d32016-02-26 23:48:05 -050079int do_irq = 1;
Len Brown1ed51012013-02-10 17:19:24 -050080int do_smi;
Len Brown103a8fe2010-10-22 23:53:03 -040081double bclk;
Len Browna2b7b742015-09-26 00:12:38 -040082double base_hz;
Len Brown21ed5572015-10-19 22:37:40 -040083unsigned int has_base_hz;
Len Browna2b7b742015-09-26 00:12:38 -040084double tsc_tweak = 1.0;
Len Brown103a8fe2010-10-22 23:53:03 -040085unsigned int show_pkg;
86unsigned int show_core;
87unsigned int show_cpu;
Len Brownc98d5d92012-06-04 00:56:40 -040088unsigned int show_pkg_only;
89unsigned int show_core_only;
90char *output_buffer, *outp;
Len Brown889facb2012-11-08 00:48:57 -050091unsigned int do_rapl;
92unsigned int do_dts;
93unsigned int do_ptm;
Len Brownfdf676e2016-02-27 01:28:12 -050094unsigned int do_gfx_rc6_ms;
95unsigned long long gfx_cur_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -050096unsigned int do_gfx_mhz;
97unsigned int gfx_cur_mhz;
Len Brown889facb2012-11-08 00:48:57 -050098unsigned int tcc_activation_temp;
99unsigned int tcc_activation_temp_override;
Andrey Semin40ee8e32014-12-05 00:07:00 -0500100double rapl_power_units, rapl_time_units;
101double rapl_dram_energy_units, rapl_energy_units;
Len Brown889facb2012-11-08 00:48:57 -0500102double rapl_joule_counter_range;
Len Brown3a9a9412014-08-15 02:39:52 -0400103unsigned int do_core_perf_limit_reasons;
104unsigned int do_gfx_perf_limit_reasons;
105unsigned int do_ring_perf_limit_reasons;
Len Brown8a5bdf42015-04-01 21:02:57 -0400106unsigned int crystal_hz;
107unsigned long long tsc_hz;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -0400108int base_cpu;
Len Brown21ed5572015-10-19 22:37:40 -0400109double discover_bclk(unsigned int family, unsigned int model);
Len Brown7f5c2582015-12-01 01:36:39 -0500110unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
111 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
112unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
113unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
114unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
115unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
Len Brown889facb2012-11-08 00:48:57 -0500116
Len Browne6f9bb32013-12-03 02:19:19 -0500117#define RAPL_PKG (1 << 0)
118 /* 0x610 MSR_PKG_POWER_LIMIT */
119 /* 0x611 MSR_PKG_ENERGY_STATUS */
120#define RAPL_PKG_PERF_STATUS (1 << 1)
121 /* 0x613 MSR_PKG_PERF_STATUS */
122#define RAPL_PKG_POWER_INFO (1 << 2)
123 /* 0x614 MSR_PKG_POWER_INFO */
124
125#define RAPL_DRAM (1 << 3)
126 /* 0x618 MSR_DRAM_POWER_LIMIT */
127 /* 0x619 MSR_DRAM_ENERGY_STATUS */
Len Browne6f9bb32013-12-03 02:19:19 -0500128#define RAPL_DRAM_PERF_STATUS (1 << 4)
129 /* 0x61b MSR_DRAM_PERF_STATUS */
Len Brown0b2bb692015-03-26 00:50:30 -0400130#define RAPL_DRAM_POWER_INFO (1 << 5)
131 /* 0x61c MSR_DRAM_POWER_INFO */
Len Browne6f9bb32013-12-03 02:19:19 -0500132
Jacob Pan91484942016-06-16 09:48:20 -0700133#define RAPL_CORES_POWER_LIMIT (1 << 6)
Len Browne6f9bb32013-12-03 02:19:19 -0500134 /* 0x638 MSR_PP0_POWER_LIMIT */
Len Brown0b2bb692015-03-26 00:50:30 -0400135#define RAPL_CORE_POLICY (1 << 7)
Len Browne6f9bb32013-12-03 02:19:19 -0500136 /* 0x63a MSR_PP0_POLICY */
137
Len Brown0b2bb692015-03-26 00:50:30 -0400138#define RAPL_GFX (1 << 8)
Len Browne6f9bb32013-12-03 02:19:19 -0500139 /* 0x640 MSR_PP1_POWER_LIMIT */
140 /* 0x641 MSR_PP1_ENERGY_STATUS */
141 /* 0x642 MSR_PP1_POLICY */
Jacob Pan91484942016-06-16 09:48:20 -0700142
143#define RAPL_CORES_ENERGY_STATUS (1 << 9)
144 /* 0x639 MSR_PP0_ENERGY_STATUS */
145#define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
Len Brown889facb2012-11-08 00:48:57 -0500146#define TJMAX_DEFAULT 100
147
148#define MAX(a, b) ((a) > (b) ? (a) : (b))
Len Brown103a8fe2010-10-22 23:53:03 -0400149
Len Brown103a8fe2010-10-22 23:53:03 -0400150int backwards_count;
151char *progname;
Len Brown103a8fe2010-10-22 23:53:03 -0400152
Len Brownc98d5d92012-06-04 00:56:40 -0400153cpu_set_t *cpu_present_set, *cpu_affinity_set;
154size_t cpu_present_setsize, cpu_affinity_setsize;
Len Brown103a8fe2010-10-22 23:53:03 -0400155
Len Brownc98d5d92012-06-04 00:56:40 -0400156struct thread_data {
157 unsigned long long tsc;
158 unsigned long long aperf;
159 unsigned long long mperf;
Len Brown144b44b2013-11-09 00:30:16 -0500160 unsigned long long c1;
Len Brown2f32edf2012-09-21 23:45:46 -0400161 unsigned long long extra_msr64;
Len Brown8e180f32012-09-22 01:25:08 -0400162 unsigned long long extra_delta64;
163 unsigned long long extra_msr32;
164 unsigned long long extra_delta32;
Len Brown562a2d32016-02-26 23:48:05 -0500165 unsigned int irq_count;
Len Brown1ed51012013-02-10 17:19:24 -0500166 unsigned int smi_count;
Len Brownc98d5d92012-06-04 00:56:40 -0400167 unsigned int cpu_id;
168 unsigned int flags;
169#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
170#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
171} *thread_even, *thread_odd;
Len Brown103a8fe2010-10-22 23:53:03 -0400172
Len Brownc98d5d92012-06-04 00:56:40 -0400173struct core_data {
174 unsigned long long c3;
175 unsigned long long c6;
176 unsigned long long c7;
Len Brown889facb2012-11-08 00:48:57 -0500177 unsigned int core_temp_c;
Len Brownc98d5d92012-06-04 00:56:40 -0400178 unsigned int core_id;
179} *core_even, *core_odd;
Len Brown103a8fe2010-10-22 23:53:03 -0400180
Len Brownc98d5d92012-06-04 00:56:40 -0400181struct pkg_data {
182 unsigned long long pc2;
183 unsigned long long pc3;
184 unsigned long long pc6;
185 unsigned long long pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800186 unsigned long long pc8;
187 unsigned long long pc9;
188 unsigned long long pc10;
Len Brown0b2bb692015-03-26 00:50:30 -0400189 unsigned long long pkg_wtd_core_c0;
190 unsigned long long pkg_any_core_c0;
191 unsigned long long pkg_any_gfxe_c0;
192 unsigned long long pkg_both_core_gfxe_c0;
Len Brown9185e982016-04-06 17:16:00 -0400193 long long gfx_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -0500194 unsigned int gfx_mhz;
Len Brownc98d5d92012-06-04 00:56:40 -0400195 unsigned int package_id;
Len Brown889facb2012-11-08 00:48:57 -0500196 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
197 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
198 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
199 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
200 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
201 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
202 unsigned int pkg_temp_c;
203
Len Brownc98d5d92012-06-04 00:56:40 -0400204} *package_even, *package_odd;
205
206#define ODD_COUNTERS thread_odd, core_odd, package_odd
207#define EVEN_COUNTERS thread_even, core_even, package_even
208
209#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \
210 (thread_base + (pkg_no) * topo.num_cores_per_pkg * \
211 topo.num_threads_per_core + \
212 (core_no) * topo.num_threads_per_core + (thread_no))
213#define GET_CORE(core_base, core_no, pkg_no) \
214 (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no))
215#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
216
217struct system_summary {
218 struct thread_data threads;
219 struct core_data cores;
220 struct pkg_data packages;
221} sum, average;
222
223
224struct topo_params {
225 int num_packages;
226 int num_cpus;
227 int num_cores;
228 int max_cpu_num;
229 int num_cores_per_pkg;
230 int num_threads_per_core;
231} topo;
232
233struct timeval tv_even, tv_odd, tv_delta;
234
Len Brown562a2d32016-02-26 23:48:05 -0500235int *irq_column_2_cpu; /* /proc/interrupts column numbers */
236int *irqs_per_cpu; /* indexed by cpu_num */
237
Len Brownc98d5d92012-06-04 00:56:40 -0400238void setup_all_buffers(void);
239
240int cpu_is_not_present(int cpu)
Len Brownd15cf7c2012-06-03 23:24:00 -0400241{
Len Brownc98d5d92012-06-04 00:56:40 -0400242 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brownd15cf7c2012-06-03 23:24:00 -0400243}
Len Brown88c32812012-03-29 21:44:40 -0400244/*
Len Brownc98d5d92012-06-04 00:56:40 -0400245 * run func(thread, core, package) in topology order
246 * skip non-present cpus
Len Brown88c32812012-03-29 21:44:40 -0400247 */
Len Brownd15cf7c2012-06-03 23:24:00 -0400248
Len Brownc98d5d92012-06-04 00:56:40 -0400249int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
250 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
Len Brown88c32812012-03-29 21:44:40 -0400251{
Len Brownc98d5d92012-06-04 00:56:40 -0400252 int retval, pkg_no, core_no, thread_no;
253
254 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
255 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
256 for (thread_no = 0; thread_no <
257 topo.num_threads_per_core; ++thread_no) {
258 struct thread_data *t;
259 struct core_data *c;
260 struct pkg_data *p;
261
262 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
263
264 if (cpu_is_not_present(t->cpu_id))
265 continue;
266
267 c = GET_CORE(core_base, core_no, pkg_no);
268 p = GET_PKG(pkg_base, pkg_no);
269
270 retval = func(t, c, p);
271 if (retval)
272 return retval;
273 }
274 }
275 }
276 return 0;
Len Brown88c32812012-03-29 21:44:40 -0400277}
278
279int cpu_migrate(int cpu)
280{
Len Brownc98d5d92012-06-04 00:56:40 -0400281 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
282 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
283 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
Len Brown88c32812012-03-29 21:44:40 -0400284 return -1;
285 else
286 return 0;
287}
Len Brown36229892016-02-26 20:51:02 -0500288int get_msr_fd(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -0400289{
Len Brown103a8fe2010-10-22 23:53:03 -0400290 char pathname[32];
291 int fd;
292
Len Brown36229892016-02-26 20:51:02 -0500293 fd = fd_percpu[cpu];
294
295 if (fd)
296 return fd;
297
Len Brown103a8fe2010-10-22 23:53:03 -0400298 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
299 fd = open(pathname, O_RDONLY);
Len Brown15aaa342012-03-29 22:19:58 -0400300 if (fd < 0)
Len Brown98481e72014-08-15 00:36:50 -0400301 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
Len Brown103a8fe2010-10-22 23:53:03 -0400302
Len Brown36229892016-02-26 20:51:02 -0500303 fd_percpu[cpu] = fd;
304
305 return fd;
306}
307
308int get_msr(int cpu, off_t offset, unsigned long long *msr)
309{
310 ssize_t retval;
311
312 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
Len Brown15aaa342012-03-29 22:19:58 -0400313
Len Brown98481e72014-08-15 00:36:50 -0400314 if (retval != sizeof *msr)
Len Brown36229892016-02-26 20:51:02 -0500315 err(-1, "msr %d offset 0x%llx read failed", cpu, (unsigned long long)offset);
Len Brown15aaa342012-03-29 22:19:58 -0400316
317 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400318}
319
Len Brownfc04cc62014-02-06 00:55:19 -0500320/*
321 * Example Format w/ field column widths:
322 *
Len Brown27d47352016-02-27 00:37:54 -0500323 * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz IRQ SMI Busy% CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp GFXMHz Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
Len Brown562a2d32016-02-26 23:48:05 -0500324 * 12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678
Len Brownfc04cc62014-02-06 00:55:19 -0500325 */
326
Len Browna829eb42011-02-10 23:36:34 -0500327void print_header(void)
Len Brown103a8fe2010-10-22 23:53:03 -0400328{
329 if (show_pkg)
Len Brown3d109de2016-04-22 23:24:27 -0400330 outp += sprintf(outp, "\tPackage");
Len Brown103a8fe2010-10-22 23:53:03 -0400331 if (show_core)
Len Brown3d109de2016-04-22 23:24:27 -0400332 outp += sprintf(outp, "\tCore");
Len Brown103a8fe2010-10-22 23:53:03 -0400333 if (show_cpu)
Len Brown3d109de2016-04-22 23:24:27 -0400334 outp += sprintf(outp, "\tCPU");
Len Brown103a8fe2010-10-22 23:53:03 -0400335 if (has_aperf)
Len Brown3d109de2016-04-22 23:24:27 -0400336 outp += sprintf(outp, "\tAvg_MHz");
Len Brownd7899442015-01-23 00:12:33 -0500337 if (has_aperf)
Len Brown3d109de2016-04-22 23:24:27 -0400338 outp += sprintf(outp, "\tBusy%%");
Len Brownfc04cc62014-02-06 00:55:19 -0500339 if (has_aperf)
Len Brown3d109de2016-04-22 23:24:27 -0400340 outp += sprintf(outp, "\tBzy_MHz");
341 outp += sprintf(outp, "\tTSC_MHz");
Len Brown1cc21f72015-02-23 00:34:57 -0500342
Len Brown8e180f32012-09-22 01:25:08 -0400343 if (extra_delta_offset32)
Len Brown3d109de2016-04-22 23:24:27 -0400344 outp += sprintf(outp, "\tcount 0x%03X", extra_delta_offset32);
Len Brown8e180f32012-09-22 01:25:08 -0400345 if (extra_delta_offset64)
Len Brown3d109de2016-04-22 23:24:27 -0400346 outp += sprintf(outp, "\tCOUNT 0x%03X", extra_delta_offset64);
Len Brown2f32edf2012-09-21 23:45:46 -0400347 if (extra_msr_offset32)
Len Brown3d109de2016-04-22 23:24:27 -0400348 outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset32);
Len Brown2f32edf2012-09-21 23:45:46 -0400349 if (extra_msr_offset64)
Len Brown3d109de2016-04-22 23:24:27 -0400350 outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset64);
Len Brown1cc21f72015-02-23 00:34:57 -0500351
352 if (!debug)
353 goto done;
354
Len Brown562a2d32016-02-26 23:48:05 -0500355 if (do_irq)
Len Brown3d109de2016-04-22 23:24:27 -0400356 outp += sprintf(outp, "\tIRQ");
Len Brown1cc21f72015-02-23 00:34:57 -0500357 if (do_smi)
Len Brown3d109de2016-04-22 23:24:27 -0400358 outp += sprintf(outp, "\tSMI");
Len Brown1cc21f72015-02-23 00:34:57 -0500359
Len Brown103a8fe2010-10-22 23:53:03 -0400360 if (do_nhm_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400361 outp += sprintf(outp, "\tCPU%%c1");
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -0700362 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400363 outp += sprintf(outp, "\tCPU%%c3");
Len Brown103a8fe2010-10-22 23:53:03 -0400364 if (do_nhm_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400365 outp += sprintf(outp, "\tCPU%%c6");
Len Brown103a8fe2010-10-22 23:53:03 -0400366 if (do_snb_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400367 outp += sprintf(outp, "\tCPU%%c7");
Len Brown889facb2012-11-08 00:48:57 -0500368
369 if (do_dts)
Len Brown3d109de2016-04-22 23:24:27 -0400370 outp += sprintf(outp, "\tCoreTmp");
Len Brown889facb2012-11-08 00:48:57 -0500371 if (do_ptm)
Len Brown3d109de2016-04-22 23:24:27 -0400372 outp += sprintf(outp, "\tPkgTmp");
Len Brown889facb2012-11-08 00:48:57 -0500373
Len Brownfdf676e2016-02-27 01:28:12 -0500374 if (do_gfx_rc6_ms)
Len Brown3d109de2016-04-22 23:24:27 -0400375 outp += sprintf(outp, "\tGFX%%rc6");
Len Brownfdf676e2016-02-27 01:28:12 -0500376
Len Brown27d47352016-02-27 00:37:54 -0500377 if (do_gfx_mhz)
Len Brown3d109de2016-04-22 23:24:27 -0400378 outp += sprintf(outp, "\tGFXMHz");
Len Brown27d47352016-02-27 00:37:54 -0500379
Len Brown0b2bb692015-03-26 00:50:30 -0400380 if (do_skl_residency) {
Len Brown3d109de2016-04-22 23:24:27 -0400381 outp += sprintf(outp, "\tTotl%%C0");
382 outp += sprintf(outp, "\tAny%%C0");
383 outp += sprintf(outp, "\tGFX%%C0");
384 outp += sprintf(outp, "\tCPUGFX%%");
Len Brown0b2bb692015-03-26 00:50:30 -0400385 }
386
Len Brownee7e38e2015-02-09 23:39:45 -0500387 if (do_pc2)
Len Brown3d109de2016-04-22 23:24:27 -0400388 outp += sprintf(outp, "\tPkg%%pc2");
Len Brownee7e38e2015-02-09 23:39:45 -0500389 if (do_pc3)
Len Brown3d109de2016-04-22 23:24:27 -0400390 outp += sprintf(outp, "\tPkg%%pc3");
Len Brownee7e38e2015-02-09 23:39:45 -0500391 if (do_pc6)
Len Brown3d109de2016-04-22 23:24:27 -0400392 outp += sprintf(outp, "\tPkg%%pc6");
Len Brownee7e38e2015-02-09 23:39:45 -0500393 if (do_pc7)
Len Brown3d109de2016-04-22 23:24:27 -0400394 outp += sprintf(outp, "\tPkg%%pc7");
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800395 if (do_c8_c9_c10) {
Len Brown3d109de2016-04-22 23:24:27 -0400396 outp += sprintf(outp, "\tPkg%%pc8");
397 outp += sprintf(outp, "\tPkg%%pc9");
398 outp += sprintf(outp, "\tPk%%pc10");
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800399 }
Len Brown103a8fe2010-10-22 23:53:03 -0400400
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800401 if (do_rapl && !rapl_joules) {
402 if (do_rapl & RAPL_PKG)
Len Brown3d109de2016-04-22 23:24:27 -0400403 outp += sprintf(outp, "\tPkgWatt");
Jacob Pan91484942016-06-16 09:48:20 -0700404 if (do_rapl & RAPL_CORES_ENERGY_STATUS)
Len Brown3d109de2016-04-22 23:24:27 -0400405 outp += sprintf(outp, "\tCorWatt");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800406 if (do_rapl & RAPL_GFX)
Len Brown3d109de2016-04-22 23:24:27 -0400407 outp += sprintf(outp, "\tGFXWatt");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800408 if (do_rapl & RAPL_DRAM)
Len Brown3d109de2016-04-22 23:24:27 -0400409 outp += sprintf(outp, "\tRAMWatt");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800410 if (do_rapl & RAPL_PKG_PERF_STATUS)
Len Brown3d109de2016-04-22 23:24:27 -0400411 outp += sprintf(outp, "\tPKG_%%");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800412 if (do_rapl & RAPL_DRAM_PERF_STATUS)
Len Brown3d109de2016-04-22 23:24:27 -0400413 outp += sprintf(outp, "\tRAM_%%");
Len Brownd7899442015-01-23 00:12:33 -0500414 } else if (do_rapl && rapl_joules) {
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800415 if (do_rapl & RAPL_PKG)
Len Brown3d109de2016-04-22 23:24:27 -0400416 outp += sprintf(outp, "\tPkg_J");
Jacob Pan91484942016-06-16 09:48:20 -0700417 if (do_rapl & RAPL_CORES_ENERGY_STATUS)
Len Brown3d109de2016-04-22 23:24:27 -0400418 outp += sprintf(outp, "\tCor_J");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800419 if (do_rapl & RAPL_GFX)
Len Brown3d109de2016-04-22 23:24:27 -0400420 outp += sprintf(outp, "\tGFX_J");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800421 if (do_rapl & RAPL_DRAM)
Len Brown3d109de2016-04-22 23:24:27 -0400422 outp += sprintf(outp, "\tRAM_J");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800423 if (do_rapl & RAPL_PKG_PERF_STATUS)
Len Brown3d109de2016-04-22 23:24:27 -0400424 outp += sprintf(outp, "\tPKG_%%");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800425 if (do_rapl & RAPL_DRAM_PERF_STATUS)
Len Brown3d109de2016-04-22 23:24:27 -0400426 outp += sprintf(outp, "\tRAM_%%");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800427 }
Len Brown1cc21f72015-02-23 00:34:57 -0500428 done:
Len Brownc98d5d92012-06-04 00:56:40 -0400429 outp += sprintf(outp, "\n");
Len Brown103a8fe2010-10-22 23:53:03 -0400430}
431
Len Brownc98d5d92012-06-04 00:56:40 -0400432int dump_counters(struct thread_data *t, struct core_data *c,
433 struct pkg_data *p)
Len Brown103a8fe2010-10-22 23:53:03 -0400434{
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200435 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
Len Brown103a8fe2010-10-22 23:53:03 -0400436
Len Brownc98d5d92012-06-04 00:56:40 -0400437 if (t) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200438 outp += sprintf(outp, "CPU: %d flags 0x%x\n",
439 t->cpu_id, t->flags);
440 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
441 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
442 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
443 outp += sprintf(outp, "c1: %016llX\n", t->c1);
444 outp += sprintf(outp, "msr0x%x: %08llX\n",
Len Brown8e180f32012-09-22 01:25:08 -0400445 extra_delta_offset32, t->extra_delta32);
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200446 outp += sprintf(outp, "msr0x%x: %016llX\n",
Len Brown8e180f32012-09-22 01:25:08 -0400447 extra_delta_offset64, t->extra_delta64);
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200448 outp += sprintf(outp, "msr0x%x: %08llX\n",
Len Brown2f32edf2012-09-21 23:45:46 -0400449 extra_msr_offset32, t->extra_msr32);
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200450 outp += sprintf(outp, "msr0x%x: %016llX\n",
Len Brown2f32edf2012-09-21 23:45:46 -0400451 extra_msr_offset64, t->extra_msr64);
Len Brown562a2d32016-02-26 23:48:05 -0500452 if (do_irq)
453 outp += sprintf(outp, "IRQ: %08X\n", t->irq_count);
Len Brown1ed51012013-02-10 17:19:24 -0500454 if (do_smi)
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200455 outp += sprintf(outp, "SMI: %08X\n", t->smi_count);
Len Brownc98d5d92012-06-04 00:56:40 -0400456 }
Len Brown103a8fe2010-10-22 23:53:03 -0400457
Len Brownc98d5d92012-06-04 00:56:40 -0400458 if (c) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200459 outp += sprintf(outp, "core: %d\n", c->core_id);
460 outp += sprintf(outp, "c3: %016llX\n", c->c3);
461 outp += sprintf(outp, "c6: %016llX\n", c->c6);
462 outp += sprintf(outp, "c7: %016llX\n", c->c7);
463 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
Len Brownc98d5d92012-06-04 00:56:40 -0400464 }
465
466 if (p) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200467 outp += sprintf(outp, "package: %d\n", p->package_id);
Len Brown0b2bb692015-03-26 00:50:30 -0400468
469 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
470 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
471 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
472 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
473
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200474 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
Len Brownee7e38e2015-02-09 23:39:45 -0500475 if (do_pc3)
476 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
477 if (do_pc6)
478 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
479 if (do_pc7)
480 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200481 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
482 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
483 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
484 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
485 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores);
486 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx);
487 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram);
488 outp += sprintf(outp, "Throttle PKG: %0X\n",
489 p->rapl_pkg_perf_status);
490 outp += sprintf(outp, "Throttle RAM: %0X\n",
491 p->rapl_dram_perf_status);
492 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
Len Brownc98d5d92012-06-04 00:56:40 -0400493 }
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200494
495 outp += sprintf(outp, "\n");
496
Len Brownc98d5d92012-06-04 00:56:40 -0400497 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400498}
499
Len Browne23da032012-02-06 18:37:16 -0500500/*
501 * column formatting convention & formats
Len Browne23da032012-02-06 18:37:16 -0500502 */
Len Brownc98d5d92012-06-04 00:56:40 -0400503int format_counters(struct thread_data *t, struct core_data *c,
504 struct pkg_data *p)
Len Brown103a8fe2010-10-22 23:53:03 -0400505{
506 double interval_float;
Len Brownfc04cc62014-02-06 00:55:19 -0500507 char *fmt8;
Len Brown103a8fe2010-10-22 23:53:03 -0400508
Len Brownc98d5d92012-06-04 00:56:40 -0400509 /* if showing only 1st thread in core and this isn't one, bail out */
510 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
511 return 0;
512
513 /* if showing only 1st thread in pkg and this isn't one, bail out */
514 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
515 return 0;
516
Len Brown103a8fe2010-10-22 23:53:03 -0400517 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
518
Len Brownc98d5d92012-06-04 00:56:40 -0400519 /* topo columns, print blanks on 1st (average) line */
520 if (t == &average.threads) {
Len Brown103a8fe2010-10-22 23:53:03 -0400521 if (show_pkg)
Len Brown3d109de2016-04-22 23:24:27 -0400522 outp += sprintf(outp, "\t-");
Len Brown103a8fe2010-10-22 23:53:03 -0400523 if (show_core)
Len Brown3d109de2016-04-22 23:24:27 -0400524 outp += sprintf(outp, "\t-");
Len Brown103a8fe2010-10-22 23:53:03 -0400525 if (show_cpu)
Len Brown3d109de2016-04-22 23:24:27 -0400526 outp += sprintf(outp, "\t-");
Len Brown103a8fe2010-10-22 23:53:03 -0400527 } else {
Len Brownc98d5d92012-06-04 00:56:40 -0400528 if (show_pkg) {
529 if (p)
Len Brown3d109de2016-04-22 23:24:27 -0400530 outp += sprintf(outp, "\t%d", p->package_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400531 else
Len Brown3d109de2016-04-22 23:24:27 -0400532 outp += sprintf(outp, "\t-");
Len Brownc98d5d92012-06-04 00:56:40 -0400533 }
Len Brownc98d5d92012-06-04 00:56:40 -0400534 if (show_core) {
535 if (c)
Len Brown3d109de2016-04-22 23:24:27 -0400536 outp += sprintf(outp, "\t%d", c->core_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400537 else
Len Brown3d109de2016-04-22 23:24:27 -0400538 outp += sprintf(outp, "\t-");
Len Brownc98d5d92012-06-04 00:56:40 -0400539 }
Len Brown103a8fe2010-10-22 23:53:03 -0400540 if (show_cpu)
Len Brown3d109de2016-04-22 23:24:27 -0400541 outp += sprintf(outp, "\t%d", t->cpu_id);
Len Brown103a8fe2010-10-22 23:53:03 -0400542 }
Len Brownfc04cc62014-02-06 00:55:19 -0500543
Len Brownd7899442015-01-23 00:12:33 -0500544 /* Avg_MHz */
Len Brownfc04cc62014-02-06 00:55:19 -0500545 if (has_aperf)
Len Brown3d109de2016-04-22 23:24:27 -0400546 outp += sprintf(outp, "\t%.0f",
Len Brownfc04cc62014-02-06 00:55:19 -0500547 1.0 / units * t->aperf / interval_float);
548
Len Brown75d2e442016-02-13 23:41:53 -0500549 /* Busy% */
Len Brownba3dec92016-04-22 20:31:46 -0400550 if (has_aperf)
Len Brown3d109de2016-04-22 23:24:27 -0400551 outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/t->tsc/tsc_tweak);
Len Brown103a8fe2010-10-22 23:53:03 -0400552
Len Brownd7899442015-01-23 00:12:33 -0500553 /* Bzy_MHz */
Len Brown21ed5572015-10-19 22:37:40 -0400554 if (has_aperf) {
555 if (has_base_hz)
Len Brown3d109de2016-04-22 23:24:27 -0400556 outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf);
Len Brown21ed5572015-10-19 22:37:40 -0400557 else
Len Brown3d109de2016-04-22 23:24:27 -0400558 outp += sprintf(outp, "\t%.0f",
Len Brown21ed5572015-10-19 22:37:40 -0400559 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float);
560 }
Len Brown103a8fe2010-10-22 23:53:03 -0400561
Len Brownd7899442015-01-23 00:12:33 -0500562 /* TSC_MHz */
Len Brown3d109de2016-04-22 23:24:27 -0400563 outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float);
Len Brown103a8fe2010-10-22 23:53:03 -0400564
Len Brown8e180f32012-09-22 01:25:08 -0400565 /* delta */
566 if (extra_delta_offset32)
Len Brown3d109de2016-04-22 23:24:27 -0400567 outp += sprintf(outp, "\t%11llu", t->extra_delta32);
Len Brown8e180f32012-09-22 01:25:08 -0400568
569 /* DELTA */
570 if (extra_delta_offset64)
Len Brown3d109de2016-04-22 23:24:27 -0400571 outp += sprintf(outp, "\t%11llu", t->extra_delta64);
Len Brown2f32edf2012-09-21 23:45:46 -0400572 /* msr */
573 if (extra_msr_offset32)
Len Brown3d109de2016-04-22 23:24:27 -0400574 outp += sprintf(outp, "\t0x%08llx", t->extra_msr32);
Len Brown2f32edf2012-09-21 23:45:46 -0400575
Len Brown130ff302012-09-21 22:56:06 -0400576 /* MSR */
Len Brown2f32edf2012-09-21 23:45:46 -0400577 if (extra_msr_offset64)
Len Brown3d109de2016-04-22 23:24:27 -0400578 outp += sprintf(outp, "\t0x%016llx", t->extra_msr64);
Len Brown130ff302012-09-21 22:56:06 -0400579
Len Brown1cc21f72015-02-23 00:34:57 -0500580 if (!debug)
581 goto done;
582
Len Brown562a2d32016-02-26 23:48:05 -0500583 /* IRQ */
584 if (do_irq)
Len Brown3d109de2016-04-22 23:24:27 -0400585 outp += sprintf(outp, "\t%d", t->irq_count);
Len Brown562a2d32016-02-26 23:48:05 -0500586
Len Brown1cc21f72015-02-23 00:34:57 -0500587 /* SMI */
588 if (do_smi)
Len Brown3d109de2016-04-22 23:24:27 -0400589 outp += sprintf(outp, "\t%d", t->smi_count);
Len Brown1cc21f72015-02-23 00:34:57 -0500590
Len Brownba3dec92016-04-22 20:31:46 -0400591 if (do_nhm_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400592 outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/t->tsc);
Len Brownc98d5d92012-06-04 00:56:40 -0400593
594 /* print per-core data only for 1st thread in core */
595 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
596 goto done;
597
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -0700598 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400599 outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/t->tsc);
Len Brown103a8fe2010-10-22 23:53:03 -0400600 if (do_nhm_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400601 outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/t->tsc);
Len Brown103a8fe2010-10-22 23:53:03 -0400602 if (do_snb_cstates)
Len Brown3d109de2016-04-22 23:24:27 -0400603 outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/t->tsc);
Len Brownc98d5d92012-06-04 00:56:40 -0400604
Len Brown889facb2012-11-08 00:48:57 -0500605 if (do_dts)
Len Brown3d109de2016-04-22 23:24:27 -0400606 outp += sprintf(outp, "\t%d", c->core_temp_c);
Len Brown889facb2012-11-08 00:48:57 -0500607
Len Brownc98d5d92012-06-04 00:56:40 -0400608 /* print per-package data only for 1st core in package */
609 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
610 goto done;
611
Len Brown0b2bb692015-03-26 00:50:30 -0400612 /* PkgTmp */
Len Brown889facb2012-11-08 00:48:57 -0500613 if (do_ptm)
Len Brown3d109de2016-04-22 23:24:27 -0400614 outp += sprintf(outp, "\t%d", p->pkg_temp_c);
Len Brown889facb2012-11-08 00:48:57 -0500615
Len Brownfdf676e2016-02-27 01:28:12 -0500616 /* GFXrc6 */
Len Brown9185e982016-04-06 17:16:00 -0400617 if (do_gfx_rc6_ms) {
Len Brownba3dec92016-04-22 20:31:46 -0400618 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
Len Brown3d109de2016-04-22 23:24:27 -0400619 outp += sprintf(outp, "\t**.**");
Len Brown9185e982016-04-06 17:16:00 -0400620 } else {
Len Brown3d109de2016-04-22 23:24:27 -0400621 outp += sprintf(outp, "\t%.2f",
Len Brown9185e982016-04-06 17:16:00 -0400622 p->gfx_rc6_ms / 10.0 / interval_float);
623 }
624 }
Len Brownfdf676e2016-02-27 01:28:12 -0500625
Len Brown27d47352016-02-27 00:37:54 -0500626 /* GFXMHz */
627 if (do_gfx_mhz)
Len Brown3d109de2016-04-22 23:24:27 -0400628 outp += sprintf(outp, "\t%d", p->gfx_mhz);
Len Brown27d47352016-02-27 00:37:54 -0500629
Len Brown0b2bb692015-03-26 00:50:30 -0400630 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
631 if (do_skl_residency) {
Len Brown3d109de2016-04-22 23:24:27 -0400632 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc);
633 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/t->tsc);
634 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/t->tsc);
635 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/t->tsc);
Len Brown0b2bb692015-03-26 00:50:30 -0400636 }
637
Len Brownee7e38e2015-02-09 23:39:45 -0500638 if (do_pc2)
Len Brown3d109de2016-04-22 23:24:27 -0400639 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/t->tsc);
Len Brownee7e38e2015-02-09 23:39:45 -0500640 if (do_pc3)
Len Brown3d109de2016-04-22 23:24:27 -0400641 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/t->tsc);
Len Brownee7e38e2015-02-09 23:39:45 -0500642 if (do_pc6)
Len Brown3d109de2016-04-22 23:24:27 -0400643 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/t->tsc);
Len Brownee7e38e2015-02-09 23:39:45 -0500644 if (do_pc7)
Len Brown3d109de2016-04-22 23:24:27 -0400645 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/t->tsc);
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800646 if (do_c8_c9_c10) {
Len Brown3d109de2016-04-22 23:24:27 -0400647 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/t->tsc);
648 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/t->tsc);
649 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/t->tsc);
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800650 }
Len Brown889facb2012-11-08 00:48:57 -0500651
652 /*
653 * If measurement interval exceeds minimum RAPL Joule Counter range,
654 * indicate that results are suspect by printing "**" in fraction place.
655 */
Len Brownfc04cc62014-02-06 00:55:19 -0500656 if (interval_float < rapl_joule_counter_range)
Len Brown3d109de2016-04-22 23:24:27 -0400657 fmt8 = "\t%.2f";
Len Brownfc04cc62014-02-06 00:55:19 -0500658 else
Len Browne975db52016-04-06 23:56:02 -0400659 fmt8 = "%6.0f**";
Len Brown889facb2012-11-08 00:48:57 -0500660
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800661 if (do_rapl && !rapl_joules) {
662 if (do_rapl & RAPL_PKG)
Len Brownfc04cc62014-02-06 00:55:19 -0500663 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float);
Jacob Pan91484942016-06-16 09:48:20 -0700664 if (do_rapl & RAPL_CORES_ENERGY_STATUS)
Len Brownfc04cc62014-02-06 00:55:19 -0500665 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800666 if (do_rapl & RAPL_GFX)
Len Brownfc04cc62014-02-06 00:55:19 -0500667 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800668 if (do_rapl & RAPL_DRAM)
Andrey Semin40ee8e32014-12-05 00:07:00 -0500669 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units / interval_float);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800670 if (do_rapl & RAPL_PKG_PERF_STATUS)
Len Brownfc04cc62014-02-06 00:55:19 -0500671 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800672 if (do_rapl & RAPL_DRAM_PERF_STATUS)
Len Brownfc04cc62014-02-06 00:55:19 -0500673 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
Len Brownd7899442015-01-23 00:12:33 -0500674 } else if (do_rapl && rapl_joules) {
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800675 if (do_rapl & RAPL_PKG)
Len Brownfc04cc62014-02-06 00:55:19 -0500676 outp += sprintf(outp, fmt8,
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800677 p->energy_pkg * rapl_energy_units);
678 if (do_rapl & RAPL_CORES)
Len Brownfc04cc62014-02-06 00:55:19 -0500679 outp += sprintf(outp, fmt8,
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800680 p->energy_cores * rapl_energy_units);
681 if (do_rapl & RAPL_GFX)
Len Brownfc04cc62014-02-06 00:55:19 -0500682 outp += sprintf(outp, fmt8,
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800683 p->energy_gfx * rapl_energy_units);
684 if (do_rapl & RAPL_DRAM)
Len Brownfc04cc62014-02-06 00:55:19 -0500685 outp += sprintf(outp, fmt8,
Andrey Semin40ee8e32014-12-05 00:07:00 -0500686 p->energy_dram * rapl_dram_energy_units);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800687 if (do_rapl & RAPL_PKG_PERF_STATUS)
Len Brownfc04cc62014-02-06 00:55:19 -0500688 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800689 if (do_rapl & RAPL_DRAM_PERF_STATUS)
Len Brownfc04cc62014-02-06 00:55:19 -0500690 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800691 }
Len Brownc98d5d92012-06-04 00:56:40 -0400692done:
Len Brownc98d5d92012-06-04 00:56:40 -0400693 outp += sprintf(outp, "\n");
694
695 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400696}
697
Len Brownb7d8c142016-02-13 23:36:17 -0500698void flush_output_stdout(void)
Len Brown103a8fe2010-10-22 23:53:03 -0400699{
Len Brownb7d8c142016-02-13 23:36:17 -0500700 FILE *filep;
701
702 if (outf == stderr)
703 filep = stdout;
704 else
705 filep = outf;
706
707 fputs(output_buffer, filep);
708 fflush(filep);
709
Len Brownc98d5d92012-06-04 00:56:40 -0400710 outp = output_buffer;
711}
Len Brownb7d8c142016-02-13 23:36:17 -0500712void flush_output_stderr(void)
Len Brownc98d5d92012-06-04 00:56:40 -0400713{
Len Brownb7d8c142016-02-13 23:36:17 -0500714 fputs(output_buffer, outf);
715 fflush(outf);
Len Brownc98d5d92012-06-04 00:56:40 -0400716 outp = output_buffer;
717}
718void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
719{
Len Browne23da032012-02-06 18:37:16 -0500720 static int printed;
Len Brown103a8fe2010-10-22 23:53:03 -0400721
Len Browne23da032012-02-06 18:37:16 -0500722 if (!printed || !summary_only)
723 print_header();
Len Brown103a8fe2010-10-22 23:53:03 -0400724
Len Brownc98d5d92012-06-04 00:56:40 -0400725 if (topo.num_cpus > 1)
726 format_counters(&average.threads, &average.cores,
727 &average.packages);
Len Brown103a8fe2010-10-22 23:53:03 -0400728
Len Browne23da032012-02-06 18:37:16 -0500729 printed = 1;
730
731 if (summary_only)
732 return;
733
Len Brownc98d5d92012-06-04 00:56:40 -0400734 for_all_cpus(format_counters, t, c, p);
Len Brown103a8fe2010-10-22 23:53:03 -0400735}
736
Len Brown889facb2012-11-08 00:48:57 -0500737#define DELTA_WRAP32(new, old) \
738 if (new > old) { \
739 old = new - old; \
740 } else { \
741 old = 0x100000000 + new - old; \
742 }
743
Len Brownba3dec92016-04-22 20:31:46 -0400744int
Len Brownc98d5d92012-06-04 00:56:40 -0400745delta_package(struct pkg_data *new, struct pkg_data *old)
Len Brown103a8fe2010-10-22 23:53:03 -0400746{
Len Brown0b2bb692015-03-26 00:50:30 -0400747
748 if (do_skl_residency) {
749 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
750 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
751 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
752 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
753 }
Len Brownc98d5d92012-06-04 00:56:40 -0400754 old->pc2 = new->pc2 - old->pc2;
Len Brownee7e38e2015-02-09 23:39:45 -0500755 if (do_pc3)
756 old->pc3 = new->pc3 - old->pc3;
757 if (do_pc6)
758 old->pc6 = new->pc6 - old->pc6;
759 if (do_pc7)
760 old->pc7 = new->pc7 - old->pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800761 old->pc8 = new->pc8 - old->pc8;
762 old->pc9 = new->pc9 - old->pc9;
763 old->pc10 = new->pc10 - old->pc10;
Len Brown889facb2012-11-08 00:48:57 -0500764 old->pkg_temp_c = new->pkg_temp_c;
765
Len Brown9185e982016-04-06 17:16:00 -0400766 /* flag an error when rc6 counter resets/wraps */
767 if (old->gfx_rc6_ms > new->gfx_rc6_ms)
768 old->gfx_rc6_ms = -1;
769 else
770 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
771
Len Brown27d47352016-02-27 00:37:54 -0500772 old->gfx_mhz = new->gfx_mhz;
773
Len Brown889facb2012-11-08 00:48:57 -0500774 DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
775 DELTA_WRAP32(new->energy_cores, old->energy_cores);
776 DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
777 DELTA_WRAP32(new->energy_dram, old->energy_dram);
778 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
779 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
Len Brownba3dec92016-04-22 20:31:46 -0400780
781 return 0;
Len Brownc98d5d92012-06-04 00:56:40 -0400782}
Len Brown103a8fe2010-10-22 23:53:03 -0400783
Len Brownc98d5d92012-06-04 00:56:40 -0400784void
785delta_core(struct core_data *new, struct core_data *old)
786{
787 old->c3 = new->c3 - old->c3;
788 old->c6 = new->c6 - old->c6;
789 old->c7 = new->c7 - old->c7;
Len Brown889facb2012-11-08 00:48:57 -0500790 old->core_temp_c = new->core_temp_c;
Len Brownc98d5d92012-06-04 00:56:40 -0400791}
Len Brown103a8fe2010-10-22 23:53:03 -0400792
Len Brownc3ae3312012-06-13 21:31:46 -0400793/*
794 * old = new - old
795 */
Len Brownba3dec92016-04-22 20:31:46 -0400796int
Len Brownc98d5d92012-06-04 00:56:40 -0400797delta_thread(struct thread_data *new, struct thread_data *old,
798 struct core_data *core_delta)
799{
800 old->tsc = new->tsc - old->tsc;
Len Brown103a8fe2010-10-22 23:53:03 -0400801
Len Brownc98d5d92012-06-04 00:56:40 -0400802 /* check for TSC < 1 Mcycles over interval */
Josh Triplettb2c95d92013-08-20 17:20:18 -0700803 if (old->tsc < (1000 * 1000))
804 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
805 "You can disable all c-states by booting with \"idle=poll\"\n"
806 "or just the deep ones with \"processor.max_cstate=1\"");
Len Brown103a8fe2010-10-22 23:53:03 -0400807
Len Brownc98d5d92012-06-04 00:56:40 -0400808 old->c1 = new->c1 - old->c1;
Len Brown103a8fe2010-10-22 23:53:03 -0400809
Len Browna7296172015-01-23 01:33:58 -0500810 if (has_aperf) {
811 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
812 old->aperf = new->aperf - old->aperf;
813 old->mperf = new->mperf - old->mperf;
814 } else {
Len Brownba3dec92016-04-22 20:31:46 -0400815 return -1;
Len Brownc98d5d92012-06-04 00:56:40 -0400816 }
Len Brownc98d5d92012-06-04 00:56:40 -0400817 }
Len Brown103a8fe2010-10-22 23:53:03 -0400818
Len Brown103a8fe2010-10-22 23:53:03 -0400819
Len Brown144b44b2013-11-09 00:30:16 -0500820 if (use_c1_residency_msr) {
821 /*
822 * Some models have a dedicated C1 residency MSR,
823 * which should be more accurate than the derivation below.
824 */
825 } else {
826 /*
827 * As counter collection is not atomic,
828 * it is possible for mperf's non-halted cycles + idle states
829 * to exceed TSC's all cycles: show c1 = 0% in that case.
830 */
831 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
832 old->c1 = 0;
833 else {
834 /* normal case, derive c1 */
835 old->c1 = old->tsc - old->mperf - core_delta->c3
Len Brownc98d5d92012-06-04 00:56:40 -0400836 - core_delta->c6 - core_delta->c7;
Len Brown144b44b2013-11-09 00:30:16 -0500837 }
Len Brownc98d5d92012-06-04 00:56:40 -0400838 }
Len Brownc3ae3312012-06-13 21:31:46 -0400839
Len Brownc98d5d92012-06-04 00:56:40 -0400840 if (old->mperf == 0) {
Len Brownb7d8c142016-02-13 23:36:17 -0500841 if (debug > 1)
842 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400843 old->mperf = 1; /* divide by 0 protection */
844 }
845
Len Brown8e180f32012-09-22 01:25:08 -0400846 old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
847 old->extra_delta32 &= 0xFFFFFFFF;
848
849 old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
850
Len Brownc98d5d92012-06-04 00:56:40 -0400851 /*
Len Brown8e180f32012-09-22 01:25:08 -0400852 * Extra MSR is just a snapshot, simply copy latest w/o subtracting
Len Brownc98d5d92012-06-04 00:56:40 -0400853 */
Len Brown2f32edf2012-09-21 23:45:46 -0400854 old->extra_msr32 = new->extra_msr32;
855 old->extra_msr64 = new->extra_msr64;
Len Brown1ed51012013-02-10 17:19:24 -0500856
Len Brown562a2d32016-02-26 23:48:05 -0500857 if (do_irq)
858 old->irq_count = new->irq_count - old->irq_count;
859
Len Brown1ed51012013-02-10 17:19:24 -0500860 if (do_smi)
861 old->smi_count = new->smi_count - old->smi_count;
Len Brownba3dec92016-04-22 20:31:46 -0400862
863 return 0;
Len Brownc98d5d92012-06-04 00:56:40 -0400864}
865
866int delta_cpu(struct thread_data *t, struct core_data *c,
867 struct pkg_data *p, struct thread_data *t2,
868 struct core_data *c2, struct pkg_data *p2)
869{
Len Brownba3dec92016-04-22 20:31:46 -0400870 int retval = 0;
871
Len Brownc98d5d92012-06-04 00:56:40 -0400872 /* calculate core delta only for 1st thread in core */
873 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
874 delta_core(c, c2);
875
876 /* always calculate thread delta */
Len Brownba3dec92016-04-22 20:31:46 -0400877 retval = delta_thread(t, t2, c2); /* c2 is core delta */
878 if (retval)
879 return retval;
Len Brownc98d5d92012-06-04 00:56:40 -0400880
881 /* calculate package delta only for 1st core in package */
882 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
Len Brownba3dec92016-04-22 20:31:46 -0400883 retval = delta_package(p, p2);
Len Brownc98d5d92012-06-04 00:56:40 -0400884
Len Brownba3dec92016-04-22 20:31:46 -0400885 return retval;
Len Brownc98d5d92012-06-04 00:56:40 -0400886}
887
888void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
889{
890 t->tsc = 0;
891 t->aperf = 0;
892 t->mperf = 0;
893 t->c1 = 0;
894
Len Brown8e180f32012-09-22 01:25:08 -0400895 t->extra_delta32 = 0;
896 t->extra_delta64 = 0;
897
Len Brown562a2d32016-02-26 23:48:05 -0500898 t->irq_count = 0;
899 t->smi_count = 0;
900
Len Brownc98d5d92012-06-04 00:56:40 -0400901 /* tells format_counters to dump all fields from this set */
902 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
903
904 c->c3 = 0;
905 c->c6 = 0;
906 c->c7 = 0;
Len Brown889facb2012-11-08 00:48:57 -0500907 c->core_temp_c = 0;
Len Brownc98d5d92012-06-04 00:56:40 -0400908
Len Brown0b2bb692015-03-26 00:50:30 -0400909 p->pkg_wtd_core_c0 = 0;
910 p->pkg_any_core_c0 = 0;
911 p->pkg_any_gfxe_c0 = 0;
912 p->pkg_both_core_gfxe_c0 = 0;
913
Len Brownc98d5d92012-06-04 00:56:40 -0400914 p->pc2 = 0;
Len Brownee7e38e2015-02-09 23:39:45 -0500915 if (do_pc3)
916 p->pc3 = 0;
917 if (do_pc6)
918 p->pc6 = 0;
919 if (do_pc7)
920 p->pc7 = 0;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800921 p->pc8 = 0;
922 p->pc9 = 0;
923 p->pc10 = 0;
Len Brown889facb2012-11-08 00:48:57 -0500924
925 p->energy_pkg = 0;
926 p->energy_dram = 0;
927 p->energy_cores = 0;
928 p->energy_gfx = 0;
929 p->rapl_pkg_perf_status = 0;
930 p->rapl_dram_perf_status = 0;
931 p->pkg_temp_c = 0;
Len Brown27d47352016-02-27 00:37:54 -0500932
Len Brownfdf676e2016-02-27 01:28:12 -0500933 p->gfx_rc6_ms = 0;
Len Brown27d47352016-02-27 00:37:54 -0500934 p->gfx_mhz = 0;
Len Brownc98d5d92012-06-04 00:56:40 -0400935}
936int sum_counters(struct thread_data *t, struct core_data *c,
937 struct pkg_data *p)
938{
939 average.threads.tsc += t->tsc;
940 average.threads.aperf += t->aperf;
941 average.threads.mperf += t->mperf;
942 average.threads.c1 += t->c1;
943
Len Brown8e180f32012-09-22 01:25:08 -0400944 average.threads.extra_delta32 += t->extra_delta32;
945 average.threads.extra_delta64 += t->extra_delta64;
946
Len Brown562a2d32016-02-26 23:48:05 -0500947 average.threads.irq_count += t->irq_count;
948 average.threads.smi_count += t->smi_count;
949
Len Brownc98d5d92012-06-04 00:56:40 -0400950 /* sum per-core values only for 1st thread in core */
951 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
952 return 0;
953
954 average.cores.c3 += c->c3;
955 average.cores.c6 += c->c6;
956 average.cores.c7 += c->c7;
957
Len Brown889facb2012-11-08 00:48:57 -0500958 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
959
Len Brownc98d5d92012-06-04 00:56:40 -0400960 /* sum per-pkg values only for 1st core in pkg */
961 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
962 return 0;
963
Len Brown0b2bb692015-03-26 00:50:30 -0400964 if (do_skl_residency) {
965 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
966 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
967 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
968 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
969 }
970
Len Brownc98d5d92012-06-04 00:56:40 -0400971 average.packages.pc2 += p->pc2;
Len Brownee7e38e2015-02-09 23:39:45 -0500972 if (do_pc3)
973 average.packages.pc3 += p->pc3;
974 if (do_pc6)
975 average.packages.pc6 += p->pc6;
976 if (do_pc7)
977 average.packages.pc7 += p->pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800978 average.packages.pc8 += p->pc8;
979 average.packages.pc9 += p->pc9;
980 average.packages.pc10 += p->pc10;
Len Brownc98d5d92012-06-04 00:56:40 -0400981
Len Brown889facb2012-11-08 00:48:57 -0500982 average.packages.energy_pkg += p->energy_pkg;
983 average.packages.energy_dram += p->energy_dram;
984 average.packages.energy_cores += p->energy_cores;
985 average.packages.energy_gfx += p->energy_gfx;
986
Len Brownfdf676e2016-02-27 01:28:12 -0500987 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -0500988 average.packages.gfx_mhz = p->gfx_mhz;
989
Len Brown889facb2012-11-08 00:48:57 -0500990 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
991
992 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
993 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
Len Brownc98d5d92012-06-04 00:56:40 -0400994 return 0;
995}
996/*
997 * sum the counters for all cpus in the system
998 * compute the weighted average
999 */
1000void compute_average(struct thread_data *t, struct core_data *c,
1001 struct pkg_data *p)
1002{
1003 clear_counters(&average.threads, &average.cores, &average.packages);
1004
1005 for_all_cpus(sum_counters, t, c, p);
1006
1007 average.threads.tsc /= topo.num_cpus;
1008 average.threads.aperf /= topo.num_cpus;
1009 average.threads.mperf /= topo.num_cpus;
1010 average.threads.c1 /= topo.num_cpus;
1011
Len Brown8e180f32012-09-22 01:25:08 -04001012 average.threads.extra_delta32 /= topo.num_cpus;
1013 average.threads.extra_delta32 &= 0xFFFFFFFF;
1014
1015 average.threads.extra_delta64 /= topo.num_cpus;
1016
Len Brownc98d5d92012-06-04 00:56:40 -04001017 average.cores.c3 /= topo.num_cores;
1018 average.cores.c6 /= topo.num_cores;
1019 average.cores.c7 /= topo.num_cores;
1020
Len Brown0b2bb692015-03-26 00:50:30 -04001021 if (do_skl_residency) {
1022 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
1023 average.packages.pkg_any_core_c0 /= topo.num_packages;
1024 average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
1025 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
1026 }
1027
Len Brownc98d5d92012-06-04 00:56:40 -04001028 average.packages.pc2 /= topo.num_packages;
Len Brownee7e38e2015-02-09 23:39:45 -05001029 if (do_pc3)
1030 average.packages.pc3 /= topo.num_packages;
1031 if (do_pc6)
1032 average.packages.pc6 /= topo.num_packages;
1033 if (do_pc7)
1034 average.packages.pc7 /= topo.num_packages;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001035
1036 average.packages.pc8 /= topo.num_packages;
1037 average.packages.pc9 /= topo.num_packages;
1038 average.packages.pc10 /= topo.num_packages;
Len Brownc98d5d92012-06-04 00:56:40 -04001039}
1040
1041static unsigned long long rdtsc(void)
1042{
1043 unsigned int low, high;
1044
1045 asm volatile("rdtsc" : "=a" (low), "=d" (high));
1046
1047 return low | ((unsigned long long)high) << 32;
1048}
1049
Len Brownc98d5d92012-06-04 00:56:40 -04001050/*
1051 * get_counters(...)
1052 * migrate to cpu
1053 * acquire and record local counters for that cpu
1054 */
1055int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1056{
1057 int cpu = t->cpu_id;
Len Brown889facb2012-11-08 00:48:57 -05001058 unsigned long long msr;
Len Brown0102b062016-02-27 03:11:29 -05001059 int aperf_mperf_retry_count = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001060
Len Browne52966c2012-11-08 22:38:05 -05001061 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05001062 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brownc98d5d92012-06-04 00:56:40 -04001063 return -1;
Len Browne52966c2012-11-08 22:38:05 -05001064 }
Len Brownc98d5d92012-06-04 00:56:40 -04001065
Len Brown0102b062016-02-27 03:11:29 -05001066retry:
Len Brownc98d5d92012-06-04 00:56:40 -04001067 t->tsc = rdtsc(); /* we are running on local CPU of interest */
1068
1069 if (has_aperf) {
Len Brown0102b062016-02-27 03:11:29 -05001070 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
1071
1072 /*
1073 * The TSC, APERF and MPERF must be read together for
1074 * APERF/MPERF and MPERF/TSC to give accurate results.
1075 *
1076 * Unfortunately, APERF and MPERF are read by
1077 * individual system call, so delays may occur
1078 * between them. If the time to read them
1079 * varies by a large amount, we re-read them.
1080 */
1081
1082 /*
1083 * This initial dummy APERF read has been seen to
1084 * reduce jitter in the subsequent reads.
1085 */
1086
Len Brown9c63a652012-10-31 01:29:52 -04001087 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
Len Brownc98d5d92012-06-04 00:56:40 -04001088 return -3;
Len Brown0102b062016-02-27 03:11:29 -05001089
1090 t->tsc = rdtsc(); /* re-read close to APERF */
1091
1092 tsc_before = t->tsc;
1093
1094 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
1095 return -3;
1096
1097 tsc_between = rdtsc();
1098
Len Brown9c63a652012-10-31 01:29:52 -04001099 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
Len Brownc98d5d92012-06-04 00:56:40 -04001100 return -4;
Len Brown0102b062016-02-27 03:11:29 -05001101
1102 tsc_after = rdtsc();
1103
1104 aperf_time = tsc_between - tsc_before;
1105 mperf_time = tsc_after - tsc_between;
1106
1107 /*
1108 * If the system call latency to read APERF and MPERF
1109 * differ by more than 2x, then try again.
1110 */
1111 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
1112 aperf_mperf_retry_count++;
1113 if (aperf_mperf_retry_count < 5)
1114 goto retry;
1115 else
1116 warnx("cpu%d jitter %lld %lld",
1117 cpu, aperf_time, mperf_time);
1118 }
1119 aperf_mperf_retry_count = 0;
1120
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02001121 t->aperf = t->aperf * aperf_mperf_multiplier;
1122 t->mperf = t->mperf * aperf_mperf_multiplier;
Len Brownc98d5d92012-06-04 00:56:40 -04001123 }
1124
Len Brown562a2d32016-02-26 23:48:05 -05001125 if (do_irq)
1126 t->irq_count = irqs_per_cpu[cpu];
Len Brown1ed51012013-02-10 17:19:24 -05001127 if (do_smi) {
1128 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
1129 return -5;
1130 t->smi_count = msr & 0xFFFFFFFF;
1131 }
Len Brown8e180f32012-09-22 01:25:08 -04001132 if (extra_delta_offset32) {
Len Brown889facb2012-11-08 00:48:57 -05001133 if (get_msr(cpu, extra_delta_offset32, &msr))
Len Brown2f32edf2012-09-21 23:45:46 -04001134 return -5;
Len Brown889facb2012-11-08 00:48:57 -05001135 t->extra_delta32 = msr & 0xFFFFFFFF;
Len Brown8e180f32012-09-22 01:25:08 -04001136 }
1137
1138 if (extra_delta_offset64)
1139 if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
1140 return -5;
1141
1142 if (extra_msr_offset32) {
Len Brown889facb2012-11-08 00:48:57 -05001143 if (get_msr(cpu, extra_msr_offset32, &msr))
Len Brown8e180f32012-09-22 01:25:08 -04001144 return -5;
Len Brown889facb2012-11-08 00:48:57 -05001145 t->extra_msr32 = msr & 0xFFFFFFFF;
Len Brown8e180f32012-09-22 01:25:08 -04001146 }
Len Brown2f32edf2012-09-21 23:45:46 -04001147
1148 if (extra_msr_offset64)
1149 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
Len Brownc98d5d92012-06-04 00:56:40 -04001150 return -5;
1151
Len Brown144b44b2013-11-09 00:30:16 -05001152 if (use_c1_residency_msr) {
1153 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
1154 return -6;
1155 }
1156
Len Brownc98d5d92012-06-04 00:56:40 -04001157 /* collect core counters only for 1st thread in core */
1158 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1159 return 0;
1160
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001161 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) {
Len Brownc98d5d92012-06-04 00:56:40 -04001162 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
1163 return -6;
Len Brown144b44b2013-11-09 00:30:16 -05001164 }
1165
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001166 if (do_nhm_cstates && !do_knl_cstates) {
Len Brownc98d5d92012-06-04 00:56:40 -04001167 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
1168 return -7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001169 } else if (do_knl_cstates) {
1170 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
1171 return -7;
Len Brownc98d5d92012-06-04 00:56:40 -04001172 }
1173
1174 if (do_snb_cstates)
1175 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
1176 return -8;
1177
Len Brown889facb2012-11-08 00:48:57 -05001178 if (do_dts) {
1179 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1180 return -9;
1181 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1182 }
1183
1184
Len Brownc98d5d92012-06-04 00:56:40 -04001185 /* collect package counters only for 1st core in package */
1186 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1187 return 0;
1188
Len Brown0b2bb692015-03-26 00:50:30 -04001189 if (do_skl_residency) {
1190 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
1191 return -10;
1192 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
1193 return -11;
1194 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
1195 return -12;
1196 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
1197 return -13;
1198 }
Len Brownee7e38e2015-02-09 23:39:45 -05001199 if (do_pc3)
Len Brownc98d5d92012-06-04 00:56:40 -04001200 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
1201 return -9;
Len Brownee7e38e2015-02-09 23:39:45 -05001202 if (do_pc6)
Len Brownc98d5d92012-06-04 00:56:40 -04001203 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
1204 return -10;
Len Brownee7e38e2015-02-09 23:39:45 -05001205 if (do_pc2)
Len Brownc98d5d92012-06-04 00:56:40 -04001206 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
1207 return -11;
Len Brownee7e38e2015-02-09 23:39:45 -05001208 if (do_pc7)
Len Brownc98d5d92012-06-04 00:56:40 -04001209 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
1210 return -12;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001211 if (do_c8_c9_c10) {
1212 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
1213 return -13;
1214 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
1215 return -13;
1216 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
1217 return -13;
1218 }
Len Brown889facb2012-11-08 00:48:57 -05001219 if (do_rapl & RAPL_PKG) {
1220 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
1221 return -13;
1222 p->energy_pkg = msr & 0xFFFFFFFF;
1223 }
Jacob Pan91484942016-06-16 09:48:20 -07001224 if (do_rapl & RAPL_CORES_ENERGY_STATUS) {
Len Brown889facb2012-11-08 00:48:57 -05001225 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr))
1226 return -14;
1227 p->energy_cores = msr & 0xFFFFFFFF;
1228 }
1229 if (do_rapl & RAPL_DRAM) {
1230 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
1231 return -15;
1232 p->energy_dram = msr & 0xFFFFFFFF;
1233 }
1234 if (do_rapl & RAPL_GFX) {
1235 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr))
1236 return -16;
1237 p->energy_gfx = msr & 0xFFFFFFFF;
1238 }
1239 if (do_rapl & RAPL_PKG_PERF_STATUS) {
1240 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr))
1241 return -16;
1242 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
1243 }
1244 if (do_rapl & RAPL_DRAM_PERF_STATUS) {
1245 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr))
1246 return -16;
1247 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
1248 }
1249 if (do_ptm) {
1250 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1251 return -17;
1252 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1253 }
Len Brownfdf676e2016-02-27 01:28:12 -05001254
1255 if (do_gfx_rc6_ms)
1256 p->gfx_rc6_ms = gfx_cur_rc6_ms;
1257
Len Brown27d47352016-02-27 00:37:54 -05001258 if (do_gfx_mhz)
1259 p->gfx_mhz = gfx_cur_mhz;
1260
Len Brown103a8fe2010-10-22 23:53:03 -04001261 return 0;
1262}
1263
Len Brownee7e38e2015-02-09 23:39:45 -05001264/*
1265 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1266 * If you change the values, note they are used both in comparisons
1267 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1268 */
1269
1270#define PCLUKN 0 /* Unknown */
1271#define PCLRSV 1 /* Reserved */
1272#define PCL__0 2 /* PC0 */
1273#define PCL__1 3 /* PC1 */
1274#define PCL__2 4 /* PC2 */
1275#define PCL__3 5 /* PC3 */
1276#define PCL__4 6 /* PC4 */
1277#define PCL__6 7 /* PC6 */
1278#define PCL_6N 8 /* PC6 No Retention */
1279#define PCL_6R 9 /* PC6 Retention */
1280#define PCL__7 10 /* PC7 */
1281#define PCL_7S 11 /* PC7 Shrink */
Len Brown0b2bb692015-03-26 00:50:30 -04001282#define PCL__8 12 /* PC8 */
1283#define PCL__9 13 /* PC9 */
1284#define PCLUNL 14 /* Unlimited */
Len Brownee7e38e2015-02-09 23:39:45 -05001285
1286int pkg_cstate_limit = PCLUKN;
1287char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
Len Brown0b2bb692015-03-26 00:50:30 -04001288 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"};
Len Brownee7e38e2015-02-09 23:39:45 -05001289
Len Browne9257f52015-04-01 21:02:57 -04001290int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1291int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1292int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1293int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1294int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1295int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Browne4085d52016-04-06 17:15:56 -04001296int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Brownd8ebb442016-12-01 20:27:46 -05001297int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Brownee7e38e2015-02-09 23:39:45 -05001298
Len Browna2b7b742015-09-26 00:12:38 -04001299
1300static void
1301calculate_tsc_tweak()
1302{
Len Browna2b7b742015-09-26 00:12:38 -04001303 tsc_tweak = base_hz / tsc_hz;
1304}
1305
Len Brownfcd17212015-03-23 20:29:09 -04001306static void
1307dump_nhm_platform_info(void)
Len Brown103a8fe2010-10-22 23:53:03 -04001308{
1309 unsigned long long msr;
1310 unsigned int ratio;
1311
Len Brownec0adc52015-11-12 02:42:31 -05001312 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown103a8fe2010-10-22 23:53:03 -04001313
Len Brownb7d8c142016-02-13 23:36:17 -05001314 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001315
Len Brown103a8fe2010-10-22 23:53:03 -04001316 ratio = (msr >> 40) & 0xFF;
Len Brownb7d8c142016-02-13 23:36:17 -05001317 fprintf(outf, "%d * %.0f = %.0f MHz max efficiency frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001318 ratio, bclk, ratio * bclk);
1319
1320 ratio = (msr >> 8) & 0xFF;
Len Brownb7d8c142016-02-13 23:36:17 -05001321 fprintf(outf, "%d * %.0f = %.0f MHz base frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001322 ratio, bclk, ratio * bclk);
1323
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001324 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001325 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
Len Brownbfae2052015-06-17 12:27:21 -04001326 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
Len Brown67920412013-01-31 15:22:15 -05001327
Len Brownfcd17212015-03-23 20:29:09 -04001328 return;
1329}
1330
1331static void
1332dump_hsw_turbo_ratio_limits(void)
1333{
1334 unsigned long long msr;
1335 unsigned int ratio;
1336
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001337 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001338
Len Brownb7d8c142016-02-13 23:36:17 -05001339 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001340
1341 ratio = (msr >> 8) & 0xFF;
1342 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001343 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 18 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001344 ratio, bclk, ratio * bclk);
1345
1346 ratio = (msr >> 0) & 0xFF;
1347 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001348 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 17 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001349 ratio, bclk, ratio * bclk);
1350 return;
1351}
1352
1353static void
1354dump_ivt_turbo_ratio_limits(void)
1355{
1356 unsigned long long msr;
1357 unsigned int ratio;
Len Brown6574a5d2012-09-21 00:01:31 -04001358
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001359 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001360
Len Brownb7d8c142016-02-13 23:36:17 -05001361 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001362
1363 ratio = (msr >> 56) & 0xFF;
1364 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001365 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001366 ratio, bclk, ratio * bclk);
1367
1368 ratio = (msr >> 48) & 0xFF;
1369 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001370 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001371 ratio, bclk, ratio * bclk);
1372
1373 ratio = (msr >> 40) & 0xFF;
1374 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001375 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001376 ratio, bclk, ratio * bclk);
1377
1378 ratio = (msr >> 32) & 0xFF;
1379 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001380 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001381 ratio, bclk, ratio * bclk);
1382
1383 ratio = (msr >> 24) & 0xFF;
1384 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001385 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001386 ratio, bclk, ratio * bclk);
1387
1388 ratio = (msr >> 16) & 0xFF;
1389 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001390 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001391 ratio, bclk, ratio * bclk);
1392
1393 ratio = (msr >> 8) & 0xFF;
1394 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001395 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001396 ratio, bclk, ratio * bclk);
1397
1398 ratio = (msr >> 0) & 0xFF;
1399 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001400 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001401 ratio, bclk, ratio * bclk);
Len Brownfcd17212015-03-23 20:29:09 -04001402 return;
1403}
Len Brown6574a5d2012-09-21 00:01:31 -04001404
Len Brownfcd17212015-03-23 20:29:09 -04001405static void
1406dump_nhm_turbo_ratio_limits(void)
1407{
1408 unsigned long long msr;
1409 unsigned int ratio;
Len Brown103a8fe2010-10-22 23:53:03 -04001410
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001411 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Len Brown103a8fe2010-10-22 23:53:03 -04001412
Len Brownb7d8c142016-02-13 23:36:17 -05001413 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001414
1415 ratio = (msr >> 56) & 0xFF;
1416 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001417 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001418 ratio, bclk, ratio * bclk);
1419
1420 ratio = (msr >> 48) & 0xFF;
1421 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001422 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001423 ratio, bclk, ratio * bclk);
1424
1425 ratio = (msr >> 40) & 0xFF;
1426 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001427 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001428 ratio, bclk, ratio * bclk);
1429
1430 ratio = (msr >> 32) & 0xFF;
1431 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001432 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001433 ratio, bclk, ratio * bclk);
1434
Len Brown103a8fe2010-10-22 23:53:03 -04001435 ratio = (msr >> 24) & 0xFF;
1436 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001437 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001438 ratio, bclk, ratio * bclk);
1439
1440 ratio = (msr >> 16) & 0xFF;
1441 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001442 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 3 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001443 ratio, bclk, ratio * bclk);
1444
1445 ratio = (msr >> 8) & 0xFF;
1446 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001447 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 2 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001448 ratio, bclk, ratio * bclk);
1449
1450 ratio = (msr >> 0) & 0xFF;
1451 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001452 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001453 ratio, bclk, ratio * bclk);
Len Brownfcd17212015-03-23 20:29:09 -04001454 return;
1455}
Len Brown3a9a9412014-08-15 02:39:52 -04001456
Len Brownfcd17212015-03-23 20:29:09 -04001457static void
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001458dump_knl_turbo_ratio_limits(void)
1459{
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001460 const unsigned int buckets_no = 7;
1461
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001462 unsigned long long msr;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001463 int delta_cores, delta_ratio;
1464 int i, b_nr;
1465 unsigned int cores[buckets_no];
1466 unsigned int ratio[buckets_no];
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001467
Srinivas Pandruvadaebf59262016-07-06 16:07:56 -07001468 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001469
Len Brownb7d8c142016-02-13 23:36:17 -05001470 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
Len Brownbfae2052015-06-17 12:27:21 -04001471 base_cpu, msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001472
1473 /**
1474 * Turbo encoding in KNL is as follows:
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001475 * [0] -- Reserved
1476 * [7:1] -- Base value of number of active cores of bucket 1.
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001477 * [15:8] -- Base value of freq ratio of bucket 1.
1478 * [20:16] -- +ve delta of number of active cores of bucket 2.
1479 * i.e. active cores of bucket 2 =
1480 * active cores of bucket 1 + delta
1481 * [23:21] -- Negative delta of freq ratio of bucket 2.
1482 * i.e. freq ratio of bucket 2 =
1483 * freq ratio of bucket 1 - delta
1484 * [28:24]-- +ve delta of number of active cores of bucket 3.
1485 * [31:29]-- -ve delta of freq ratio of bucket 3.
1486 * [36:32]-- +ve delta of number of active cores of bucket 4.
1487 * [39:37]-- -ve delta of freq ratio of bucket 4.
1488 * [44:40]-- +ve delta of number of active cores of bucket 5.
1489 * [47:45]-- -ve delta of freq ratio of bucket 5.
1490 * [52:48]-- +ve delta of number of active cores of bucket 6.
1491 * [55:53]-- -ve delta of freq ratio of bucket 6.
1492 * [60:56]-- +ve delta of number of active cores of bucket 7.
1493 * [63:61]-- -ve delta of freq ratio of bucket 7.
1494 */
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001495
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001496 b_nr = 0;
1497 cores[b_nr] = (msr & 0xFF) >> 1;
1498 ratio[b_nr] = (msr >> 8) & 0xFF;
1499
1500 for (i = 16; i < 64; i += 8) {
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001501 delta_cores = (msr >> i) & 0x1F;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001502 delta_ratio = (msr >> (i + 5)) & 0x7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001503
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001504 cores[b_nr + 1] = cores[b_nr] + delta_cores;
1505 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
1506 b_nr++;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001507 }
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001508
1509 for (i = buckets_no - 1; i >= 0; i--)
1510 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
Len Brownb7d8c142016-02-13 23:36:17 -05001511 fprintf(outf,
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001512 "%d * %.0f = %.0f MHz max turbo %d active cores\n",
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001513 ratio[i], bclk, ratio[i] * bclk, cores[i]);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001514}
1515
1516static void
Len Brownfcd17212015-03-23 20:29:09 -04001517dump_nhm_cst_cfg(void)
1518{
1519 unsigned long long msr;
1520
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001521 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001522
1523#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
1524#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
1525
Len Brownb7d8c142016-02-13 23:36:17 -05001526 fprintf(outf, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001527
Len Brownb7d8c142016-02-13 23:36:17 -05001528 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
Len Brownfcd17212015-03-23 20:29:09 -04001529 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1530 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1531 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1532 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1533 (msr & (1 << 15)) ? "" : "UN",
Len Brown6c34f162016-03-13 03:21:22 -04001534 (unsigned int)msr & 0xF,
Len Brownfcd17212015-03-23 20:29:09 -04001535 pkg_cstate_limit_strings[pkg_cstate_limit]);
1536 return;
Len Brown103a8fe2010-10-22 23:53:03 -04001537}
1538
Len Brown6fb31432015-06-17 16:23:45 -04001539static void
1540dump_config_tdp(void)
1541{
1542 unsigned long long msr;
1543
1544 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001545 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001546 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
Len Brown6fb31432015-06-17 16:23:45 -04001547
1548 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001549 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001550 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001551 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1552 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1553 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1554 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001555 }
Len Brownb7d8c142016-02-13 23:36:17 -05001556 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001557
1558 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001559 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001560 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001561 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1562 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1563 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1564 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001565 }
Len Brownb7d8c142016-02-13 23:36:17 -05001566 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001567
1568 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001569 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001570 if ((msr) & 0x3)
Len Brownb7d8c142016-02-13 23:36:17 -05001571 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
1572 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1573 fprintf(outf, ")\n");
Len Brown36229892016-02-26 20:51:02 -05001574
Len Brown6fb31432015-06-17 16:23:45 -04001575 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001576 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001577 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
Len Brownb7d8c142016-02-13 23:36:17 -05001578 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1579 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001580}
Len Brown5a634262016-04-06 17:15:55 -04001581
1582unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
1583
1584void print_irtl(void)
1585{
1586 unsigned long long msr;
1587
1588 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
1589 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
1590 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1591 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1592
1593 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
1594 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
1595 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1596 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1597
1598 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
1599 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
1600 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1601 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1602
1603 if (!do_irtl_hsw)
1604 return;
1605
1606 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
1607 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
1608 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1609 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1610
1611 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
1612 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
1613 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1614 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1615
1616 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
1617 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
1618 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1619 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1620
1621}
Len Brown36229892016-02-26 20:51:02 -05001622void free_fd_percpu(void)
1623{
1624 int i;
1625
Mika Westerberg01a67ad2016-04-22 11:13:23 +03001626 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
Len Brown36229892016-02-26 20:51:02 -05001627 if (fd_percpu[i] != 0)
1628 close(fd_percpu[i]);
1629 }
1630
1631 free(fd_percpu);
Len Brown6fb31432015-06-17 16:23:45 -04001632}
1633
Len Brownc98d5d92012-06-04 00:56:40 -04001634void free_all_buffers(void)
Len Brown103a8fe2010-10-22 23:53:03 -04001635{
Len Brownc98d5d92012-06-04 00:56:40 -04001636 CPU_FREE(cpu_present_set);
1637 cpu_present_set = NULL;
Len Brown36229892016-02-26 20:51:02 -05001638 cpu_present_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001639
Len Brownc98d5d92012-06-04 00:56:40 -04001640 CPU_FREE(cpu_affinity_set);
1641 cpu_affinity_set = NULL;
1642 cpu_affinity_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001643
Len Brownc98d5d92012-06-04 00:56:40 -04001644 free(thread_even);
1645 free(core_even);
1646 free(package_even);
1647
1648 thread_even = NULL;
1649 core_even = NULL;
1650 package_even = NULL;
1651
1652 free(thread_odd);
1653 free(core_odd);
1654 free(package_odd);
1655
1656 thread_odd = NULL;
1657 core_odd = NULL;
1658 package_odd = NULL;
1659
1660 free(output_buffer);
1661 output_buffer = NULL;
1662 outp = NULL;
Len Brown36229892016-02-26 20:51:02 -05001663
1664 free_fd_percpu();
Len Brown562a2d32016-02-26 23:48:05 -05001665
1666 free(irq_column_2_cpu);
1667 free(irqs_per_cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001668}
1669
Len Brownc98d5d92012-06-04 00:56:40 -04001670/*
Josh Triplett57a42a32013-08-20 17:20:17 -07001671 * Open a file, and exit on failure
1672 */
1673FILE *fopen_or_die(const char *path, const char *mode)
1674{
Len Brownb7d8c142016-02-13 23:36:17 -05001675 FILE *filep = fopen(path, mode);
Josh Triplettb2c95d92013-08-20 17:20:18 -07001676 if (!filep)
1677 err(1, "%s: open failed", path);
Josh Triplett57a42a32013-08-20 17:20:17 -07001678 return filep;
1679}
1680
1681/*
Josh Triplett95aebc42013-08-20 17:20:16 -07001682 * Parse a file containing a single int.
1683 */
1684int parse_int_file(const char *fmt, ...)
1685{
1686 va_list args;
1687 char path[PATH_MAX];
1688 FILE *filep;
1689 int value;
1690
1691 va_start(args, fmt);
1692 vsnprintf(path, sizeof(path), fmt, args);
1693 va_end(args);
Josh Triplett57a42a32013-08-20 17:20:17 -07001694 filep = fopen_or_die(path, "r");
Josh Triplettb2c95d92013-08-20 17:20:18 -07001695 if (fscanf(filep, "%d", &value) != 1)
1696 err(1, "%s: failed to parse number from file", path);
Josh Triplett95aebc42013-08-20 17:20:16 -07001697 fclose(filep);
1698 return value;
1699}
1700
1701/*
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001702 * get_cpu_position_in_core(cpu)
1703 * return the position of the CPU among its HT siblings in the core
1704 * return -1 if the sibling is not in list
Len Brownc98d5d92012-06-04 00:56:40 -04001705 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001706int get_cpu_position_in_core(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04001707{
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001708 char path[64];
1709 FILE *filep;
1710 int this_cpu;
1711 char character;
1712 int i;
1713
1714 sprintf(path,
1715 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
1716 cpu);
1717 filep = fopen(path, "r");
1718 if (filep == NULL) {
1719 perror(path);
1720 exit(1);
1721 }
1722
1723 for (i = 0; i < topo.num_threads_per_core; i++) {
1724 fscanf(filep, "%d", &this_cpu);
1725 if (this_cpu == cpu) {
1726 fclose(filep);
1727 return i;
1728 }
1729
1730 /* Account for no separator after last thread*/
1731 if (i != (topo.num_threads_per_core - 1))
1732 fscanf(filep, "%c", &character);
1733 }
1734
1735 fclose(filep);
1736 return -1;
Len Brown103a8fe2010-10-22 23:53:03 -04001737}
1738
Len Brownc98d5d92012-06-04 00:56:40 -04001739/*
1740 * cpu_is_first_core_in_package(cpu)
1741 * return 1 if given CPU is 1st core in package
1742 */
1743int cpu_is_first_core_in_package(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04001744{
Josh Triplett95aebc42013-08-20 17:20:16 -07001745 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001746}
1747
1748int get_physical_package_id(int cpu)
1749{
Josh Triplett95aebc42013-08-20 17:20:16 -07001750 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001751}
1752
1753int get_core_id(int cpu)
1754{
Josh Triplett95aebc42013-08-20 17:20:16 -07001755 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001756}
1757
Len Brownc98d5d92012-06-04 00:56:40 -04001758int get_num_ht_siblings(int cpu)
1759{
1760 char path[80];
1761 FILE *filep;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001762 int sib1;
1763 int matches = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001764 char character;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001765 char str[100];
1766 char *ch;
Len Brownc98d5d92012-06-04 00:56:40 -04001767
1768 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
Josh Triplett57a42a32013-08-20 17:20:17 -07001769 filep = fopen_or_die(path, "r");
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001770
Len Brownc98d5d92012-06-04 00:56:40 -04001771 /*
1772 * file format:
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001773 * A ',' separated or '-' separated set of numbers
1774 * (eg 1-2 or 1,3,4,5)
Len Brownc98d5d92012-06-04 00:56:40 -04001775 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001776 fscanf(filep, "%d%c\n", &sib1, &character);
1777 fseek(filep, 0, SEEK_SET);
1778 fgets(str, 100, filep);
1779 ch = strchr(str, character);
1780 while (ch != NULL) {
1781 matches++;
1782 ch = strchr(ch+1, character);
1783 }
Len Brownc98d5d92012-06-04 00:56:40 -04001784
1785 fclose(filep);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001786 return matches+1;
Len Brownc98d5d92012-06-04 00:56:40 -04001787}
1788
Len Brown103a8fe2010-10-22 23:53:03 -04001789/*
Len Brownc98d5d92012-06-04 00:56:40 -04001790 * run func(thread, core, package) in topology order
1791 * skip non-present cpus
Len Brown103a8fe2010-10-22 23:53:03 -04001792 */
1793
Len Brownc98d5d92012-06-04 00:56:40 -04001794int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
1795 struct pkg_data *, struct thread_data *, struct core_data *,
1796 struct pkg_data *), struct thread_data *thread_base,
1797 struct core_data *core_base, struct pkg_data *pkg_base,
1798 struct thread_data *thread_base2, struct core_data *core_base2,
1799 struct pkg_data *pkg_base2)
1800{
1801 int retval, pkg_no, core_no, thread_no;
1802
1803 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
1804 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
1805 for (thread_no = 0; thread_no <
1806 topo.num_threads_per_core; ++thread_no) {
1807 struct thread_data *t, *t2;
1808 struct core_data *c, *c2;
1809 struct pkg_data *p, *p2;
1810
1811 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
1812
1813 if (cpu_is_not_present(t->cpu_id))
1814 continue;
1815
1816 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no);
1817
1818 c = GET_CORE(core_base, core_no, pkg_no);
1819 c2 = GET_CORE(core_base2, core_no, pkg_no);
1820
1821 p = GET_PKG(pkg_base, pkg_no);
1822 p2 = GET_PKG(pkg_base2, pkg_no);
1823
1824 retval = func(t, c, p, t2, c2, p2);
1825 if (retval)
1826 return retval;
1827 }
1828 }
1829 }
1830 return 0;
1831}
1832
1833/*
1834 * run func(cpu) on every cpu in /proc/stat
1835 * return max_cpu number
1836 */
1837int for_all_proc_cpus(int (func)(int))
Len Brown103a8fe2010-10-22 23:53:03 -04001838{
1839 FILE *fp;
Len Brownc98d5d92012-06-04 00:56:40 -04001840 int cpu_num;
Len Brown103a8fe2010-10-22 23:53:03 -04001841 int retval;
1842
Josh Triplett57a42a32013-08-20 17:20:17 -07001843 fp = fopen_or_die(proc_stat, "r");
Len Brown103a8fe2010-10-22 23:53:03 -04001844
1845 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
Josh Triplettb2c95d92013-08-20 17:20:18 -07001846 if (retval != 0)
1847 err(1, "%s: failed to parse format", proc_stat);
Len Brown103a8fe2010-10-22 23:53:03 -04001848
Len Brownc98d5d92012-06-04 00:56:40 -04001849 while (1) {
1850 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
Len Brown103a8fe2010-10-22 23:53:03 -04001851 if (retval != 1)
1852 break;
1853
Len Brownc98d5d92012-06-04 00:56:40 -04001854 retval = func(cpu_num);
1855 if (retval) {
1856 fclose(fp);
1857 return(retval);
1858 }
Len Brown103a8fe2010-10-22 23:53:03 -04001859 }
1860 fclose(fp);
Len Brownc98d5d92012-06-04 00:56:40 -04001861 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001862}
1863
1864void re_initialize(void)
1865{
Len Brownc98d5d92012-06-04 00:56:40 -04001866 free_all_buffers();
1867 setup_all_buffers();
1868 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
Len Brown103a8fe2010-10-22 23:53:03 -04001869}
1870
Len Brownc98d5d92012-06-04 00:56:40 -04001871
Len Brown103a8fe2010-10-22 23:53:03 -04001872/*
Len Brownc98d5d92012-06-04 00:56:40 -04001873 * count_cpus()
1874 * remember the last one seen, it will be the max
Len Brown103a8fe2010-10-22 23:53:03 -04001875 */
Len Brownc98d5d92012-06-04 00:56:40 -04001876int count_cpus(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04001877{
Len Brownc98d5d92012-06-04 00:56:40 -04001878 if (topo.max_cpu_num < cpu)
1879 topo.max_cpu_num = cpu;
Len Brown103a8fe2010-10-22 23:53:03 -04001880
Len Brownc98d5d92012-06-04 00:56:40 -04001881 topo.num_cpus += 1;
1882 return 0;
1883}
1884int mark_cpu_present(int cpu)
1885{
1886 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brown15aaa342012-03-29 22:19:58 -04001887 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001888}
1889
Len Brown562a2d32016-02-26 23:48:05 -05001890/*
1891 * snapshot_proc_interrupts()
1892 *
1893 * read and record summary of /proc/interrupts
1894 *
1895 * return 1 if config change requires a restart, else return 0
1896 */
1897int snapshot_proc_interrupts(void)
1898{
1899 static FILE *fp;
1900 int column, retval;
1901
1902 if (fp == NULL)
1903 fp = fopen_or_die("/proc/interrupts", "r");
1904 else
1905 rewind(fp);
1906
1907 /* read 1st line of /proc/interrupts to get cpu* name for each column */
1908 for (column = 0; column < topo.num_cpus; ++column) {
1909 int cpu_number;
1910
1911 retval = fscanf(fp, " CPU%d", &cpu_number);
1912 if (retval != 1)
1913 break;
1914
1915 if (cpu_number > topo.max_cpu_num) {
1916 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
1917 return 1;
1918 }
1919
1920 irq_column_2_cpu[column] = cpu_number;
1921 irqs_per_cpu[cpu_number] = 0;
1922 }
1923
1924 /* read /proc/interrupt count lines and sum up irqs per cpu */
1925 while (1) {
1926 int column;
1927 char buf[64];
1928
1929 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
1930 if (retval != 1)
1931 break;
1932
1933 /* read the count per cpu */
1934 for (column = 0; column < topo.num_cpus; ++column) {
1935
1936 int cpu_number, irq_count;
1937
1938 retval = fscanf(fp, " %d", &irq_count);
1939 if (retval != 1)
1940 break;
1941
1942 cpu_number = irq_column_2_cpu[column];
1943 irqs_per_cpu[cpu_number] += irq_count;
1944
1945 }
1946
1947 while (getc(fp) != '\n')
1948 ; /* flush interrupt description */
1949
1950 }
1951 return 0;
1952}
Len Brown27d47352016-02-27 00:37:54 -05001953/*
Len Brownfdf676e2016-02-27 01:28:12 -05001954 * snapshot_gfx_rc6_ms()
1955 *
1956 * record snapshot of
1957 * /sys/class/drm/card0/power/rc6_residency_ms
1958 *
1959 * return 1 if config change requires a restart, else return 0
1960 */
1961int snapshot_gfx_rc6_ms(void)
1962{
1963 FILE *fp;
1964 int retval;
1965
1966 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
1967
1968 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
1969 if (retval != 1)
1970 err(1, "GFX rc6");
1971
1972 fclose(fp);
1973
1974 return 0;
1975}
1976/*
Len Brown27d47352016-02-27 00:37:54 -05001977 * snapshot_gfx_mhz()
1978 *
1979 * record snapshot of
1980 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
1981 *
1982 * return 1 if config change requires a restart, else return 0
1983 */
1984int snapshot_gfx_mhz(void)
1985{
1986 static FILE *fp;
1987 int retval;
1988
1989 if (fp == NULL)
1990 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
1991 else
1992 rewind(fp);
1993
1994 retval = fscanf(fp, "%d", &gfx_cur_mhz);
1995 if (retval != 1)
1996 err(1, "GFX MHz");
1997
1998 return 0;
1999}
Len Brown562a2d32016-02-26 23:48:05 -05002000
2001/*
2002 * snapshot /proc and /sys files
2003 *
2004 * return 1 if configuration restart needed, else return 0
2005 */
2006int snapshot_proc_sysfs_files(void)
2007{
2008 if (snapshot_proc_interrupts())
2009 return 1;
2010
Len Brownfdf676e2016-02-27 01:28:12 -05002011 if (do_gfx_rc6_ms)
2012 snapshot_gfx_rc6_ms();
2013
Len Brown27d47352016-02-27 00:37:54 -05002014 if (do_gfx_mhz)
2015 snapshot_gfx_mhz();
2016
Len Brown562a2d32016-02-26 23:48:05 -05002017 return 0;
2018}
2019
Len Brown103a8fe2010-10-22 23:53:03 -04002020void turbostat_loop()
2021{
Len Brownc98d5d92012-06-04 00:56:40 -04002022 int retval;
Len Browne52966c2012-11-08 22:38:05 -05002023 int restarted = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04002024
Len Brown103a8fe2010-10-22 23:53:03 -04002025restart:
Len Browne52966c2012-11-08 22:38:05 -05002026 restarted++;
2027
Len Brown562a2d32016-02-26 23:48:05 -05002028 snapshot_proc_sysfs_files();
Len Brownc98d5d92012-06-04 00:56:40 -04002029 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002030 if (retval < -1) {
2031 exit(retval);
2032 } else if (retval == -1) {
Len Browne52966c2012-11-08 22:38:05 -05002033 if (restarted > 1) {
2034 exit(retval);
2035 }
Len Brownc98d5d92012-06-04 00:56:40 -04002036 re_initialize();
2037 goto restart;
2038 }
Len Browne52966c2012-11-08 22:38:05 -05002039 restarted = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002040 gettimeofday(&tv_even, (struct timezone *)NULL);
2041
2042 while (1) {
Len Brownc98d5d92012-06-04 00:56:40 -04002043 if (for_all_proc_cpus(cpu_is_not_present)) {
Len Brown103a8fe2010-10-22 23:53:03 -04002044 re_initialize();
2045 goto restart;
2046 }
Len Brown2a0609c2016-02-12 22:44:48 -05002047 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002048 if (snapshot_proc_sysfs_files())
2049 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002050 retval = for_all_cpus(get_counters, ODD_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002051 if (retval < -1) {
2052 exit(retval);
2053 } else if (retval == -1) {
Len Brown15aaa342012-03-29 22:19:58 -04002054 re_initialize();
2055 goto restart;
2056 }
Len Brown103a8fe2010-10-22 23:53:03 -04002057 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002058 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002059 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
2060 re_initialize();
2061 goto restart;
2062 }
Len Brownc98d5d92012-06-04 00:56:40 -04002063 compute_average(EVEN_COUNTERS);
2064 format_all_counters(EVEN_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002065 flush_output_stdout();
Len Brown2a0609c2016-02-12 22:44:48 -05002066 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002067 if (snapshot_proc_sysfs_files())
2068 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002069 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002070 if (retval < -1) {
2071 exit(retval);
2072 } else if (retval == -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04002073 re_initialize();
2074 goto restart;
2075 }
Len Brown103a8fe2010-10-22 23:53:03 -04002076 gettimeofday(&tv_even, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002077 timersub(&tv_even, &tv_odd, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002078 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
2079 re_initialize();
2080 goto restart;
2081 }
Len Brownc98d5d92012-06-04 00:56:40 -04002082 compute_average(ODD_COUNTERS);
2083 format_all_counters(ODD_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002084 flush_output_stdout();
Len Brown103a8fe2010-10-22 23:53:03 -04002085 }
2086}
2087
2088void check_dev_msr()
2089{
2090 struct stat sb;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002091 char pathname[32];
Len Brown103a8fe2010-10-22 23:53:03 -04002092
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002093 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2094 if (stat(pathname, &sb))
Len Browna21d38c2015-03-24 16:37:35 -04002095 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
2096 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
Len Brown103a8fe2010-10-22 23:53:03 -04002097}
2098
Len Brown98481e72014-08-15 00:36:50 -04002099void check_permissions()
Len Brown103a8fe2010-10-22 23:53:03 -04002100{
Len Brown98481e72014-08-15 00:36:50 -04002101 struct __user_cap_header_struct cap_header_data;
2102 cap_user_header_t cap_header = &cap_header_data;
2103 struct __user_cap_data_struct cap_data_data;
2104 cap_user_data_t cap_data = &cap_data_data;
2105 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
2106 int do_exit = 0;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002107 char pathname[32];
Len Brown98481e72014-08-15 00:36:50 -04002108
2109 /* check for CAP_SYS_RAWIO */
2110 cap_header->pid = getpid();
2111 cap_header->version = _LINUX_CAPABILITY_VERSION;
2112 if (capget(cap_header, cap_data) < 0)
2113 err(-6, "capget(2) failed");
2114
2115 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
2116 do_exit++;
2117 warnx("capget(CAP_SYS_RAWIO) failed,"
2118 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
2119 }
2120
2121 /* test file permissions */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002122 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2123 if (euidaccess(pathname, R_OK)) {
Len Brown98481e72014-08-15 00:36:50 -04002124 do_exit++;
2125 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
2126 }
2127
2128 /* if all else fails, thell them to be root */
2129 if (do_exit)
2130 if (getuid() != 0)
Len Brownd7899442015-01-23 00:12:33 -05002131 warnx("... or simply run as root");
Len Brown98481e72014-08-15 00:36:50 -04002132
2133 if (do_exit)
2134 exit(-6);
Len Brown103a8fe2010-10-22 23:53:03 -04002135}
2136
Len Brownd7899442015-01-23 00:12:33 -05002137/*
2138 * NHM adds support for additional MSRs:
2139 *
2140 * MSR_SMI_COUNT 0x00000034
2141 *
Len Brownec0adc52015-11-12 02:42:31 -05002142 * MSR_PLATFORM_INFO 0x000000ce
Len Brownd7899442015-01-23 00:12:33 -05002143 * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2
2144 *
2145 * MSR_PKG_C3_RESIDENCY 0x000003f8
2146 * MSR_PKG_C6_RESIDENCY 0x000003f9
2147 * MSR_CORE_C3_RESIDENCY 0x000003fc
2148 * MSR_CORE_C6_RESIDENCY 0x000003fd
2149 *
Len Brownee7e38e2015-02-09 23:39:45 -05002150 * Side effect:
2151 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL
Len Brownd7899442015-01-23 00:12:33 -05002152 */
Len Brownee7e38e2015-02-09 23:39:45 -05002153int probe_nhm_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04002154{
Len Brownee7e38e2015-02-09 23:39:45 -05002155 unsigned long long msr;
Len Brown21ed5572015-10-19 22:37:40 -04002156 unsigned int base_ratio;
Len Brownee7e38e2015-02-09 23:39:45 -05002157 int *pkg_cstate_limits;
2158
Len Brown103a8fe2010-10-22 23:53:03 -04002159 if (!genuine_intel)
2160 return 0;
2161
2162 if (family != 6)
2163 return 0;
2164
Len Brown21ed5572015-10-19 22:37:40 -04002165 bclk = discover_bclk(family, model);
2166
Len Brown103a8fe2010-10-22 23:53:03 -04002167 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002168 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
2169 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
Len Brown103a8fe2010-10-22 23:53:03 -04002170 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
Len Brown869ce692016-06-16 23:22:37 -04002171 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
2172 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
2173 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2174 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
Len Brownee7e38e2015-02-09 23:39:45 -05002175 pkg_cstate_limits = nhm_pkg_cstate_limits;
2176 break;
Len Brown869ce692016-06-16 23:22:37 -04002177 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
2178 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */
2179 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2180 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
Len Brownee7e38e2015-02-09 23:39:45 -05002181 pkg_cstate_limits = snb_pkg_cstate_limits;
2182 break;
Len Brown869ce692016-06-16 23:22:37 -04002183 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2184 case INTEL_FAM6_HASWELL_X: /* HSX */
2185 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2186 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2187 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2188 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2189 case INTEL_FAM6_BROADWELL_X: /* BDX */
2190 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2191 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2192 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2193 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2194 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brownee7e38e2015-02-09 23:39:45 -05002195 pkg_cstate_limits = hsw_pkg_cstate_limits;
2196 break;
Len Brownd8ebb442016-12-01 20:27:46 -05002197 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2198 pkg_cstate_limits = skx_pkg_cstate_limits;
2199 break;
Len Brown869ce692016-06-16 23:22:37 -04002200 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2201 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brownee7e38e2015-02-09 23:39:45 -05002202 pkg_cstate_limits = slv_pkg_cstate_limits;
2203 break;
Len Brown869ce692016-06-16 23:22:37 -04002204 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
Len Brownee7e38e2015-02-09 23:39:45 -05002205 pkg_cstate_limits = amt_pkg_cstate_limits;
2206 break;
Len Brown869ce692016-06-16 23:22:37 -04002207 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
Len Brown005c82d2016-12-01 01:35:38 -05002208 case INTEL_FAM6_XEON_PHI_KNM:
Len Brownee7e38e2015-02-09 23:39:45 -05002209 pkg_cstate_limits = phi_pkg_cstate_limits;
2210 break;
Len Brown869ce692016-06-16 23:22:37 -04002211 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
2212 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Browne4085d52016-04-06 17:15:56 -04002213 pkg_cstate_limits = bxt_pkg_cstate_limits;
2214 break;
Len Brown103a8fe2010-10-22 23:53:03 -04002215 default:
2216 return 0;
2217 }
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002218 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
Len Browne9257f52015-04-01 21:02:57 -04002219 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
Len Brownee7e38e2015-02-09 23:39:45 -05002220
Len Brownec0adc52015-11-12 02:42:31 -05002221 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown21ed5572015-10-19 22:37:40 -04002222 base_ratio = (msr >> 8) & 0xFF;
2223
2224 base_hz = base_ratio * bclk * 1000000;
2225 has_base_hz = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002226 return 1;
Len Brown103a8fe2010-10-22 23:53:03 -04002227}
Len Brownd7899442015-01-23 00:12:33 -05002228int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
2229{
Len Brownd7899442015-01-23 00:12:33 -05002230 switch (model) {
2231 /* Nehalem compatible, but do not include turbo-ratio limit support */
Len Brown869ce692016-06-16 23:22:37 -04002232 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2233 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
2234 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
Len Brown005c82d2016-12-01 01:35:38 -05002235 case INTEL_FAM6_XEON_PHI_KNM:
Len Brownd7899442015-01-23 00:12:33 -05002236 return 0;
2237 default:
2238 return 1;
2239 }
2240}
Len Brown6574a5d2012-09-21 00:01:31 -04002241int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
2242{
2243 if (!genuine_intel)
2244 return 0;
2245
2246 if (family != 6)
2247 return 0;
2248
2249 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002250 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2251 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brown6574a5d2012-09-21 00:01:31 -04002252 return 1;
2253 default:
2254 return 0;
2255 }
2256}
Len Brownfcd17212015-03-23 20:29:09 -04002257int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
2258{
2259 if (!genuine_intel)
2260 return 0;
2261
2262 if (family != 6)
2263 return 0;
2264
2265 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002266 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brownfcd17212015-03-23 20:29:09 -04002267 return 1;
2268 default:
2269 return 0;
2270 }
2271}
2272
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002273int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
2274{
2275 if (!genuine_intel)
2276 return 0;
2277
2278 if (family != 6)
2279 return 0;
2280
2281 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002282 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown005c82d2016-12-01 01:35:38 -05002283 case INTEL_FAM6_XEON_PHI_KNM:
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002284 return 1;
2285 default:
2286 return 0;
2287 }
2288}
Len Brown6fb31432015-06-17 16:23:45 -04002289int has_config_tdp(unsigned int family, unsigned int model)
2290{
2291 if (!genuine_intel)
2292 return 0;
2293
2294 if (family != 6)
2295 return 0;
2296
2297 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002298 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2299 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2300 case INTEL_FAM6_HASWELL_X: /* HSX */
2301 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2302 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2303 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2304 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2305 case INTEL_FAM6_BROADWELL_X: /* BDX */
2306 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2307 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2308 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2309 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2310 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2311 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brown6fb31432015-06-17 16:23:45 -04002312
Len Brown869ce692016-06-16 23:22:37 -04002313 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown005c82d2016-12-01 01:35:38 -05002314 case INTEL_FAM6_XEON_PHI_KNM:
Len Brown6fb31432015-06-17 16:23:45 -04002315 return 1;
2316 default:
2317 return 0;
2318 }
2319}
2320
Len Brownfcd17212015-03-23 20:29:09 -04002321static void
Colin Ian King1b693172016-03-02 13:50:25 +00002322dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
Len Brownfcd17212015-03-23 20:29:09 -04002323{
2324 if (!do_nhm_platform_info)
2325 return;
2326
2327 dump_nhm_platform_info();
2328
2329 if (has_hsw_turbo_ratio_limit(family, model))
2330 dump_hsw_turbo_ratio_limits();
2331
2332 if (has_ivt_turbo_ratio_limit(family, model))
2333 dump_ivt_turbo_ratio_limits();
2334
2335 if (has_nhm_turbo_ratio_limit(family, model))
2336 dump_nhm_turbo_ratio_limits();
2337
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002338 if (has_knl_turbo_ratio_limit(family, model))
2339 dump_knl_turbo_ratio_limits();
2340
Len Brown6fb31432015-06-17 16:23:45 -04002341 if (has_config_tdp(family, model))
2342 dump_config_tdp();
2343
Len Brownfcd17212015-03-23 20:29:09 -04002344 dump_nhm_cst_cfg();
2345}
2346
Len Brown6574a5d2012-09-21 00:01:31 -04002347
Len Brown889facb2012-11-08 00:48:57 -05002348/*
2349 * print_epb()
2350 * Decode the ENERGY_PERF_BIAS MSR
2351 */
2352int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2353{
2354 unsigned long long msr;
2355 char *epb_string;
2356 int cpu;
2357
2358 if (!has_epb)
2359 return 0;
2360
2361 cpu = t->cpu_id;
2362
2363 /* EPB is per-package */
2364 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2365 return 0;
2366
2367 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002368 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002369 return -1;
2370 }
2371
2372 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
2373 return 0;
2374
Len Browne9be7dd2015-05-26 12:19:37 -04002375 switch (msr & 0xF) {
Len Brown889facb2012-11-08 00:48:57 -05002376 case ENERGY_PERF_BIAS_PERFORMANCE:
2377 epb_string = "performance";
2378 break;
2379 case ENERGY_PERF_BIAS_NORMAL:
2380 epb_string = "balanced";
2381 break;
2382 case ENERGY_PERF_BIAS_POWERSAVE:
2383 epb_string = "powersave";
2384 break;
2385 default:
2386 epb_string = "custom";
2387 break;
2388 }
Len Brownb7d8c142016-02-13 23:36:17 -05002389 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
Len Brown889facb2012-11-08 00:48:57 -05002390
2391 return 0;
2392}
Len Brown7f5c2582015-12-01 01:36:39 -05002393/*
2394 * print_hwp()
2395 * Decode the MSR_HWP_CAPABILITIES
2396 */
2397int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2398{
2399 unsigned long long msr;
2400 int cpu;
2401
2402 if (!has_hwp)
2403 return 0;
2404
2405 cpu = t->cpu_id;
2406
2407 /* MSR_HWP_CAPABILITIES is per-package */
2408 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2409 return 0;
2410
2411 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002412 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown7f5c2582015-12-01 01:36:39 -05002413 return -1;
2414 }
2415
2416 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
2417 return 0;
2418
Len Brownb7d8c142016-02-13 23:36:17 -05002419 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
Len Brown7f5c2582015-12-01 01:36:39 -05002420 cpu, msr, (msr & (1 << 0)) ? "" : "No-");
2421
2422 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
2423 if ((msr & (1 << 0)) == 0)
2424 return 0;
2425
2426 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
2427 return 0;
2428
Len Brownb7d8c142016-02-13 23:36:17 -05002429 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002430 "(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
2431 cpu, msr,
2432 (unsigned int)HWP_HIGHEST_PERF(msr),
2433 (unsigned int)HWP_GUARANTEED_PERF(msr),
2434 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
2435 (unsigned int)HWP_LOWEST_PERF(msr));
2436
2437 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
2438 return 0;
2439
Len Brownb7d8c142016-02-13 23:36:17 -05002440 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002441 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
2442 cpu, msr,
2443 (unsigned int)(((msr) >> 0) & 0xff),
2444 (unsigned int)(((msr) >> 8) & 0xff),
2445 (unsigned int)(((msr) >> 16) & 0xff),
2446 (unsigned int)(((msr) >> 24) & 0xff),
2447 (unsigned int)(((msr) >> 32) & 0xff3),
2448 (unsigned int)(((msr) >> 42) & 0x1));
2449
2450 if (has_hwp_pkg) {
2451 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
2452 return 0;
2453
Len Brownb7d8c142016-02-13 23:36:17 -05002454 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002455 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
2456 cpu, msr,
2457 (unsigned int)(((msr) >> 0) & 0xff),
2458 (unsigned int)(((msr) >> 8) & 0xff),
2459 (unsigned int)(((msr) >> 16) & 0xff),
2460 (unsigned int)(((msr) >> 24) & 0xff),
2461 (unsigned int)(((msr) >> 32) & 0xff3));
2462 }
2463 if (has_hwp_notify) {
2464 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
2465 return 0;
2466
Len Brownb7d8c142016-02-13 23:36:17 -05002467 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002468 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
2469 cpu, msr,
2470 ((msr) & 0x1) ? "EN" : "Dis",
2471 ((msr) & 0x2) ? "EN" : "Dis");
2472 }
2473 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
2474 return 0;
2475
Len Brownb7d8c142016-02-13 23:36:17 -05002476 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002477 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
2478 cpu, msr,
2479 ((msr) & 0x1) ? "" : "No-",
2480 ((msr) & 0x2) ? "" : "No-");
Len Brown889facb2012-11-08 00:48:57 -05002481
2482 return 0;
2483}
2484
Len Brown3a9a9412014-08-15 02:39:52 -04002485/*
2486 * print_perf_limit()
2487 */
2488int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2489{
2490 unsigned long long msr;
2491 int cpu;
2492
2493 cpu = t->cpu_id;
2494
2495 /* per-package */
2496 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2497 return 0;
2498
2499 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002500 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown3a9a9412014-08-15 02:39:52 -04002501 return -1;
2502 }
2503
2504 if (do_core_perf_limit_reasons) {
2505 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05002506 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2507 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
Len Browne33cbe82015-03-13 16:30:57 -04002508 (msr & 1 << 15) ? "bit15, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04002509 (msr & 1 << 14) ? "bit14, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04002510 (msr & 1 << 13) ? "Transitions, " : "",
2511 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
2512 (msr & 1 << 11) ? "PkgPwrL2, " : "",
2513 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2514 (msr & 1 << 9) ? "CorePwr, " : "",
2515 (msr & 1 << 8) ? "Amps, " : "",
2516 (msr & 1 << 6) ? "VR-Therm, " : "",
2517 (msr & 1 << 5) ? "Auto-HWP, " : "",
2518 (msr & 1 << 4) ? "Graphics, " : "",
2519 (msr & 1 << 2) ? "bit2, " : "",
2520 (msr & 1 << 1) ? "ThermStatus, " : "",
2521 (msr & 1 << 0) ? "PROCHOT, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05002522 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
Len Browne33cbe82015-03-13 16:30:57 -04002523 (msr & 1 << 31) ? "bit31, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04002524 (msr & 1 << 30) ? "bit30, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04002525 (msr & 1 << 29) ? "Transitions, " : "",
2526 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
2527 (msr & 1 << 27) ? "PkgPwrL2, " : "",
2528 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2529 (msr & 1 << 25) ? "CorePwr, " : "",
2530 (msr & 1 << 24) ? "Amps, " : "",
2531 (msr & 1 << 22) ? "VR-Therm, " : "",
2532 (msr & 1 << 21) ? "Auto-HWP, " : "",
2533 (msr & 1 << 20) ? "Graphics, " : "",
2534 (msr & 1 << 18) ? "bit18, " : "",
2535 (msr & 1 << 17) ? "ThermStatus, " : "",
2536 (msr & 1 << 16) ? "PROCHOT, " : "");
Len Brown3a9a9412014-08-15 02:39:52 -04002537
2538 }
2539 if (do_gfx_perf_limit_reasons) {
2540 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05002541 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2542 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04002543 (msr & 1 << 0) ? "PROCHOT, " : "",
2544 (msr & 1 << 1) ? "ThermStatus, " : "",
2545 (msr & 1 << 4) ? "Graphics, " : "",
2546 (msr & 1 << 6) ? "VR-Therm, " : "",
2547 (msr & 1 << 8) ? "Amps, " : "",
2548 (msr & 1 << 9) ? "GFXPwr, " : "",
2549 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2550 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05002551 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04002552 (msr & 1 << 16) ? "PROCHOT, " : "",
2553 (msr & 1 << 17) ? "ThermStatus, " : "",
2554 (msr & 1 << 20) ? "Graphics, " : "",
2555 (msr & 1 << 22) ? "VR-Therm, " : "",
2556 (msr & 1 << 24) ? "Amps, " : "",
2557 (msr & 1 << 25) ? "GFXPwr, " : "",
2558 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2559 (msr & 1 << 27) ? "PkgPwrL2, " : "");
2560 }
2561 if (do_ring_perf_limit_reasons) {
2562 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05002563 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2564 fprintf(outf, " (Active: %s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04002565 (msr & 1 << 0) ? "PROCHOT, " : "",
2566 (msr & 1 << 1) ? "ThermStatus, " : "",
2567 (msr & 1 << 6) ? "VR-Therm, " : "",
2568 (msr & 1 << 8) ? "Amps, " : "",
2569 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2570 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05002571 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04002572 (msr & 1 << 16) ? "PROCHOT, " : "",
2573 (msr & 1 << 17) ? "ThermStatus, " : "",
2574 (msr & 1 << 22) ? "VR-Therm, " : "",
2575 (msr & 1 << 24) ? "Amps, " : "",
2576 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2577 (msr & 1 << 27) ? "PkgPwrL2, " : "");
2578 }
2579 return 0;
2580}
2581
Len Brown889facb2012-11-08 00:48:57 -05002582#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
2583#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
2584
Colin Ian King1b693172016-03-02 13:50:25 +00002585double get_tdp(unsigned int model)
Len Brown144b44b2013-11-09 00:30:16 -05002586{
2587 unsigned long long msr;
2588
2589 if (do_rapl & RAPL_PKG_POWER_INFO)
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002590 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
Len Brown144b44b2013-11-09 00:30:16 -05002591 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
2592
2593 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002594 case INTEL_FAM6_ATOM_SILVERMONT1:
2595 case INTEL_FAM6_ATOM_SILVERMONT2:
Len Brown144b44b2013-11-09 00:30:16 -05002596 return 30.0;
2597 default:
2598 return 135.0;
2599 }
2600}
2601
Andrey Semin40ee8e32014-12-05 00:07:00 -05002602/*
2603 * rapl_dram_energy_units_probe()
2604 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
2605 */
2606static double
2607rapl_dram_energy_units_probe(int model, double rapl_energy_units)
2608{
2609 /* only called for genuine_intel, family 6 */
2610
2611 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002612 case INTEL_FAM6_HASWELL_X: /* HSX */
2613 case INTEL_FAM6_BROADWELL_X: /* BDX */
2614 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2615 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05002616 case INTEL_FAM6_XEON_PHI_KNM:
Andrey Semin40ee8e32014-12-05 00:07:00 -05002617 return (rapl_dram_energy_units = 15.3 / 1000000);
2618 default:
2619 return (rapl_energy_units);
2620 }
2621}
2622
Len Brown144b44b2013-11-09 00:30:16 -05002623
Len Brown889facb2012-11-08 00:48:57 -05002624/*
2625 * rapl_probe()
2626 *
Len Brown144b44b2013-11-09 00:30:16 -05002627 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
Len Brown889facb2012-11-08 00:48:57 -05002628 */
2629void rapl_probe(unsigned int family, unsigned int model)
2630{
2631 unsigned long long msr;
Len Brown144b44b2013-11-09 00:30:16 -05002632 unsigned int time_unit;
Len Brown889facb2012-11-08 00:48:57 -05002633 double tdp;
2634
2635 if (!genuine_intel)
2636 return;
2637
2638 if (family != 6)
2639 return;
2640
2641 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002642 case INTEL_FAM6_SANDYBRIDGE:
2643 case INTEL_FAM6_IVYBRIDGE:
2644 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2645 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2646 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2647 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2648 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
Len Brown144b44b2013-11-09 00:30:16 -05002649 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
Len Brown889facb2012-11-08 00:48:57 -05002650 break;
Len Brown869ce692016-06-16 23:22:37 -04002651 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Browne4085d52016-04-06 17:15:56 -04002652 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
2653 break;
Len Brown869ce692016-06-16 23:22:37 -04002654 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2655 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2656 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2657 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04002658 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
2659 break;
Len Brown869ce692016-06-16 23:22:37 -04002660 case INTEL_FAM6_HASWELL_X: /* HSX */
2661 case INTEL_FAM6_BROADWELL_X: /* BDX */
2662 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2663 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2664 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05002665 case INTEL_FAM6_XEON_PHI_KNM:
Len Brown0b2bb692015-03-26 00:50:30 -04002666 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
Len Browne6f9bb32013-12-03 02:19:19 -05002667 break;
Len Brown869ce692016-06-16 23:22:37 -04002668 case INTEL_FAM6_SANDYBRIDGE_X:
2669 case INTEL_FAM6_IVYBRIDGE_X:
Len Brown0b2bb692015-03-26 00:50:30 -04002670 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO;
Len Brown144b44b2013-11-09 00:30:16 -05002671 break;
Len Brown869ce692016-06-16 23:22:37 -04002672 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2673 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Jacob Pan91484942016-06-16 09:48:20 -07002674 do_rapl = RAPL_PKG | RAPL_CORES;
Len Brown889facb2012-11-08 00:48:57 -05002675 break;
Len Brown869ce692016-06-16 23:22:37 -04002676 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Jacob Pan0f644902016-06-16 09:48:22 -07002677 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;
2678 break;
Len Brown889facb2012-11-08 00:48:57 -05002679 default:
2680 return;
2681 }
2682
2683 /* units on package 0, verify later other packages match */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002684 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
Len Brown889facb2012-11-08 00:48:57 -05002685 return;
2686
2687 rapl_power_units = 1.0 / (1 << (msr & 0xF));
Len Brown869ce692016-06-16 23:22:37 -04002688 if (model == INTEL_FAM6_ATOM_SILVERMONT1)
Len Brown144b44b2013-11-09 00:30:16 -05002689 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
2690 else
2691 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
Len Brown889facb2012-11-08 00:48:57 -05002692
Andrey Semin40ee8e32014-12-05 00:07:00 -05002693 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
2694
Len Brown144b44b2013-11-09 00:30:16 -05002695 time_unit = msr >> 16 & 0xF;
2696 if (time_unit == 0)
2697 time_unit = 0xA;
Len Brown889facb2012-11-08 00:48:57 -05002698
Len Brown144b44b2013-11-09 00:30:16 -05002699 rapl_time_units = 1.0 / (1 << (time_unit));
2700
2701 tdp = get_tdp(model);
Len Brown889facb2012-11-08 00:48:57 -05002702
2703 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
Len Brownd8af6f52015-02-10 01:56:38 -05002704 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05002705 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
Len Brown889facb2012-11-08 00:48:57 -05002706
2707 return;
2708}
2709
Colin Ian King1b693172016-03-02 13:50:25 +00002710void perf_limit_reasons_probe(unsigned int family, unsigned int model)
Len Brown3a9a9412014-08-15 02:39:52 -04002711{
2712 if (!genuine_intel)
2713 return;
2714
2715 if (family != 6)
2716 return;
2717
2718 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002719 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2720 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2721 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
Len Brown3a9a9412014-08-15 02:39:52 -04002722 do_gfx_perf_limit_reasons = 1;
Len Brown869ce692016-06-16 23:22:37 -04002723 case INTEL_FAM6_HASWELL_X: /* HSX */
Len Brown3a9a9412014-08-15 02:39:52 -04002724 do_core_perf_limit_reasons = 1;
2725 do_ring_perf_limit_reasons = 1;
2726 default:
2727 return;
2728 }
2729}
2730
Len Brown889facb2012-11-08 00:48:57 -05002731int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2732{
2733 unsigned long long msr;
2734 unsigned int dts;
2735 int cpu;
2736
2737 if (!(do_dts || do_ptm))
2738 return 0;
2739
2740 cpu = t->cpu_id;
2741
2742 /* DTS is per-core, no need to print for each thread */
2743 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
2744 return 0;
2745
2746 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002747 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002748 return -1;
2749 }
2750
2751 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
2752 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
2753 return 0;
2754
2755 dts = (msr >> 16) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05002756 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05002757 cpu, msr, tcc_activation_temp - dts);
2758
2759#ifdef THERM_DEBUG
2760 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
2761 return 0;
2762
2763 dts = (msr >> 16) & 0x7F;
2764 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05002765 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05002766 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
2767#endif
2768 }
2769
2770
2771 if (do_dts) {
2772 unsigned int resolution;
2773
2774 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
2775 return 0;
2776
2777 dts = (msr >> 16) & 0x7F;
2778 resolution = (msr >> 27) & 0xF;
Len Brownb7d8c142016-02-13 23:36:17 -05002779 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
Len Brown889facb2012-11-08 00:48:57 -05002780 cpu, msr, tcc_activation_temp - dts, resolution);
2781
2782#ifdef THERM_DEBUG
2783 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
2784 return 0;
2785
2786 dts = (msr >> 16) & 0x7F;
2787 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05002788 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05002789 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
2790#endif
2791 }
2792
2793 return 0;
2794}
Len Brown36229892016-02-26 20:51:02 -05002795
Len Brown889facb2012-11-08 00:48:57 -05002796void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
2797{
Len Brownb7d8c142016-02-13 23:36:17 -05002798 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05002799 cpu, label,
2800 ((msr >> 15) & 1) ? "EN" : "DIS",
2801 ((msr >> 0) & 0x7FFF) * rapl_power_units,
2802 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
2803 (((msr >> 16) & 1) ? "EN" : "DIS"));
2804
2805 return;
2806}
2807
2808int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2809{
2810 unsigned long long msr;
2811 int cpu;
Len Brown889facb2012-11-08 00:48:57 -05002812
2813 if (!do_rapl)
2814 return 0;
2815
2816 /* RAPL counters are per package, so print only for 1st thread/package */
2817 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2818 return 0;
2819
2820 cpu = t->cpu_id;
2821 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002822 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002823 return -1;
2824 }
2825
2826 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
2827 return -1;
2828
Len Brownd8af6f52015-02-10 01:56:38 -05002829 if (debug) {
Len Brownb7d8c142016-02-13 23:36:17 -05002830 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
Len Brown889facb2012-11-08 00:48:57 -05002831 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
Len Brown144b44b2013-11-09 00:30:16 -05002832 rapl_power_units, rapl_energy_units, rapl_time_units);
Len Brown889facb2012-11-08 00:48:57 -05002833 }
Len Brown144b44b2013-11-09 00:30:16 -05002834 if (do_rapl & RAPL_PKG_POWER_INFO) {
2835
Len Brown889facb2012-11-08 00:48:57 -05002836 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
2837 return -5;
2838
2839
Len Brownb7d8c142016-02-13 23:36:17 -05002840 fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
Len Brown889facb2012-11-08 00:48:57 -05002841 cpu, msr,
2842 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2843 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2844 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2845 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
2846
Len Brown144b44b2013-11-09 00:30:16 -05002847 }
2848 if (do_rapl & RAPL_PKG) {
2849
Len Brown889facb2012-11-08 00:48:57 -05002850 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
2851 return -9;
2852
Len Brownb7d8c142016-02-13 23:36:17 -05002853 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002854 cpu, msr, (msr >> 63) & 1 ? "": "UN");
2855
2856 print_power_limit_msr(cpu, msr, "PKG Limit #1");
Len Brownb7d8c142016-02-13 23:36:17 -05002857 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05002858 cpu,
2859 ((msr >> 47) & 1) ? "EN" : "DIS",
2860 ((msr >> 32) & 0x7FFF) * rapl_power_units,
2861 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
2862 ((msr >> 48) & 1) ? "EN" : "DIS");
2863 }
2864
Len Brown0b2bb692015-03-26 00:50:30 -04002865 if (do_rapl & RAPL_DRAM_POWER_INFO) {
Len Brown889facb2012-11-08 00:48:57 -05002866 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
2867 return -6;
2868
Len Brownb7d8c142016-02-13 23:36:17 -05002869 fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
Len Brown889facb2012-11-08 00:48:57 -05002870 cpu, msr,
2871 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2872 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2873 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2874 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
Len Brown0b2bb692015-03-26 00:50:30 -04002875 }
2876 if (do_rapl & RAPL_DRAM) {
Len Brown889facb2012-11-08 00:48:57 -05002877 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
2878 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05002879 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002880 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2881
2882 print_power_limit_msr(cpu, msr, "DRAM Limit");
2883 }
Len Brown144b44b2013-11-09 00:30:16 -05002884 if (do_rapl & RAPL_CORE_POLICY) {
Len Brownd8af6f52015-02-10 01:56:38 -05002885 if (debug) {
Len Brown889facb2012-11-08 00:48:57 -05002886 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
2887 return -7;
2888
Len Brownb7d8c142016-02-13 23:36:17 -05002889 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown144b44b2013-11-09 00:30:16 -05002890 }
2891 }
Jacob Pan91484942016-06-16 09:48:20 -07002892 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
Len Brownd8af6f52015-02-10 01:56:38 -05002893 if (debug) {
Len Brown889facb2012-11-08 00:48:57 -05002894 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
2895 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05002896 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002897 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2898 print_power_limit_msr(cpu, msr, "Cores Limit");
2899 }
2900 }
2901 if (do_rapl & RAPL_GFX) {
Len Brownd8af6f52015-02-10 01:56:38 -05002902 if (debug) {
Len Brown889facb2012-11-08 00:48:57 -05002903 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
2904 return -8;
2905
Len Brownb7d8c142016-02-13 23:36:17 -05002906 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown889facb2012-11-08 00:48:57 -05002907
2908 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
2909 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05002910 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002911 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2912 print_power_limit_msr(cpu, msr, "GFX Limit");
2913 }
2914 }
2915 return 0;
2916}
2917
Len Brownd7899442015-01-23 00:12:33 -05002918/*
2919 * SNB adds support for additional MSRs:
2920 *
2921 * MSR_PKG_C7_RESIDENCY 0x000003fa
2922 * MSR_CORE_C7_RESIDENCY 0x000003fe
2923 * MSR_PKG_C2_RESIDENCY 0x0000060d
2924 */
Len Brown103a8fe2010-10-22 23:53:03 -04002925
Len Brownd7899442015-01-23 00:12:33 -05002926int has_snb_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04002927{
2928 if (!genuine_intel)
2929 return 0;
2930
2931 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002932 case INTEL_FAM6_SANDYBRIDGE:
2933 case INTEL_FAM6_SANDYBRIDGE_X:
2934 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2935 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2936 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2937 case INTEL_FAM6_HASWELL_X: /* HSW */
2938 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2939 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2940 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2941 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2942 case INTEL_FAM6_BROADWELL_X: /* BDX */
2943 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2944 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2945 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2946 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2947 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2948 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2949 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Xiaolong Wang5bbac262016-09-30 17:53:40 +08002950 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Brown103a8fe2010-10-22 23:53:03 -04002951 return 1;
2952 }
2953 return 0;
2954}
2955
Len Brownd7899442015-01-23 00:12:33 -05002956/*
2957 * HSW adds support for additional MSRs:
2958 *
Len Brown5a634262016-04-06 17:15:55 -04002959 * MSR_PKG_C8_RESIDENCY 0x00000630
2960 * MSR_PKG_C9_RESIDENCY 0x00000631
2961 * MSR_PKG_C10_RESIDENCY 0x00000632
2962 *
2963 * MSR_PKGC8_IRTL 0x00000633
2964 * MSR_PKGC9_IRTL 0x00000634
2965 * MSR_PKGC10_IRTL 0x00000635
2966 *
Len Brownd7899442015-01-23 00:12:33 -05002967 */
2968int has_hsw_msrs(unsigned int family, unsigned int model)
Kristen Carlson Accardica587102012-11-21 05:22:43 -08002969{
2970 if (!genuine_intel)
2971 return 0;
2972
2973 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002974 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2975 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2976 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2977 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2978 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2979 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2980 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Kristen Carlson Accardica587102012-11-21 05:22:43 -08002981 return 1;
2982 }
2983 return 0;
2984}
2985
Len Brown0b2bb692015-03-26 00:50:30 -04002986/*
2987 * SKL adds support for additional MSRS:
2988 *
2989 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
2990 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
2991 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
2992 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
2993 */
2994int has_skl_msrs(unsigned int family, unsigned int model)
2995{
2996 if (!genuine_intel)
2997 return 0;
2998
2999 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003000 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3001 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3002 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3003 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04003004 return 1;
3005 }
3006 return 0;
3007}
3008
3009
Kristen Carlson Accardica587102012-11-21 05:22:43 -08003010
Len Brown144b44b2013-11-09 00:30:16 -05003011int is_slm(unsigned int family, unsigned int model)
3012{
3013 if (!genuine_intel)
3014 return 0;
3015 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003016 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3017 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brown144b44b2013-11-09 00:30:16 -05003018 return 1;
3019 }
3020 return 0;
3021}
3022
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003023int is_knl(unsigned int family, unsigned int model)
3024{
3025 if (!genuine_intel)
3026 return 0;
3027 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003028 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003029 case INTEL_FAM6_XEON_PHI_KNM:
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003030 return 1;
3031 }
3032 return 0;
3033}
3034
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02003035unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
3036{
3037 if (is_knl(family, model))
3038 return 1024;
3039 return 1;
3040}
3041
Len Brown144b44b2013-11-09 00:30:16 -05003042#define SLM_BCLK_FREQS 5
3043double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
3044
3045double slm_bclk(void)
3046{
3047 unsigned long long msr = 3;
3048 unsigned int i;
3049 double freq;
3050
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003051 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003052 fprintf(outf, "SLM BCLK: unknown\n");
Len Brown144b44b2013-11-09 00:30:16 -05003053
3054 i = msr & 0xf;
3055 if (i >= SLM_BCLK_FREQS) {
Len Brownb7d8c142016-02-13 23:36:17 -05003056 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
Colin Ian King0a91e552016-04-25 13:03:15 +01003057 i = 3;
Len Brown144b44b2013-11-09 00:30:16 -05003058 }
3059 freq = slm_freq_table[i];
3060
Len Brownb7d8c142016-02-13 23:36:17 -05003061 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
Len Brown144b44b2013-11-09 00:30:16 -05003062
3063 return freq;
3064}
3065
Len Brown103a8fe2010-10-22 23:53:03 -04003066double discover_bclk(unsigned int family, unsigned int model)
3067{
Chrzaniuk, Hubert121b48b2016-02-10 16:35:17 +01003068 if (has_snb_msrs(family, model) || is_knl(family, model))
Len Brown103a8fe2010-10-22 23:53:03 -04003069 return 100.00;
Len Brown144b44b2013-11-09 00:30:16 -05003070 else if (is_slm(family, model))
3071 return slm_bclk();
Len Brown103a8fe2010-10-22 23:53:03 -04003072 else
3073 return 133.33;
3074}
3075
Len Brown889facb2012-11-08 00:48:57 -05003076/*
3077 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
3078 * the Thermal Control Circuit (TCC) activates.
3079 * This is usually equal to tjMax.
3080 *
3081 * Older processors do not have this MSR, so there we guess,
3082 * but also allow cmdline over-ride with -T.
3083 *
3084 * Several MSR temperature values are in units of degrees-C
3085 * below this value, including the Digital Thermal Sensor (DTS),
3086 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
3087 */
3088int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3089{
3090 unsigned long long msr;
3091 unsigned int target_c_local;
3092 int cpu;
3093
3094 /* tcc_activation_temp is used only for dts or ptm */
3095 if (!(do_dts || do_ptm))
3096 return 0;
3097
3098 /* this is a per-package concept */
3099 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3100 return 0;
3101
3102 cpu = t->cpu_id;
3103 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003104 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003105 return -1;
3106 }
3107
3108 if (tcc_activation_temp_override != 0) {
3109 tcc_activation_temp = tcc_activation_temp_override;
Len Brownb7d8c142016-02-13 23:36:17 -05003110 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003111 cpu, tcc_activation_temp);
3112 return 0;
3113 }
3114
3115 /* Temperature Target MSR is Nehalem and newer only */
Len Brownd7899442015-01-23 00:12:33 -05003116 if (!do_nhm_platform_info)
Len Brown889facb2012-11-08 00:48:57 -05003117 goto guess;
3118
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003119 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
Len Brown889facb2012-11-08 00:48:57 -05003120 goto guess;
3121
Jean Delvare34821242014-05-01 11:40:19 +02003122 target_c_local = (msr >> 16) & 0xFF;
Len Brown889facb2012-11-08 00:48:57 -05003123
Len Brownd8af6f52015-02-10 01:56:38 -05003124 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003125 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003126 cpu, msr, target_c_local);
3127
Jean Delvare34821242014-05-01 11:40:19 +02003128 if (!target_c_local)
Len Brown889facb2012-11-08 00:48:57 -05003129 goto guess;
3130
3131 tcc_activation_temp = target_c_local;
3132
3133 return 0;
3134
3135guess:
3136 tcc_activation_temp = TJMAX_DEFAULT;
Len Brownb7d8c142016-02-13 23:36:17 -05003137 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
Len Brown889facb2012-11-08 00:48:57 -05003138 cpu, tcc_activation_temp);
3139
3140 return 0;
3141}
Len Brown69807a62015-11-21 12:22:47 -05003142
Len Brownaa8d8cc2016-03-11 13:26:03 -05003143void decode_feature_control_msr(void)
3144{
3145 unsigned long long msr;
3146
3147 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
3148 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
3149 base_cpu, msr,
3150 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
3151 msr & (1 << 18) ? "SGX" : "");
3152}
3153
Len Brown69807a62015-11-21 12:22:47 -05003154void decode_misc_enable_msr(void)
3155{
3156 unsigned long long msr;
3157
3158 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003159 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%s %s %s)\n",
Len Brown69807a62015-11-21 12:22:47 -05003160 base_cpu, msr,
3161 msr & (1 << 3) ? "TCC" : "",
3162 msr & (1 << 16) ? "EIST" : "",
3163 msr & (1 << 18) ? "MONITOR" : "");
3164}
3165
Len Brownf0057312015-12-03 01:35:36 -05003166/*
3167 * Decode MSR_MISC_PWR_MGMT
3168 *
3169 * Decode the bits according to the Nehalem documentation
3170 * bit[0] seems to continue to have same meaning going forward
3171 * bit[1] less so...
3172 */
3173void decode_misc_pwr_mgmt_msr(void)
3174{
3175 unsigned long long msr;
3176
3177 if (!do_nhm_platform_info)
3178 return;
3179
3180 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
Srinivas Pandruvadaddadb8a2016-11-11 14:29:48 -08003181 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
Len Brownf0057312015-12-03 01:35:36 -05003182 base_cpu, msr,
3183 msr & (1 << 0) ? "DIS" : "EN",
Srinivas Pandruvadaddadb8a2016-11-11 14:29:48 -08003184 msr & (1 << 1) ? "EN" : "DIS",
3185 msr & (1 << 8) ? "EN" : "DIS");
Len Brownf0057312015-12-03 01:35:36 -05003186}
Len Brown7f5c2582015-12-01 01:36:39 -05003187
Len Brownfcd17212015-03-23 20:29:09 -04003188void process_cpuid()
Len Brown103a8fe2010-10-22 23:53:03 -04003189{
Len Brown61a87ba2015-11-23 02:30:51 -05003190 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
Len Brown103a8fe2010-10-22 23:53:03 -04003191 unsigned int fms, family, model, stepping;
3192
3193 eax = ebx = ecx = edx = 0;
3194
Len Brown5aea2f72016-03-13 03:14:35 -04003195 __cpuid(0, max_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003196
3197 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
3198 genuine_intel = 1;
3199
Len Brownd8af6f52015-02-10 01:56:38 -05003200 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003201 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
Len Brown103a8fe2010-10-22 23:53:03 -04003202 (char *)&ebx, (char *)&edx, (char *)&ecx);
3203
Len Brown5aea2f72016-03-13 03:14:35 -04003204 __cpuid(1, fms, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003205 family = (fms >> 8) & 0xf;
3206 model = (fms >> 4) & 0xf;
3207 stepping = fms & 0xf;
3208 if (family == 6 || family == 0xf)
3209 model += ((fms >> 16) & 0xf) << 4;
3210
Len Brown69807a62015-11-21 12:22:47 -05003211 if (debug) {
Len Brownb7d8c142016-02-13 23:36:17 -05003212 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
Len Brown103a8fe2010-10-22 23:53:03 -04003213 max_level, family, model, stepping, family, model, stepping);
Len Brownaa8d8cc2016-03-11 13:26:03 -05003214 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
Len Brown69807a62015-11-21 12:22:47 -05003215 ecx & (1 << 0) ? "SSE3" : "-",
3216 ecx & (1 << 3) ? "MONITOR" : "-",
Len Brownaa8d8cc2016-03-11 13:26:03 -05003217 ecx & (1 << 6) ? "SMX" : "-",
Len Brown69807a62015-11-21 12:22:47 -05003218 ecx & (1 << 7) ? "EIST" : "-",
3219 ecx & (1 << 8) ? "TM2" : "-",
3220 edx & (1 << 4) ? "TSC" : "-",
3221 edx & (1 << 5) ? "MSR" : "-",
3222 edx & (1 << 22) ? "ACPI-TM" : "-",
3223 edx & (1 << 29) ? "TM" : "-");
3224 }
Len Brown103a8fe2010-10-22 23:53:03 -04003225
Josh Triplettb2c95d92013-08-20 17:20:18 -07003226 if (!(edx & (1 << 5)))
3227 errx(1, "CPUID: no MSR");
Len Brown103a8fe2010-10-22 23:53:03 -04003228
3229 /*
3230 * check max extended function levels of CPUID.
3231 * This is needed to check for invariant TSC.
3232 * This check is valid for both Intel and AMD.
3233 */
3234 ebx = ecx = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003235 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003236
Len Brown61a87ba2015-11-23 02:30:51 -05003237 if (max_extended_level >= 0x80000007) {
Len Brown103a8fe2010-10-22 23:53:03 -04003238
Len Brownd7899442015-01-23 00:12:33 -05003239 /*
3240 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
3241 * this check is valid for both Intel and AMD
3242 */
Len Brown5aea2f72016-03-13 03:14:35 -04003243 __cpuid(0x80000007, eax, ebx, ecx, edx);
Len Brownd7899442015-01-23 00:12:33 -05003244 has_invariant_tsc = edx & (1 << 8);
3245 }
Len Brown103a8fe2010-10-22 23:53:03 -04003246
3247 /*
3248 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
3249 * this check is valid for both Intel and AMD
3250 */
3251
Len Brown5aea2f72016-03-13 03:14:35 -04003252 __cpuid(0x6, eax, ebx, ecx, edx);
Thomas Renninger8209e052011-01-21 15:11:19 +01003253 has_aperf = ecx & (1 << 0);
Len Brown889facb2012-11-08 00:48:57 -05003254 do_dts = eax & (1 << 0);
3255 do_ptm = eax & (1 << 6);
Len Brown7f5c2582015-12-01 01:36:39 -05003256 has_hwp = eax & (1 << 7);
3257 has_hwp_notify = eax & (1 << 8);
3258 has_hwp_activity_window = eax & (1 << 9);
3259 has_hwp_epp = eax & (1 << 10);
3260 has_hwp_pkg = eax & (1 << 11);
Len Brown889facb2012-11-08 00:48:57 -05003261 has_epb = ecx & (1 << 3);
3262
Len Brownd8af6f52015-02-10 01:56:38 -05003263 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003264 fprintf(outf, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sHWP, "
Len Brown7f5c2582015-12-01 01:36:39 -05003265 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
3266 has_aperf ? "" : "No-",
3267 do_dts ? "" : "No-",
3268 do_ptm ? "" : "No-",
3269 has_hwp ? "" : "No-",
3270 has_hwp_notify ? "" : "No-",
3271 has_hwp_activity_window ? "" : "No-",
3272 has_hwp_epp ? "" : "No-",
3273 has_hwp_pkg ? "" : "No-",
3274 has_epb ? "" : "No-");
Len Brown103a8fe2010-10-22 23:53:03 -04003275
Len Brown69807a62015-11-21 12:22:47 -05003276 if (debug)
3277 decode_misc_enable_msr();
3278
Len Brown8ae72252016-04-06 17:15:54 -04003279 if (max_level >= 0x7 && debug) {
Len Brownaa8d8cc2016-03-11 13:26:03 -05003280 int has_sgx;
3281
3282 ecx = 0;
3283
3284 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
3285
3286 has_sgx = ebx & (1 << 2);
3287 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
3288
3289 if (has_sgx)
3290 decode_feature_control_msr();
3291 }
3292
Len Brown61a87ba2015-11-23 02:30:51 -05003293 if (max_level >= 0x15) {
Len Brown8a5bdf42015-04-01 21:02:57 -04003294 unsigned int eax_crystal;
3295 unsigned int ebx_tsc;
3296
3297 /*
3298 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
3299 */
3300 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003301 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
Len Brown8a5bdf42015-04-01 21:02:57 -04003302
3303 if (ebx_tsc != 0) {
3304
3305 if (debug && (ebx != 0))
Len Brownb7d8c142016-02-13 23:36:17 -05003306 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003307 eax_crystal, ebx_tsc, crystal_hz);
3308
3309 if (crystal_hz == 0)
3310 switch(model) {
Len Brown869ce692016-06-16 23:22:37 -04003311 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3312 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3313 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3314 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Browne8efbc82016-04-06 17:15:57 -04003315 crystal_hz = 24000000; /* 24.0 MHz */
3316 break;
Len Brown869ce692016-06-16 23:22:37 -04003317 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brownec53e592016-04-06 17:15:58 -04003318 crystal_hz = 25000000; /* 25.0 MHz */
3319 break;
Len Brown869ce692016-06-16 23:22:37 -04003320 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
3321 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Browne8efbc82016-04-06 17:15:57 -04003322 crystal_hz = 19200000; /* 19.2 MHz */
Len Brown8a5bdf42015-04-01 21:02:57 -04003323 break;
3324 default:
3325 crystal_hz = 0;
3326 }
3327
3328 if (crystal_hz) {
3329 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
3330 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003331 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003332 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
3333 }
3334 }
3335 }
Len Brown61a87ba2015-11-23 02:30:51 -05003336 if (max_level >= 0x16) {
3337 unsigned int base_mhz, max_mhz, bus_mhz, edx;
3338
3339 /*
3340 * CPUID 16H Base MHz, Max MHz, Bus MHz
3341 */
3342 base_mhz = max_mhz = bus_mhz = edx = 0;
3343
Len Brown5aea2f72016-03-13 03:14:35 -04003344 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
Len Brown61a87ba2015-11-23 02:30:51 -05003345 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003346 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
Len Brown61a87ba2015-11-23 02:30:51 -05003347 base_mhz, max_mhz, bus_mhz);
3348 }
Len Brown8a5bdf42015-04-01 21:02:57 -04003349
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02003350 if (has_aperf)
3351 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
3352
Len Brownee7e38e2015-02-09 23:39:45 -05003353 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
Len Brownd7899442015-01-23 00:12:33 -05003354 do_snb_cstates = has_snb_msrs(family, model);
Len Brown5a634262016-04-06 17:15:55 -04003355 do_irtl_snb = has_snb_msrs(family, model);
Len Brownee7e38e2015-02-09 23:39:45 -05003356 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
3357 do_pc3 = (pkg_cstate_limit >= PCL__3);
3358 do_pc6 = (pkg_cstate_limit >= PCL__6);
3359 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
Len Brownd7899442015-01-23 00:12:33 -05003360 do_c8_c9_c10 = has_hsw_msrs(family, model);
Len Brown5a634262016-04-06 17:15:55 -04003361 do_irtl_hsw = has_hsw_msrs(family, model);
Len Brown0b2bb692015-03-26 00:50:30 -04003362 do_skl_residency = has_skl_msrs(family, model);
Len Brown144b44b2013-11-09 00:30:16 -05003363 do_slm_cstates = is_slm(family, model);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003364 do_knl_cstates = is_knl(family, model);
Len Brown103a8fe2010-10-22 23:53:03 -04003365
Len Brownf0057312015-12-03 01:35:36 -05003366 if (debug)
3367 decode_misc_pwr_mgmt_msr();
3368
Len Brown889facb2012-11-08 00:48:57 -05003369 rapl_probe(family, model);
Len Brown3a9a9412014-08-15 02:39:52 -04003370 perf_limit_reasons_probe(family, model);
Len Brown889facb2012-11-08 00:48:57 -05003371
Len Brownfcd17212015-03-23 20:29:09 -04003372 if (debug)
Colin Ian King1b693172016-03-02 13:50:25 +00003373 dump_cstate_pstate_config_info(family, model);
Len Brownfcd17212015-03-23 20:29:09 -04003374
Len Browna2b7b742015-09-26 00:12:38 -04003375 if (has_skl_msrs(family, model))
3376 calculate_tsc_tweak();
3377
Len Brownfdf676e2016-02-27 01:28:12 -05003378 do_gfx_rc6_ms = !access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK);
3379
Len Brown27d47352016-02-27 00:37:54 -05003380 do_gfx_mhz = !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK);
3381
Len Brown889facb2012-11-08 00:48:57 -05003382 return;
Len Brown103a8fe2010-10-22 23:53:03 -04003383}
3384
Len Brownd8af6f52015-02-10 01:56:38 -05003385void help()
Len Brown103a8fe2010-10-22 23:53:03 -04003386{
Len Brownb7d8c142016-02-13 23:36:17 -05003387 fprintf(outf,
Len Brownd8af6f52015-02-10 01:56:38 -05003388 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
3389 "\n"
3390 "Turbostat forks the specified COMMAND and prints statistics\n"
3391 "when COMMAND completes.\n"
3392 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
3393 "to print statistics, until interrupted.\n"
3394 "--debug run in \"debug\" mode\n"
3395 "--interval sec Override default 5-second measurement interval\n"
3396 "--help print this help message\n"
3397 "--counter msr print 32-bit counter at address \"msr\"\n"
3398 "--Counter msr print 64-bit Counter at address \"msr\"\n"
Len Brownb7d8c142016-02-13 23:36:17 -05003399 "--out file create or truncate \"file\" for all output\n"
Len Brownd8af6f52015-02-10 01:56:38 -05003400 "--msr msr print 32-bit value at address \"msr\"\n"
3401 "--MSR msr print 64-bit Value at address \"msr\"\n"
3402 "--version print version information\n"
3403 "\n"
3404 "For more help, run \"man turbostat\"\n");
Len Brown103a8fe2010-10-22 23:53:03 -04003405}
3406
3407
3408/*
3409 * in /dev/cpu/ return success for names that are numbers
3410 * ie. filter out ".", "..", "microcode".
3411 */
3412int dir_filter(const struct dirent *dirp)
3413{
3414 if (isdigit(dirp->d_name[0]))
3415 return 1;
3416 else
3417 return 0;
3418}
3419
3420int open_dev_cpu_msr(int dummy1)
3421{
3422 return 0;
3423}
3424
Len Brownc98d5d92012-06-04 00:56:40 -04003425void topology_probe()
3426{
3427 int i;
3428 int max_core_id = 0;
3429 int max_package_id = 0;
3430 int max_siblings = 0;
3431 struct cpu_topology {
3432 int core_id;
3433 int physical_package_id;
3434 } *cpus;
3435
3436 /* Initialize num_cpus, max_cpu_num */
3437 topo.num_cpus = 0;
3438 topo.max_cpu_num = 0;
3439 for_all_proc_cpus(count_cpus);
3440 if (!summary_only && topo.num_cpus > 1)
3441 show_cpu = 1;
3442
Len Brownd8af6f52015-02-10 01:56:38 -05003443 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003444 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
Len Brownc98d5d92012-06-04 00:56:40 -04003445
3446 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
Josh Triplettb2c95d92013-08-20 17:20:18 -07003447 if (cpus == NULL)
3448 err(1, "calloc cpus");
Len Brownc98d5d92012-06-04 00:56:40 -04003449
3450 /*
3451 * Allocate and initialize cpu_present_set
3452 */
3453 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07003454 if (cpu_present_set == NULL)
3455 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04003456 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3457 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
3458 for_all_proc_cpus(mark_cpu_present);
3459
3460 /*
3461 * Allocate and initialize cpu_affinity_set
3462 */
3463 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07003464 if (cpu_affinity_set == NULL)
3465 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04003466 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3467 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
3468
3469
3470 /*
3471 * For online cpus
3472 * find max_core_id, max_package_id
3473 */
3474 for (i = 0; i <= topo.max_cpu_num; ++i) {
3475 int siblings;
3476
3477 if (cpu_is_not_present(i)) {
Len Brownd8af6f52015-02-10 01:56:38 -05003478 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003479 fprintf(outf, "cpu%d NOT PRESENT\n", i);
Len Brownc98d5d92012-06-04 00:56:40 -04003480 continue;
3481 }
3482 cpus[i].core_id = get_core_id(i);
3483 if (cpus[i].core_id > max_core_id)
3484 max_core_id = cpus[i].core_id;
3485
3486 cpus[i].physical_package_id = get_physical_package_id(i);
3487 if (cpus[i].physical_package_id > max_package_id)
3488 max_package_id = cpus[i].physical_package_id;
3489
3490 siblings = get_num_ht_siblings(i);
3491 if (siblings > max_siblings)
3492 max_siblings = siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05003493 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003494 fprintf(outf, "cpu %d pkg %d core %d\n",
Len Brownc98d5d92012-06-04 00:56:40 -04003495 i, cpus[i].physical_package_id, cpus[i].core_id);
3496 }
3497 topo.num_cores_per_pkg = max_core_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05003498 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003499 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
Len Brownc98d5d92012-06-04 00:56:40 -04003500 max_core_id, topo.num_cores_per_pkg);
Len Brown1cc21f72015-02-23 00:34:57 -05003501 if (debug && !summary_only && topo.num_cores_per_pkg > 1)
Len Brownc98d5d92012-06-04 00:56:40 -04003502 show_core = 1;
3503
3504 topo.num_packages = max_package_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05003505 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003506 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
Len Brownc98d5d92012-06-04 00:56:40 -04003507 max_package_id, topo.num_packages);
Len Brown1cc21f72015-02-23 00:34:57 -05003508 if (debug && !summary_only && topo.num_packages > 1)
Len Brownc98d5d92012-06-04 00:56:40 -04003509 show_pkg = 1;
3510
3511 topo.num_threads_per_core = max_siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05003512 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003513 fprintf(outf, "max_siblings %d\n", max_siblings);
Len Brownc98d5d92012-06-04 00:56:40 -04003514
3515 free(cpus);
3516}
3517
3518void
3519allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
3520{
3521 int i;
3522
3523 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
3524 topo.num_packages, sizeof(struct thread_data));
3525 if (*t == NULL)
3526 goto error;
3527
3528 for (i = 0; i < topo.num_threads_per_core *
3529 topo.num_cores_per_pkg * topo.num_packages; i++)
3530 (*t)[i].cpu_id = -1;
3531
3532 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
3533 sizeof(struct core_data));
3534 if (*c == NULL)
3535 goto error;
3536
3537 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
3538 (*c)[i].core_id = -1;
3539
3540 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
3541 if (*p == NULL)
3542 goto error;
3543
3544 for (i = 0; i < topo.num_packages; i++)
3545 (*p)[i].package_id = i;
3546
3547 return;
3548error:
Josh Triplettb2c95d92013-08-20 17:20:18 -07003549 err(1, "calloc counters");
Len Brownc98d5d92012-06-04 00:56:40 -04003550}
3551/*
3552 * init_counter()
3553 *
3554 * set cpu_id, core_num, pkg_num
3555 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
3556 *
3557 * increment topo.num_cores when 1st core in pkg seen
3558 */
3559void init_counter(struct thread_data *thread_base, struct core_data *core_base,
3560 struct pkg_data *pkg_base, int thread_num, int core_num,
3561 int pkg_num, int cpu_id)
3562{
3563 struct thread_data *t;
3564 struct core_data *c;
3565 struct pkg_data *p;
3566
3567 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num);
3568 c = GET_CORE(core_base, core_num, pkg_num);
3569 p = GET_PKG(pkg_base, pkg_num);
3570
3571 t->cpu_id = cpu_id;
3572 if (thread_num == 0) {
3573 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
3574 if (cpu_is_first_core_in_package(cpu_id))
3575 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
3576 }
3577
3578 c->core_id = core_num;
3579 p->package_id = pkg_num;
3580}
3581
3582
3583int initialize_counters(int cpu_id)
3584{
3585 int my_thread_id, my_core_id, my_package_id;
3586
3587 my_package_id = get_physical_package_id(cpu_id);
3588 my_core_id = get_core_id(cpu_id);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07003589 my_thread_id = get_cpu_position_in_core(cpu_id);
3590 if (!my_thread_id)
Len Brownc98d5d92012-06-04 00:56:40 -04003591 topo.num_cores++;
Len Brownc98d5d92012-06-04 00:56:40 -04003592
3593 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
3594 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
3595 return 0;
3596}
3597
3598void allocate_output_buffer()
3599{
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003600 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
Len Brownc98d5d92012-06-04 00:56:40 -04003601 outp = output_buffer;
Josh Triplettb2c95d92013-08-20 17:20:18 -07003602 if (outp == NULL)
3603 err(-1, "calloc output buffer");
Len Brownc98d5d92012-06-04 00:56:40 -04003604}
Len Brown36229892016-02-26 20:51:02 -05003605void allocate_fd_percpu(void)
3606{
Mika Westerberg01a67ad2016-04-22 11:13:23 +03003607 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown36229892016-02-26 20:51:02 -05003608 if (fd_percpu == NULL)
3609 err(-1, "calloc fd_percpu");
3610}
Len Brown562a2d32016-02-26 23:48:05 -05003611void allocate_irq_buffers(void)
3612{
3613 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
3614 if (irq_column_2_cpu == NULL)
3615 err(-1, "calloc %d", topo.num_cpus);
Len Brownc98d5d92012-06-04 00:56:40 -04003616
Mika Westerberg01a67ad2016-04-22 11:13:23 +03003617 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown562a2d32016-02-26 23:48:05 -05003618 if (irqs_per_cpu == NULL)
Mika Westerberg01a67ad2016-04-22 11:13:23 +03003619 err(-1, "calloc %d", topo.max_cpu_num + 1);
Len Brown562a2d32016-02-26 23:48:05 -05003620}
Len Brownc98d5d92012-06-04 00:56:40 -04003621void setup_all_buffers(void)
3622{
3623 topology_probe();
Len Brown562a2d32016-02-26 23:48:05 -05003624 allocate_irq_buffers();
Len Brown36229892016-02-26 20:51:02 -05003625 allocate_fd_percpu();
Len Brownc98d5d92012-06-04 00:56:40 -04003626 allocate_counters(&thread_even, &core_even, &package_even);
3627 allocate_counters(&thread_odd, &core_odd, &package_odd);
3628 allocate_output_buffer();
3629 for_all_proc_cpus(initialize_counters);
3630}
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003631
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003632void set_base_cpu(void)
3633{
3634 base_cpu = sched_getcpu();
3635 if (base_cpu < 0)
3636 err(-ENODEV, "No valid cpus found");
3637
3638 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003639 fprintf(outf, "base_cpu = %d\n", base_cpu);
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003640}
3641
Len Brown103a8fe2010-10-22 23:53:03 -04003642void turbostat_init()
3643{
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003644 setup_all_buffers();
3645 set_base_cpu();
Len Brown103a8fe2010-10-22 23:53:03 -04003646 check_dev_msr();
Len Brown98481e72014-08-15 00:36:50 -04003647 check_permissions();
Len Brownfcd17212015-03-23 20:29:09 -04003648 process_cpuid();
Len Brown103a8fe2010-10-22 23:53:03 -04003649
Len Brown103a8fe2010-10-22 23:53:03 -04003650
Len Brownd8af6f52015-02-10 01:56:38 -05003651 if (debug)
Len Brown7f5c2582015-12-01 01:36:39 -05003652 for_all_cpus(print_hwp, ODD_COUNTERS);
3653
3654 if (debug)
Len Brown889facb2012-11-08 00:48:57 -05003655 for_all_cpus(print_epb, ODD_COUNTERS);
3656
Len Brownd8af6f52015-02-10 01:56:38 -05003657 if (debug)
Len Brown3a9a9412014-08-15 02:39:52 -04003658 for_all_cpus(print_perf_limit, ODD_COUNTERS);
3659
Len Brownd8af6f52015-02-10 01:56:38 -05003660 if (debug)
Len Brown889facb2012-11-08 00:48:57 -05003661 for_all_cpus(print_rapl, ODD_COUNTERS);
3662
3663 for_all_cpus(set_temperature_target, ODD_COUNTERS);
3664
Len Brownd8af6f52015-02-10 01:56:38 -05003665 if (debug)
Len Brown889facb2012-11-08 00:48:57 -05003666 for_all_cpus(print_thermal, ODD_COUNTERS);
Len Brown5a634262016-04-06 17:15:55 -04003667
3668 if (debug && do_irtl_snb)
3669 print_irtl();
Len Brown103a8fe2010-10-22 23:53:03 -04003670}
3671
3672int fork_it(char **argv)
3673{
Len Brown103a8fe2010-10-22 23:53:03 -04003674 pid_t child_pid;
Len Brownd91bb172012-11-01 00:08:19 -04003675 int status;
Len Brownd15cf7c2012-06-03 23:24:00 -04003676
Len Brownd91bb172012-11-01 00:08:19 -04003677 status = for_all_cpus(get_counters, EVEN_COUNTERS);
3678 if (status)
3679 exit(status);
Len Brownc98d5d92012-06-04 00:56:40 -04003680 /* clear affinity side-effect of get_counters() */
3681 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
Len Brown103a8fe2010-10-22 23:53:03 -04003682 gettimeofday(&tv_even, (struct timezone *)NULL);
3683
3684 child_pid = fork();
3685 if (!child_pid) {
3686 /* child */
3687 execvp(argv[0], argv);
3688 } else {
Len Brown103a8fe2010-10-22 23:53:03 -04003689
3690 /* parent */
Josh Triplettb2c95d92013-08-20 17:20:18 -07003691 if (child_pid == -1)
3692 err(1, "fork");
Len Brown103a8fe2010-10-22 23:53:03 -04003693
3694 signal(SIGINT, SIG_IGN);
3695 signal(SIGQUIT, SIG_IGN);
Josh Triplettb2c95d92013-08-20 17:20:18 -07003696 if (waitpid(child_pid, &status, 0) == -1)
3697 err(status, "waitpid");
Len Brown103a8fe2010-10-22 23:53:03 -04003698 }
Len Brownc98d5d92012-06-04 00:56:40 -04003699 /*
3700 * n.b. fork_it() does not check for errors from for_all_cpus()
3701 * because re-starting is problematic when forking
3702 */
3703 for_all_cpus(get_counters, ODD_COUNTERS);
Len Brown103a8fe2010-10-22 23:53:03 -04003704 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04003705 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04003706 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
3707 fprintf(outf, "%s: Counter reset detected\n", progname);
3708 else {
3709 compute_average(EVEN_COUNTERS);
3710 format_all_counters(EVEN_COUNTERS);
3711 }
Len Brown103a8fe2010-10-22 23:53:03 -04003712
Len Brownb7d8c142016-02-13 23:36:17 -05003713 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
3714
3715 flush_output_stderr();
Len Brown103a8fe2010-10-22 23:53:03 -04003716
Len Brownd91bb172012-11-01 00:08:19 -04003717 return status;
Len Brown103a8fe2010-10-22 23:53:03 -04003718}
3719
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003720int get_and_dump_counters(void)
3721{
3722 int status;
3723
3724 status = for_all_cpus(get_counters, ODD_COUNTERS);
3725 if (status)
3726 return status;
3727
3728 status = for_all_cpus(dump_counters, ODD_COUNTERS);
3729 if (status)
3730 return status;
3731
Len Brownb7d8c142016-02-13 23:36:17 -05003732 flush_output_stdout();
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003733
3734 return status;
3735}
3736
Len Brownd8af6f52015-02-10 01:56:38 -05003737void print_version() {
Len Brown3d109de2016-04-22 23:24:27 -04003738 fprintf(outf, "turbostat version 4.14 22 Apr 2016"
Len Brownd8af6f52015-02-10 01:56:38 -05003739 " - Len Brown <lenb@kernel.org>\n");
3740}
3741
Len Brown103a8fe2010-10-22 23:53:03 -04003742void cmdline(int argc, char **argv)
3743{
3744 int opt;
Len Brownd8af6f52015-02-10 01:56:38 -05003745 int option_index = 0;
3746 static struct option long_options[] = {
3747 {"Counter", required_argument, 0, 'C'},
3748 {"counter", required_argument, 0, 'c'},
3749 {"Dump", no_argument, 0, 'D'},
3750 {"debug", no_argument, 0, 'd'},
3751 {"interval", required_argument, 0, 'i'},
3752 {"help", no_argument, 0, 'h'},
3753 {"Joules", no_argument, 0, 'J'},
3754 {"MSR", required_argument, 0, 'M'},
3755 {"msr", required_argument, 0, 'm'},
Len Brownb7d8c142016-02-13 23:36:17 -05003756 {"out", required_argument, 0, 'o'},
Len Brownd8af6f52015-02-10 01:56:38 -05003757 {"Package", no_argument, 0, 'p'},
3758 {"processor", no_argument, 0, 'p'},
3759 {"Summary", no_argument, 0, 'S'},
3760 {"TCC", required_argument, 0, 'T'},
3761 {"version", no_argument, 0, 'v' },
3762 {0, 0, 0, 0 }
3763 };
Len Brown103a8fe2010-10-22 23:53:03 -04003764
3765 progname = argv[0];
3766
Len Brownb7d8c142016-02-13 23:36:17 -05003767 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v",
Len Brownd8af6f52015-02-10 01:56:38 -05003768 long_options, &option_index)) != -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04003769 switch (opt) {
Len Brownd8af6f52015-02-10 01:56:38 -05003770 case 'C':
3771 sscanf(optarg, "%x", &extra_delta_offset64);
Len Brown103a8fe2010-10-22 23:53:03 -04003772 break;
Len Brownf9240812012-10-06 15:26:31 -04003773 case 'c':
Len Brown8e180f32012-09-22 01:25:08 -04003774 sscanf(optarg, "%x", &extra_delta_offset32);
3775 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003776 case 'D':
3777 dump_only++;
Len Brown8e180f32012-09-22 01:25:08 -04003778 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003779 case 'd':
3780 debug++;
Len Brown2f32edf2012-09-21 23:45:46 -04003781 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003782 case 'h':
3783 default:
3784 help();
3785 exit(1);
3786 case 'i':
Len Brown2a0609c2016-02-12 22:44:48 -05003787 {
3788 double interval = strtod(optarg, NULL);
3789
3790 if (interval < 0.001) {
Len Brownb7d8c142016-02-13 23:36:17 -05003791 fprintf(outf, "interval %f seconds is too small\n",
Len Brown2a0609c2016-02-12 22:44:48 -05003792 interval);
3793 exit(2);
3794 }
3795
3796 interval_ts.tv_sec = interval;
3797 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
3798 }
Len Brown889facb2012-11-08 00:48:57 -05003799 break;
Dirk Brandewie5c56be92013-12-16 10:23:41 -08003800 case 'J':
3801 rapl_joules++;
3802 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003803 case 'M':
3804 sscanf(optarg, "%x", &extra_msr_offset64);
3805 break;
3806 case 'm':
3807 sscanf(optarg, "%x", &extra_msr_offset32);
3808 break;
Len Brownb7d8c142016-02-13 23:36:17 -05003809 case 'o':
3810 outf = fopen_or_die(optarg, "w");
3811 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003812 case 'P':
3813 show_pkg_only++;
3814 break;
3815 case 'p':
3816 show_core_only++;
3817 break;
3818 case 'S':
3819 summary_only++;
3820 break;
3821 case 'T':
3822 tcc_activation_temp_override = atoi(optarg);
3823 break;
3824 case 'v':
3825 print_version();
3826 exit(0);
3827 break;
Len Brown103a8fe2010-10-22 23:53:03 -04003828 }
3829 }
3830}
3831
3832int main(int argc, char **argv)
3833{
Len Brownb7d8c142016-02-13 23:36:17 -05003834 outf = stderr;
3835
Len Brown103a8fe2010-10-22 23:53:03 -04003836 cmdline(argc, argv);
3837
Len Brownd8af6f52015-02-10 01:56:38 -05003838 if (debug)
3839 print_version();
Len Brown103a8fe2010-10-22 23:53:03 -04003840
3841 turbostat_init();
3842
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003843 /* dump counters and exit */
3844 if (dump_only)
3845 return get_and_dump_counters();
3846
Len Brown103a8fe2010-10-22 23:53:03 -04003847 /*
3848 * if any params left, it must be a command to fork
3849 */
3850 if (argc - optind)
3851 return fork_it(argv + optind);
3852 else
3853 turbostat_loop();
3854
3855 return 0;
3856}