blob: 89c31e90a85e533fc46aca5f9163b307ebae04ae [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 Brown869ce69e2016-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 Brownee7e38e2015-02-09 23:39:45 -05001297
Len Browna2b7b742015-09-26 00:12:38 -04001298
1299static void
1300calculate_tsc_tweak()
1301{
Len Browna2b7b742015-09-26 00:12:38 -04001302 tsc_tweak = base_hz / tsc_hz;
1303}
1304
Len Brownfcd17212015-03-23 20:29:09 -04001305static void
1306dump_nhm_platform_info(void)
Len Brown103a8fe2010-10-22 23:53:03 -04001307{
1308 unsigned long long msr;
1309 unsigned int ratio;
1310
Len Brownec0adc52015-11-12 02:42:31 -05001311 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown103a8fe2010-10-22 23:53:03 -04001312
Len Brownb7d8c142016-02-13 23:36:17 -05001313 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001314
Len Brown103a8fe2010-10-22 23:53:03 -04001315 ratio = (msr >> 40) & 0xFF;
Len Brownb7d8c142016-02-13 23:36:17 -05001316 fprintf(outf, "%d * %.0f = %.0f MHz max efficiency frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001317 ratio, bclk, ratio * bclk);
1318
1319 ratio = (msr >> 8) & 0xFF;
Len Brownb7d8c142016-02-13 23:36:17 -05001320 fprintf(outf, "%d * %.0f = %.0f MHz base frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001321 ratio, bclk, ratio * bclk);
1322
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001323 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001324 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
Len Brownbfae2052015-06-17 12:27:21 -04001325 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
Len Brown67920412013-01-31 15:22:15 -05001326
Len Brownfcd17212015-03-23 20:29:09 -04001327 return;
1328}
1329
1330static void
1331dump_hsw_turbo_ratio_limits(void)
1332{
1333 unsigned long long msr;
1334 unsigned int ratio;
1335
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001336 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001337
Len Brownb7d8c142016-02-13 23:36:17 -05001338 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001339
1340 ratio = (msr >> 8) & 0xFF;
1341 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001342 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 18 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001343 ratio, bclk, ratio * bclk);
1344
1345 ratio = (msr >> 0) & 0xFF;
1346 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001347 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 17 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001348 ratio, bclk, ratio * bclk);
1349 return;
1350}
1351
1352static void
1353dump_ivt_turbo_ratio_limits(void)
1354{
1355 unsigned long long msr;
1356 unsigned int ratio;
Len Brown6574a5d2012-09-21 00:01:31 -04001357
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001358 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001359
Len Brownb7d8c142016-02-13 23:36:17 -05001360 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001361
1362 ratio = (msr >> 56) & 0xFF;
1363 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001364 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001365 ratio, bclk, ratio * bclk);
1366
1367 ratio = (msr >> 48) & 0xFF;
1368 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001369 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001370 ratio, bclk, ratio * bclk);
1371
1372 ratio = (msr >> 40) & 0xFF;
1373 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001374 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001375 ratio, bclk, ratio * bclk);
1376
1377 ratio = (msr >> 32) & 0xFF;
1378 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001379 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001380 ratio, bclk, ratio * bclk);
1381
1382 ratio = (msr >> 24) & 0xFF;
1383 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001384 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001385 ratio, bclk, ratio * bclk);
1386
1387 ratio = (msr >> 16) & 0xFF;
1388 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001389 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001390 ratio, bclk, ratio * bclk);
1391
1392 ratio = (msr >> 8) & 0xFF;
1393 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001394 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001395 ratio, bclk, ratio * bclk);
1396
1397 ratio = (msr >> 0) & 0xFF;
1398 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001399 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001400 ratio, bclk, ratio * bclk);
Len Brownfcd17212015-03-23 20:29:09 -04001401 return;
1402}
Len Brown6574a5d2012-09-21 00:01:31 -04001403
Len Brownfcd17212015-03-23 20:29:09 -04001404static void
1405dump_nhm_turbo_ratio_limits(void)
1406{
1407 unsigned long long msr;
1408 unsigned int ratio;
Len Brown103a8fe2010-10-22 23:53:03 -04001409
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001410 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Len Brown103a8fe2010-10-22 23:53:03 -04001411
Len Brownb7d8c142016-02-13 23:36:17 -05001412 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001413
1414 ratio = (msr >> 56) & 0xFF;
1415 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001416 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001417 ratio, bclk, ratio * bclk);
1418
1419 ratio = (msr >> 48) & 0xFF;
1420 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001421 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001422 ratio, bclk, ratio * bclk);
1423
1424 ratio = (msr >> 40) & 0xFF;
1425 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001426 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001427 ratio, bclk, ratio * bclk);
1428
1429 ratio = (msr >> 32) & 0xFF;
1430 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001431 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001432 ratio, bclk, ratio * bclk);
1433
Len Brown103a8fe2010-10-22 23:53:03 -04001434 ratio = (msr >> 24) & 0xFF;
1435 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001436 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001437 ratio, bclk, ratio * bclk);
1438
1439 ratio = (msr >> 16) & 0xFF;
1440 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001441 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 3 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001442 ratio, bclk, ratio * bclk);
1443
1444 ratio = (msr >> 8) & 0xFF;
1445 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001446 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 2 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001447 ratio, bclk, ratio * bclk);
1448
1449 ratio = (msr >> 0) & 0xFF;
1450 if (ratio)
Len Brownb7d8c142016-02-13 23:36:17 -05001451 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001452 ratio, bclk, ratio * bclk);
Len Brownfcd17212015-03-23 20:29:09 -04001453 return;
1454}
Len Brown3a9a9412014-08-15 02:39:52 -04001455
Len Brownfcd17212015-03-23 20:29:09 -04001456static void
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001457dump_knl_turbo_ratio_limits(void)
1458{
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001459 const unsigned int buckets_no = 7;
1460
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001461 unsigned long long msr;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001462 int delta_cores, delta_ratio;
1463 int i, b_nr;
1464 unsigned int cores[buckets_no];
1465 unsigned int ratio[buckets_no];
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001466
Srinivas Pandruvadaebf59262016-07-06 16:07:56 -07001467 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001468
Len Brownb7d8c142016-02-13 23:36:17 -05001469 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
Len Brownbfae2052015-06-17 12:27:21 -04001470 base_cpu, msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001471
1472 /**
1473 * Turbo encoding in KNL is as follows:
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001474 * [0] -- Reserved
1475 * [7:1] -- Base value of number of active cores of bucket 1.
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001476 * [15:8] -- Base value of freq ratio of bucket 1.
1477 * [20:16] -- +ve delta of number of active cores of bucket 2.
1478 * i.e. active cores of bucket 2 =
1479 * active cores of bucket 1 + delta
1480 * [23:21] -- Negative delta of freq ratio of bucket 2.
1481 * i.e. freq ratio of bucket 2 =
1482 * freq ratio of bucket 1 - delta
1483 * [28:24]-- +ve delta of number of active cores of bucket 3.
1484 * [31:29]-- -ve delta of freq ratio of bucket 3.
1485 * [36:32]-- +ve delta of number of active cores of bucket 4.
1486 * [39:37]-- -ve delta of freq ratio of bucket 4.
1487 * [44:40]-- +ve delta of number of active cores of bucket 5.
1488 * [47:45]-- -ve delta of freq ratio of bucket 5.
1489 * [52:48]-- +ve delta of number of active cores of bucket 6.
1490 * [55:53]-- -ve delta of freq ratio of bucket 6.
1491 * [60:56]-- +ve delta of number of active cores of bucket 7.
1492 * [63:61]-- -ve delta of freq ratio of bucket 7.
1493 */
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001494
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001495 b_nr = 0;
1496 cores[b_nr] = (msr & 0xFF) >> 1;
1497 ratio[b_nr] = (msr >> 8) & 0xFF;
1498
1499 for (i = 16; i < 64; i += 8) {
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001500 delta_cores = (msr >> i) & 0x1F;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001501 delta_ratio = (msr >> (i + 5)) & 0x7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001502
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001503 cores[b_nr + 1] = cores[b_nr] + delta_cores;
1504 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
1505 b_nr++;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001506 }
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001507
1508 for (i = buckets_no - 1; i >= 0; i--)
1509 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
Len Brownb7d8c142016-02-13 23:36:17 -05001510 fprintf(outf,
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001511 "%d * %.0f = %.0f MHz max turbo %d active cores\n",
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001512 ratio[i], bclk, ratio[i] * bclk, cores[i]);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001513}
1514
1515static void
Len Brownfcd17212015-03-23 20:29:09 -04001516dump_nhm_cst_cfg(void)
1517{
1518 unsigned long long msr;
1519
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001520 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001521
1522#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
1523#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
1524
Len Brownb7d8c142016-02-13 23:36:17 -05001525 fprintf(outf, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001526
Len Brownb7d8c142016-02-13 23:36:17 -05001527 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
Len Brownfcd17212015-03-23 20:29:09 -04001528 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1529 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1530 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1531 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1532 (msr & (1 << 15)) ? "" : "UN",
Len Brown6c34f162016-03-13 03:21:22 -04001533 (unsigned int)msr & 0xF,
Len Brownfcd17212015-03-23 20:29:09 -04001534 pkg_cstate_limit_strings[pkg_cstate_limit]);
1535 return;
Len Brown103a8fe2010-10-22 23:53:03 -04001536}
1537
Len Brown6fb31432015-06-17 16:23:45 -04001538static void
1539dump_config_tdp(void)
1540{
1541 unsigned long long msr;
1542
1543 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001544 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001545 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
Len Brown6fb31432015-06-17 16:23:45 -04001546
1547 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001548 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001549 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001550 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1551 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1552 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1553 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001554 }
Len Brownb7d8c142016-02-13 23:36:17 -05001555 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001556
1557 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001558 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001559 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001560 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1561 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1562 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1563 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001564 }
Len Brownb7d8c142016-02-13 23:36:17 -05001565 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001566
1567 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001568 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001569 if ((msr) & 0x3)
Len Brownb7d8c142016-02-13 23:36:17 -05001570 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
1571 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1572 fprintf(outf, ")\n");
Len Brown36229892016-02-26 20:51:02 -05001573
Len Brown6fb31432015-06-17 16:23:45 -04001574 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001575 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001576 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
Len Brownb7d8c142016-02-13 23:36:17 -05001577 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1578 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001579}
Len Brown5a634262016-04-06 17:15:55 -04001580
1581unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
1582
1583void print_irtl(void)
1584{
1585 unsigned long long msr;
1586
1587 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
1588 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
1589 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1590 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1591
1592 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
1593 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
1594 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1595 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1596
1597 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
1598 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
1599 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1600 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1601
1602 if (!do_irtl_hsw)
1603 return;
1604
1605 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
1606 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
1607 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1608 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1609
1610 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
1611 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
1612 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1613 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1614
1615 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
1616 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
1617 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
1618 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
1619
1620}
Len Brown36229892016-02-26 20:51:02 -05001621void free_fd_percpu(void)
1622{
1623 int i;
1624
Mika Westerberg01a67ad2016-04-22 11:13:23 +03001625 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
Len Brown36229892016-02-26 20:51:02 -05001626 if (fd_percpu[i] != 0)
1627 close(fd_percpu[i]);
1628 }
1629
1630 free(fd_percpu);
Len Brown6fb31432015-06-17 16:23:45 -04001631}
1632
Len Brownc98d5d92012-06-04 00:56:40 -04001633void free_all_buffers(void)
Len Brown103a8fe2010-10-22 23:53:03 -04001634{
Len Brownc98d5d92012-06-04 00:56:40 -04001635 CPU_FREE(cpu_present_set);
1636 cpu_present_set = NULL;
Len Brown36229892016-02-26 20:51:02 -05001637 cpu_present_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001638
Len Brownc98d5d92012-06-04 00:56:40 -04001639 CPU_FREE(cpu_affinity_set);
1640 cpu_affinity_set = NULL;
1641 cpu_affinity_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001642
Len Brownc98d5d92012-06-04 00:56:40 -04001643 free(thread_even);
1644 free(core_even);
1645 free(package_even);
1646
1647 thread_even = NULL;
1648 core_even = NULL;
1649 package_even = NULL;
1650
1651 free(thread_odd);
1652 free(core_odd);
1653 free(package_odd);
1654
1655 thread_odd = NULL;
1656 core_odd = NULL;
1657 package_odd = NULL;
1658
1659 free(output_buffer);
1660 output_buffer = NULL;
1661 outp = NULL;
Len Brown36229892016-02-26 20:51:02 -05001662
1663 free_fd_percpu();
Len Brown562a2d32016-02-26 23:48:05 -05001664
1665 free(irq_column_2_cpu);
1666 free(irqs_per_cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001667}
1668
Len Brownc98d5d92012-06-04 00:56:40 -04001669/*
Josh Triplett57a42a32013-08-20 17:20:17 -07001670 * Open a file, and exit on failure
1671 */
1672FILE *fopen_or_die(const char *path, const char *mode)
1673{
Len Brownb7d8c142016-02-13 23:36:17 -05001674 FILE *filep = fopen(path, mode);
Josh Triplettb2c95d92013-08-20 17:20:18 -07001675 if (!filep)
1676 err(1, "%s: open failed", path);
Josh Triplett57a42a32013-08-20 17:20:17 -07001677 return filep;
1678}
1679
1680/*
Josh Triplett95aebc42013-08-20 17:20:16 -07001681 * Parse a file containing a single int.
1682 */
1683int parse_int_file(const char *fmt, ...)
1684{
1685 va_list args;
1686 char path[PATH_MAX];
1687 FILE *filep;
1688 int value;
1689
1690 va_start(args, fmt);
1691 vsnprintf(path, sizeof(path), fmt, args);
1692 va_end(args);
Josh Triplett57a42a32013-08-20 17:20:17 -07001693 filep = fopen_or_die(path, "r");
Josh Triplettb2c95d92013-08-20 17:20:18 -07001694 if (fscanf(filep, "%d", &value) != 1)
1695 err(1, "%s: failed to parse number from file", path);
Josh Triplett95aebc42013-08-20 17:20:16 -07001696 fclose(filep);
1697 return value;
1698}
1699
1700/*
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001701 * get_cpu_position_in_core(cpu)
1702 * return the position of the CPU among its HT siblings in the core
1703 * return -1 if the sibling is not in list
Len Brownc98d5d92012-06-04 00:56:40 -04001704 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001705int get_cpu_position_in_core(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04001706{
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001707 char path[64];
1708 FILE *filep;
1709 int this_cpu;
1710 char character;
1711 int i;
1712
1713 sprintf(path,
1714 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
1715 cpu);
1716 filep = fopen(path, "r");
1717 if (filep == NULL) {
1718 perror(path);
1719 exit(1);
1720 }
1721
1722 for (i = 0; i < topo.num_threads_per_core; i++) {
1723 fscanf(filep, "%d", &this_cpu);
1724 if (this_cpu == cpu) {
1725 fclose(filep);
1726 return i;
1727 }
1728
1729 /* Account for no separator after last thread*/
1730 if (i != (topo.num_threads_per_core - 1))
1731 fscanf(filep, "%c", &character);
1732 }
1733
1734 fclose(filep);
1735 return -1;
Len Brown103a8fe2010-10-22 23:53:03 -04001736}
1737
Len Brownc98d5d92012-06-04 00:56:40 -04001738/*
1739 * cpu_is_first_core_in_package(cpu)
1740 * return 1 if given CPU is 1st core in package
1741 */
1742int cpu_is_first_core_in_package(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04001743{
Josh Triplett95aebc42013-08-20 17:20:16 -07001744 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001745}
1746
1747int get_physical_package_id(int cpu)
1748{
Josh Triplett95aebc42013-08-20 17:20:16 -07001749 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001750}
1751
1752int get_core_id(int cpu)
1753{
Josh Triplett95aebc42013-08-20 17:20:16 -07001754 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04001755}
1756
Len Brownc98d5d92012-06-04 00:56:40 -04001757int get_num_ht_siblings(int cpu)
1758{
1759 char path[80];
1760 FILE *filep;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001761 int sib1;
1762 int matches = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001763 char character;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001764 char str[100];
1765 char *ch;
Len Brownc98d5d92012-06-04 00:56:40 -04001766
1767 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
Josh Triplett57a42a32013-08-20 17:20:17 -07001768 filep = fopen_or_die(path, "r");
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001769
Len Brownc98d5d92012-06-04 00:56:40 -04001770 /*
1771 * file format:
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001772 * A ',' separated or '-' separated set of numbers
1773 * (eg 1-2 or 1,3,4,5)
Len Brownc98d5d92012-06-04 00:56:40 -04001774 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001775 fscanf(filep, "%d%c\n", &sib1, &character);
1776 fseek(filep, 0, SEEK_SET);
1777 fgets(str, 100, filep);
1778 ch = strchr(str, character);
1779 while (ch != NULL) {
1780 matches++;
1781 ch = strchr(ch+1, character);
1782 }
Len Brownc98d5d92012-06-04 00:56:40 -04001783
1784 fclose(filep);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07001785 return matches+1;
Len Brownc98d5d92012-06-04 00:56:40 -04001786}
1787
Len Brown103a8fe2010-10-22 23:53:03 -04001788/*
Len Brownc98d5d92012-06-04 00:56:40 -04001789 * run func(thread, core, package) in topology order
1790 * skip non-present cpus
Len Brown103a8fe2010-10-22 23:53:03 -04001791 */
1792
Len Brownc98d5d92012-06-04 00:56:40 -04001793int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
1794 struct pkg_data *, struct thread_data *, struct core_data *,
1795 struct pkg_data *), struct thread_data *thread_base,
1796 struct core_data *core_base, struct pkg_data *pkg_base,
1797 struct thread_data *thread_base2, struct core_data *core_base2,
1798 struct pkg_data *pkg_base2)
1799{
1800 int retval, pkg_no, core_no, thread_no;
1801
1802 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
1803 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
1804 for (thread_no = 0; thread_no <
1805 topo.num_threads_per_core; ++thread_no) {
1806 struct thread_data *t, *t2;
1807 struct core_data *c, *c2;
1808 struct pkg_data *p, *p2;
1809
1810 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
1811
1812 if (cpu_is_not_present(t->cpu_id))
1813 continue;
1814
1815 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no);
1816
1817 c = GET_CORE(core_base, core_no, pkg_no);
1818 c2 = GET_CORE(core_base2, core_no, pkg_no);
1819
1820 p = GET_PKG(pkg_base, pkg_no);
1821 p2 = GET_PKG(pkg_base2, pkg_no);
1822
1823 retval = func(t, c, p, t2, c2, p2);
1824 if (retval)
1825 return retval;
1826 }
1827 }
1828 }
1829 return 0;
1830}
1831
1832/*
1833 * run func(cpu) on every cpu in /proc/stat
1834 * return max_cpu number
1835 */
1836int for_all_proc_cpus(int (func)(int))
Len Brown103a8fe2010-10-22 23:53:03 -04001837{
1838 FILE *fp;
Len Brownc98d5d92012-06-04 00:56:40 -04001839 int cpu_num;
Len Brown103a8fe2010-10-22 23:53:03 -04001840 int retval;
1841
Josh Triplett57a42a32013-08-20 17:20:17 -07001842 fp = fopen_or_die(proc_stat, "r");
Len Brown103a8fe2010-10-22 23:53:03 -04001843
1844 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
Josh Triplettb2c95d92013-08-20 17:20:18 -07001845 if (retval != 0)
1846 err(1, "%s: failed to parse format", proc_stat);
Len Brown103a8fe2010-10-22 23:53:03 -04001847
Len Brownc98d5d92012-06-04 00:56:40 -04001848 while (1) {
1849 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 -04001850 if (retval != 1)
1851 break;
1852
Len Brownc98d5d92012-06-04 00:56:40 -04001853 retval = func(cpu_num);
1854 if (retval) {
1855 fclose(fp);
1856 return(retval);
1857 }
Len Brown103a8fe2010-10-22 23:53:03 -04001858 }
1859 fclose(fp);
Len Brownc98d5d92012-06-04 00:56:40 -04001860 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001861}
1862
1863void re_initialize(void)
1864{
Len Brownc98d5d92012-06-04 00:56:40 -04001865 free_all_buffers();
1866 setup_all_buffers();
1867 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
Len Brown103a8fe2010-10-22 23:53:03 -04001868}
1869
Len Brownc98d5d92012-06-04 00:56:40 -04001870
Len Brown103a8fe2010-10-22 23:53:03 -04001871/*
Len Brownc98d5d92012-06-04 00:56:40 -04001872 * count_cpus()
1873 * remember the last one seen, it will be the max
Len Brown103a8fe2010-10-22 23:53:03 -04001874 */
Len Brownc98d5d92012-06-04 00:56:40 -04001875int count_cpus(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04001876{
Len Brownc98d5d92012-06-04 00:56:40 -04001877 if (topo.max_cpu_num < cpu)
1878 topo.max_cpu_num = cpu;
Len Brown103a8fe2010-10-22 23:53:03 -04001879
Len Brownc98d5d92012-06-04 00:56:40 -04001880 topo.num_cpus += 1;
1881 return 0;
1882}
1883int mark_cpu_present(int cpu)
1884{
1885 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brown15aaa342012-03-29 22:19:58 -04001886 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04001887}
1888
Len Brown562a2d32016-02-26 23:48:05 -05001889/*
1890 * snapshot_proc_interrupts()
1891 *
1892 * read and record summary of /proc/interrupts
1893 *
1894 * return 1 if config change requires a restart, else return 0
1895 */
1896int snapshot_proc_interrupts(void)
1897{
1898 static FILE *fp;
1899 int column, retval;
1900
1901 if (fp == NULL)
1902 fp = fopen_or_die("/proc/interrupts", "r");
1903 else
1904 rewind(fp);
1905
1906 /* read 1st line of /proc/interrupts to get cpu* name for each column */
1907 for (column = 0; column < topo.num_cpus; ++column) {
1908 int cpu_number;
1909
1910 retval = fscanf(fp, " CPU%d", &cpu_number);
1911 if (retval != 1)
1912 break;
1913
1914 if (cpu_number > topo.max_cpu_num) {
1915 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
1916 return 1;
1917 }
1918
1919 irq_column_2_cpu[column] = cpu_number;
1920 irqs_per_cpu[cpu_number] = 0;
1921 }
1922
1923 /* read /proc/interrupt count lines and sum up irqs per cpu */
1924 while (1) {
1925 int column;
1926 char buf[64];
1927
1928 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
1929 if (retval != 1)
1930 break;
1931
1932 /* read the count per cpu */
1933 for (column = 0; column < topo.num_cpus; ++column) {
1934
1935 int cpu_number, irq_count;
1936
1937 retval = fscanf(fp, " %d", &irq_count);
1938 if (retval != 1)
1939 break;
1940
1941 cpu_number = irq_column_2_cpu[column];
1942 irqs_per_cpu[cpu_number] += irq_count;
1943
1944 }
1945
1946 while (getc(fp) != '\n')
1947 ; /* flush interrupt description */
1948
1949 }
1950 return 0;
1951}
Len Brown27d47352016-02-27 00:37:54 -05001952/*
Len Brownfdf676e2016-02-27 01:28:12 -05001953 * snapshot_gfx_rc6_ms()
1954 *
1955 * record snapshot of
1956 * /sys/class/drm/card0/power/rc6_residency_ms
1957 *
1958 * return 1 if config change requires a restart, else return 0
1959 */
1960int snapshot_gfx_rc6_ms(void)
1961{
1962 FILE *fp;
1963 int retval;
1964
1965 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
1966
1967 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
1968 if (retval != 1)
1969 err(1, "GFX rc6");
1970
1971 fclose(fp);
1972
1973 return 0;
1974}
1975/*
Len Brown27d47352016-02-27 00:37:54 -05001976 * snapshot_gfx_mhz()
1977 *
1978 * record snapshot of
1979 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
1980 *
1981 * return 1 if config change requires a restart, else return 0
1982 */
1983int snapshot_gfx_mhz(void)
1984{
1985 static FILE *fp;
1986 int retval;
1987
1988 if (fp == NULL)
1989 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
1990 else
1991 rewind(fp);
1992
1993 retval = fscanf(fp, "%d", &gfx_cur_mhz);
1994 if (retval != 1)
1995 err(1, "GFX MHz");
1996
1997 return 0;
1998}
Len Brown562a2d32016-02-26 23:48:05 -05001999
2000/*
2001 * snapshot /proc and /sys files
2002 *
2003 * return 1 if configuration restart needed, else return 0
2004 */
2005int snapshot_proc_sysfs_files(void)
2006{
2007 if (snapshot_proc_interrupts())
2008 return 1;
2009
Len Brownfdf676e2016-02-27 01:28:12 -05002010 if (do_gfx_rc6_ms)
2011 snapshot_gfx_rc6_ms();
2012
Len Brown27d47352016-02-27 00:37:54 -05002013 if (do_gfx_mhz)
2014 snapshot_gfx_mhz();
2015
Len Brown562a2d32016-02-26 23:48:05 -05002016 return 0;
2017}
2018
Len Brown103a8fe2010-10-22 23:53:03 -04002019void turbostat_loop()
2020{
Len Brownc98d5d92012-06-04 00:56:40 -04002021 int retval;
Len Browne52966c2012-11-08 22:38:05 -05002022 int restarted = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04002023
Len Brown103a8fe2010-10-22 23:53:03 -04002024restart:
Len Browne52966c2012-11-08 22:38:05 -05002025 restarted++;
2026
Len Brown562a2d32016-02-26 23:48:05 -05002027 snapshot_proc_sysfs_files();
Len Brownc98d5d92012-06-04 00:56:40 -04002028 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002029 if (retval < -1) {
2030 exit(retval);
2031 } else if (retval == -1) {
Len Browne52966c2012-11-08 22:38:05 -05002032 if (restarted > 1) {
2033 exit(retval);
2034 }
Len Brownc98d5d92012-06-04 00:56:40 -04002035 re_initialize();
2036 goto restart;
2037 }
Len Browne52966c2012-11-08 22:38:05 -05002038 restarted = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002039 gettimeofday(&tv_even, (struct timezone *)NULL);
2040
2041 while (1) {
Len Brownc98d5d92012-06-04 00:56:40 -04002042 if (for_all_proc_cpus(cpu_is_not_present)) {
Len Brown103a8fe2010-10-22 23:53:03 -04002043 re_initialize();
2044 goto restart;
2045 }
Len Brown2a0609c2016-02-12 22:44:48 -05002046 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002047 if (snapshot_proc_sysfs_files())
2048 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002049 retval = for_all_cpus(get_counters, ODD_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002050 if (retval < -1) {
2051 exit(retval);
2052 } else if (retval == -1) {
Len Brown15aaa342012-03-29 22:19:58 -04002053 re_initialize();
2054 goto restart;
2055 }
Len Brown103a8fe2010-10-22 23:53:03 -04002056 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002057 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002058 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
2059 re_initialize();
2060 goto restart;
2061 }
Len Brownc98d5d92012-06-04 00:56:40 -04002062 compute_average(EVEN_COUNTERS);
2063 format_all_counters(EVEN_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002064 flush_output_stdout();
Len Brown2a0609c2016-02-12 22:44:48 -05002065 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002066 if (snapshot_proc_sysfs_files())
2067 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002068 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002069 if (retval < -1) {
2070 exit(retval);
2071 } else if (retval == -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04002072 re_initialize();
2073 goto restart;
2074 }
Len Brown103a8fe2010-10-22 23:53:03 -04002075 gettimeofday(&tv_even, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002076 timersub(&tv_even, &tv_odd, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002077 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
2078 re_initialize();
2079 goto restart;
2080 }
Len Brownc98d5d92012-06-04 00:56:40 -04002081 compute_average(ODD_COUNTERS);
2082 format_all_counters(ODD_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002083 flush_output_stdout();
Len Brown103a8fe2010-10-22 23:53:03 -04002084 }
2085}
2086
2087void check_dev_msr()
2088{
2089 struct stat sb;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002090 char pathname[32];
Len Brown103a8fe2010-10-22 23:53:03 -04002091
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002092 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2093 if (stat(pathname, &sb))
Len Browna21d38c2015-03-24 16:37:35 -04002094 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
2095 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
Len Brown103a8fe2010-10-22 23:53:03 -04002096}
2097
Len Brown98481e72014-08-15 00:36:50 -04002098void check_permissions()
Len Brown103a8fe2010-10-22 23:53:03 -04002099{
Len Brown98481e72014-08-15 00:36:50 -04002100 struct __user_cap_header_struct cap_header_data;
2101 cap_user_header_t cap_header = &cap_header_data;
2102 struct __user_cap_data_struct cap_data_data;
2103 cap_user_data_t cap_data = &cap_data_data;
2104 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
2105 int do_exit = 0;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002106 char pathname[32];
Len Brown98481e72014-08-15 00:36:50 -04002107
2108 /* check for CAP_SYS_RAWIO */
2109 cap_header->pid = getpid();
2110 cap_header->version = _LINUX_CAPABILITY_VERSION;
2111 if (capget(cap_header, cap_data) < 0)
2112 err(-6, "capget(2) failed");
2113
2114 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
2115 do_exit++;
2116 warnx("capget(CAP_SYS_RAWIO) failed,"
2117 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
2118 }
2119
2120 /* test file permissions */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002121 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2122 if (euidaccess(pathname, R_OK)) {
Len Brown98481e72014-08-15 00:36:50 -04002123 do_exit++;
2124 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
2125 }
2126
2127 /* if all else fails, thell them to be root */
2128 if (do_exit)
2129 if (getuid() != 0)
Len Brownd7899442015-01-23 00:12:33 -05002130 warnx("... or simply run as root");
Len Brown98481e72014-08-15 00:36:50 -04002131
2132 if (do_exit)
2133 exit(-6);
Len Brown103a8fe2010-10-22 23:53:03 -04002134}
2135
Len Brownd7899442015-01-23 00:12:33 -05002136/*
2137 * NHM adds support for additional MSRs:
2138 *
2139 * MSR_SMI_COUNT 0x00000034
2140 *
Len Brownec0adc52015-11-12 02:42:31 -05002141 * MSR_PLATFORM_INFO 0x000000ce
Len Brownd7899442015-01-23 00:12:33 -05002142 * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2
2143 *
2144 * MSR_PKG_C3_RESIDENCY 0x000003f8
2145 * MSR_PKG_C6_RESIDENCY 0x000003f9
2146 * MSR_CORE_C3_RESIDENCY 0x000003fc
2147 * MSR_CORE_C6_RESIDENCY 0x000003fd
2148 *
Len Brownee7e38e2015-02-09 23:39:45 -05002149 * Side effect:
2150 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL
Len Brownd7899442015-01-23 00:12:33 -05002151 */
Len Brownee7e38e2015-02-09 23:39:45 -05002152int probe_nhm_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04002153{
Len Brownee7e38e2015-02-09 23:39:45 -05002154 unsigned long long msr;
Len Brown21ed5572015-10-19 22:37:40 -04002155 unsigned int base_ratio;
Len Brownee7e38e2015-02-09 23:39:45 -05002156 int *pkg_cstate_limits;
2157
Len Brown103a8fe2010-10-22 23:53:03 -04002158 if (!genuine_intel)
2159 return 0;
2160
2161 if (family != 6)
2162 return 0;
2163
Len Brown21ed5572015-10-19 22:37:40 -04002164 bclk = discover_bclk(family, model);
2165
Len Brown103a8fe2010-10-22 23:53:03 -04002166 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002167 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
2168 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
Len Brown103a8fe2010-10-22 23:53:03 -04002169 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
Len Brown869ce69e2016-06-16 23:22:37 -04002170 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
2171 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
2172 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2173 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
Len Brownee7e38e2015-02-09 23:39:45 -05002174 pkg_cstate_limits = nhm_pkg_cstate_limits;
2175 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002176 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
2177 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */
2178 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2179 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
Len Brownee7e38e2015-02-09 23:39:45 -05002180 pkg_cstate_limits = snb_pkg_cstate_limits;
2181 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002182 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2183 case INTEL_FAM6_HASWELL_X: /* HSX */
2184 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2185 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2186 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2187 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2188 case INTEL_FAM6_BROADWELL_X: /* BDX */
2189 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2190 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2191 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2192 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2193 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2194 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brownee7e38e2015-02-09 23:39:45 -05002195 pkg_cstate_limits = hsw_pkg_cstate_limits;
2196 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002197 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2198 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brownee7e38e2015-02-09 23:39:45 -05002199 pkg_cstate_limits = slv_pkg_cstate_limits;
2200 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002201 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
Len Brownee7e38e2015-02-09 23:39:45 -05002202 pkg_cstate_limits = amt_pkg_cstate_limits;
2203 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002204 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
Len Brownee7e38e2015-02-09 23:39:45 -05002205 pkg_cstate_limits = phi_pkg_cstate_limits;
2206 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002207 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
2208 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Browne4085d52016-04-06 17:15:56 -04002209 pkg_cstate_limits = bxt_pkg_cstate_limits;
2210 break;
Len Brown103a8fe2010-10-22 23:53:03 -04002211 default:
2212 return 0;
2213 }
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002214 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
Len Browne9257f52015-04-01 21:02:57 -04002215 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
Len Brownee7e38e2015-02-09 23:39:45 -05002216
Len Brownec0adc52015-11-12 02:42:31 -05002217 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown21ed5572015-10-19 22:37:40 -04002218 base_ratio = (msr >> 8) & 0xFF;
2219
2220 base_hz = base_ratio * bclk * 1000000;
2221 has_base_hz = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002222 return 1;
Len Brown103a8fe2010-10-22 23:53:03 -04002223}
Len Brownd7899442015-01-23 00:12:33 -05002224int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
2225{
Len Brownd7899442015-01-23 00:12:33 -05002226 switch (model) {
2227 /* Nehalem compatible, but do not include turbo-ratio limit support */
Len Brown869ce69e2016-06-16 23:22:37 -04002228 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2229 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
2230 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
Len Brownd7899442015-01-23 00:12:33 -05002231 return 0;
2232 default:
2233 return 1;
2234 }
2235}
Len Brown6574a5d2012-09-21 00:01:31 -04002236int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
2237{
2238 if (!genuine_intel)
2239 return 0;
2240
2241 if (family != 6)
2242 return 0;
2243
2244 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002245 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2246 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brown6574a5d2012-09-21 00:01:31 -04002247 return 1;
2248 default:
2249 return 0;
2250 }
2251}
Len Brownfcd17212015-03-23 20:29:09 -04002252int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
2253{
2254 if (!genuine_intel)
2255 return 0;
2256
2257 if (family != 6)
2258 return 0;
2259
2260 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002261 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brownfcd17212015-03-23 20:29:09 -04002262 return 1;
2263 default:
2264 return 0;
2265 }
2266}
2267
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002268int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
2269{
2270 if (!genuine_intel)
2271 return 0;
2272
2273 if (family != 6)
2274 return 0;
2275
2276 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002277 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002278 return 1;
2279 default:
2280 return 0;
2281 }
2282}
Len Brown6fb31432015-06-17 16:23:45 -04002283int has_config_tdp(unsigned int family, unsigned int model)
2284{
2285 if (!genuine_intel)
2286 return 0;
2287
2288 if (family != 6)
2289 return 0;
2290
2291 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002292 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2293 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2294 case INTEL_FAM6_HASWELL_X: /* HSX */
2295 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2296 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2297 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2298 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2299 case INTEL_FAM6_BROADWELL_X: /* BDX */
2300 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2301 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2302 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2303 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2304 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2305 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brown6fb31432015-06-17 16:23:45 -04002306
Len Brown869ce69e2016-06-16 23:22:37 -04002307 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown6fb31432015-06-17 16:23:45 -04002308 return 1;
2309 default:
2310 return 0;
2311 }
2312}
2313
Len Brownfcd17212015-03-23 20:29:09 -04002314static void
Colin Ian King1b693172016-03-02 13:50:25 +00002315dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
Len Brownfcd17212015-03-23 20:29:09 -04002316{
2317 if (!do_nhm_platform_info)
2318 return;
2319
2320 dump_nhm_platform_info();
2321
2322 if (has_hsw_turbo_ratio_limit(family, model))
2323 dump_hsw_turbo_ratio_limits();
2324
2325 if (has_ivt_turbo_ratio_limit(family, model))
2326 dump_ivt_turbo_ratio_limits();
2327
2328 if (has_nhm_turbo_ratio_limit(family, model))
2329 dump_nhm_turbo_ratio_limits();
2330
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002331 if (has_knl_turbo_ratio_limit(family, model))
2332 dump_knl_turbo_ratio_limits();
2333
Len Brown6fb31432015-06-17 16:23:45 -04002334 if (has_config_tdp(family, model))
2335 dump_config_tdp();
2336
Len Brownfcd17212015-03-23 20:29:09 -04002337 dump_nhm_cst_cfg();
2338}
2339
Len Brown6574a5d2012-09-21 00:01:31 -04002340
Len Brown889facb2012-11-08 00:48:57 -05002341/*
2342 * print_epb()
2343 * Decode the ENERGY_PERF_BIAS MSR
2344 */
2345int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2346{
2347 unsigned long long msr;
2348 char *epb_string;
2349 int cpu;
2350
2351 if (!has_epb)
2352 return 0;
2353
2354 cpu = t->cpu_id;
2355
2356 /* EPB is per-package */
2357 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2358 return 0;
2359
2360 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002361 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002362 return -1;
2363 }
2364
2365 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
2366 return 0;
2367
Len Browne9be7dd2015-05-26 12:19:37 -04002368 switch (msr & 0xF) {
Len Brown889facb2012-11-08 00:48:57 -05002369 case ENERGY_PERF_BIAS_PERFORMANCE:
2370 epb_string = "performance";
2371 break;
2372 case ENERGY_PERF_BIAS_NORMAL:
2373 epb_string = "balanced";
2374 break;
2375 case ENERGY_PERF_BIAS_POWERSAVE:
2376 epb_string = "powersave";
2377 break;
2378 default:
2379 epb_string = "custom";
2380 break;
2381 }
Len Brownb7d8c142016-02-13 23:36:17 -05002382 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
Len Brown889facb2012-11-08 00:48:57 -05002383
2384 return 0;
2385}
Len Brown7f5c2582015-12-01 01:36:39 -05002386/*
2387 * print_hwp()
2388 * Decode the MSR_HWP_CAPABILITIES
2389 */
2390int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2391{
2392 unsigned long long msr;
2393 int cpu;
2394
2395 if (!has_hwp)
2396 return 0;
2397
2398 cpu = t->cpu_id;
2399
2400 /* MSR_HWP_CAPABILITIES is per-package */
2401 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2402 return 0;
2403
2404 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002405 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown7f5c2582015-12-01 01:36:39 -05002406 return -1;
2407 }
2408
2409 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
2410 return 0;
2411
Len Brownb7d8c142016-02-13 23:36:17 -05002412 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
Len Brown7f5c2582015-12-01 01:36:39 -05002413 cpu, msr, (msr & (1 << 0)) ? "" : "No-");
2414
2415 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
2416 if ((msr & (1 << 0)) == 0)
2417 return 0;
2418
2419 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
2420 return 0;
2421
Len Brownb7d8c142016-02-13 23:36:17 -05002422 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002423 "(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
2424 cpu, msr,
2425 (unsigned int)HWP_HIGHEST_PERF(msr),
2426 (unsigned int)HWP_GUARANTEED_PERF(msr),
2427 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
2428 (unsigned int)HWP_LOWEST_PERF(msr));
2429
2430 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
2431 return 0;
2432
Len Brownb7d8c142016-02-13 23:36:17 -05002433 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002434 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
2435 cpu, msr,
2436 (unsigned int)(((msr) >> 0) & 0xff),
2437 (unsigned int)(((msr) >> 8) & 0xff),
2438 (unsigned int)(((msr) >> 16) & 0xff),
2439 (unsigned int)(((msr) >> 24) & 0xff),
2440 (unsigned int)(((msr) >> 32) & 0xff3),
2441 (unsigned int)(((msr) >> 42) & 0x1));
2442
2443 if (has_hwp_pkg) {
2444 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
2445 return 0;
2446
Len Brownb7d8c142016-02-13 23:36:17 -05002447 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002448 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
2449 cpu, msr,
2450 (unsigned int)(((msr) >> 0) & 0xff),
2451 (unsigned int)(((msr) >> 8) & 0xff),
2452 (unsigned int)(((msr) >> 16) & 0xff),
2453 (unsigned int)(((msr) >> 24) & 0xff),
2454 (unsigned int)(((msr) >> 32) & 0xff3));
2455 }
2456 if (has_hwp_notify) {
2457 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
2458 return 0;
2459
Len Brownb7d8c142016-02-13 23:36:17 -05002460 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002461 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
2462 cpu, msr,
2463 ((msr) & 0x1) ? "EN" : "Dis",
2464 ((msr) & 0x2) ? "EN" : "Dis");
2465 }
2466 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
2467 return 0;
2468
Len Brownb7d8c142016-02-13 23:36:17 -05002469 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002470 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
2471 cpu, msr,
2472 ((msr) & 0x1) ? "" : "No-",
2473 ((msr) & 0x2) ? "" : "No-");
Len Brown889facb2012-11-08 00:48:57 -05002474
2475 return 0;
2476}
2477
Len Brown3a9a9412014-08-15 02:39:52 -04002478/*
2479 * print_perf_limit()
2480 */
2481int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2482{
2483 unsigned long long msr;
2484 int cpu;
2485
2486 cpu = t->cpu_id;
2487
2488 /* per-package */
2489 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2490 return 0;
2491
2492 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002493 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown3a9a9412014-08-15 02:39:52 -04002494 return -1;
2495 }
2496
2497 if (do_core_perf_limit_reasons) {
2498 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05002499 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2500 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
Len Browne33cbe82015-03-13 16:30:57 -04002501 (msr & 1 << 15) ? "bit15, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04002502 (msr & 1 << 14) ? "bit14, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04002503 (msr & 1 << 13) ? "Transitions, " : "",
2504 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
2505 (msr & 1 << 11) ? "PkgPwrL2, " : "",
2506 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2507 (msr & 1 << 9) ? "CorePwr, " : "",
2508 (msr & 1 << 8) ? "Amps, " : "",
2509 (msr & 1 << 6) ? "VR-Therm, " : "",
2510 (msr & 1 << 5) ? "Auto-HWP, " : "",
2511 (msr & 1 << 4) ? "Graphics, " : "",
2512 (msr & 1 << 2) ? "bit2, " : "",
2513 (msr & 1 << 1) ? "ThermStatus, " : "",
2514 (msr & 1 << 0) ? "PROCHOT, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05002515 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 -04002516 (msr & 1 << 31) ? "bit31, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04002517 (msr & 1 << 30) ? "bit30, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04002518 (msr & 1 << 29) ? "Transitions, " : "",
2519 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
2520 (msr & 1 << 27) ? "PkgPwrL2, " : "",
2521 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2522 (msr & 1 << 25) ? "CorePwr, " : "",
2523 (msr & 1 << 24) ? "Amps, " : "",
2524 (msr & 1 << 22) ? "VR-Therm, " : "",
2525 (msr & 1 << 21) ? "Auto-HWP, " : "",
2526 (msr & 1 << 20) ? "Graphics, " : "",
2527 (msr & 1 << 18) ? "bit18, " : "",
2528 (msr & 1 << 17) ? "ThermStatus, " : "",
2529 (msr & 1 << 16) ? "PROCHOT, " : "");
Len Brown3a9a9412014-08-15 02:39:52 -04002530
2531 }
2532 if (do_gfx_perf_limit_reasons) {
2533 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05002534 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2535 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04002536 (msr & 1 << 0) ? "PROCHOT, " : "",
2537 (msr & 1 << 1) ? "ThermStatus, " : "",
2538 (msr & 1 << 4) ? "Graphics, " : "",
2539 (msr & 1 << 6) ? "VR-Therm, " : "",
2540 (msr & 1 << 8) ? "Amps, " : "",
2541 (msr & 1 << 9) ? "GFXPwr, " : "",
2542 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2543 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05002544 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04002545 (msr & 1 << 16) ? "PROCHOT, " : "",
2546 (msr & 1 << 17) ? "ThermStatus, " : "",
2547 (msr & 1 << 20) ? "Graphics, " : "",
2548 (msr & 1 << 22) ? "VR-Therm, " : "",
2549 (msr & 1 << 24) ? "Amps, " : "",
2550 (msr & 1 << 25) ? "GFXPwr, " : "",
2551 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2552 (msr & 1 << 27) ? "PkgPwrL2, " : "");
2553 }
2554 if (do_ring_perf_limit_reasons) {
2555 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05002556 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
2557 fprintf(outf, " (Active: %s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04002558 (msr & 1 << 0) ? "PROCHOT, " : "",
2559 (msr & 1 << 1) ? "ThermStatus, " : "",
2560 (msr & 1 << 6) ? "VR-Therm, " : "",
2561 (msr & 1 << 8) ? "Amps, " : "",
2562 (msr & 1 << 10) ? "PkgPwrL1, " : "",
2563 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05002564 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04002565 (msr & 1 << 16) ? "PROCHOT, " : "",
2566 (msr & 1 << 17) ? "ThermStatus, " : "",
2567 (msr & 1 << 22) ? "VR-Therm, " : "",
2568 (msr & 1 << 24) ? "Amps, " : "",
2569 (msr & 1 << 26) ? "PkgPwrL1, " : "",
2570 (msr & 1 << 27) ? "PkgPwrL2, " : "");
2571 }
2572 return 0;
2573}
2574
Len Brown889facb2012-11-08 00:48:57 -05002575#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
2576#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
2577
Colin Ian King1b693172016-03-02 13:50:25 +00002578double get_tdp(unsigned int model)
Len Brown144b44b2013-11-09 00:30:16 -05002579{
2580 unsigned long long msr;
2581
2582 if (do_rapl & RAPL_PKG_POWER_INFO)
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002583 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
Len Brown144b44b2013-11-09 00:30:16 -05002584 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
2585
2586 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002587 case INTEL_FAM6_ATOM_SILVERMONT1:
2588 case INTEL_FAM6_ATOM_SILVERMONT2:
Len Brown144b44b2013-11-09 00:30:16 -05002589 return 30.0;
2590 default:
2591 return 135.0;
2592 }
2593}
2594
Andrey Semin40ee8e32014-12-05 00:07:00 -05002595/*
2596 * rapl_dram_energy_units_probe()
2597 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
2598 */
2599static double
2600rapl_dram_energy_units_probe(int model, double rapl_energy_units)
2601{
2602 /* only called for genuine_intel, family 6 */
2603
2604 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002605 case INTEL_FAM6_HASWELL_X: /* HSX */
2606 case INTEL_FAM6_BROADWELL_X: /* BDX */
2607 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2608 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Andrey Semin40ee8e32014-12-05 00:07:00 -05002609 return (rapl_dram_energy_units = 15.3 / 1000000);
2610 default:
2611 return (rapl_energy_units);
2612 }
2613}
2614
Len Brown144b44b2013-11-09 00:30:16 -05002615
Len Brown889facb2012-11-08 00:48:57 -05002616/*
2617 * rapl_probe()
2618 *
Len Brown144b44b2013-11-09 00:30:16 -05002619 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
Len Brown889facb2012-11-08 00:48:57 -05002620 */
2621void rapl_probe(unsigned int family, unsigned int model)
2622{
2623 unsigned long long msr;
Len Brown144b44b2013-11-09 00:30:16 -05002624 unsigned int time_unit;
Len Brown889facb2012-11-08 00:48:57 -05002625 double tdp;
2626
2627 if (!genuine_intel)
2628 return;
2629
2630 if (family != 6)
2631 return;
2632
2633 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002634 case INTEL_FAM6_SANDYBRIDGE:
2635 case INTEL_FAM6_IVYBRIDGE:
2636 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2637 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2638 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2639 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2640 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
Len Brown144b44b2013-11-09 00:30:16 -05002641 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
Len Brown889facb2012-11-08 00:48:57 -05002642 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002643 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Browne4085d52016-04-06 17:15:56 -04002644 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
2645 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002646 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2647 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2648 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2649 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04002650 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
2651 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002652 case INTEL_FAM6_HASWELL_X: /* HSX */
2653 case INTEL_FAM6_BROADWELL_X: /* BDX */
2654 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2655 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2656 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown0b2bb692015-03-26 00:50:30 -04002657 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 -05002658 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002659 case INTEL_FAM6_SANDYBRIDGE_X:
2660 case INTEL_FAM6_IVYBRIDGE_X:
Len Brown0b2bb692015-03-26 00:50:30 -04002661 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 -05002662 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002663 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2664 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Jacob Pan91484942016-06-16 09:48:20 -07002665 do_rapl = RAPL_PKG | RAPL_CORES;
Len Brown889facb2012-11-08 00:48:57 -05002666 break;
Len Brown869ce69e2016-06-16 23:22:37 -04002667 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Jacob Pan0f644902016-06-16 09:48:22 -07002668 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;
2669 break;
Len Brown889facb2012-11-08 00:48:57 -05002670 default:
2671 return;
2672 }
2673
2674 /* units on package 0, verify later other packages match */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002675 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
Len Brown889facb2012-11-08 00:48:57 -05002676 return;
2677
2678 rapl_power_units = 1.0 / (1 << (msr & 0xF));
Len Brown869ce69e2016-06-16 23:22:37 -04002679 if (model == INTEL_FAM6_ATOM_SILVERMONT1)
Len Brown144b44b2013-11-09 00:30:16 -05002680 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
2681 else
2682 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
Len Brown889facb2012-11-08 00:48:57 -05002683
Andrey Semin40ee8e32014-12-05 00:07:00 -05002684 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
2685
Len Brown144b44b2013-11-09 00:30:16 -05002686 time_unit = msr >> 16 & 0xF;
2687 if (time_unit == 0)
2688 time_unit = 0xA;
Len Brown889facb2012-11-08 00:48:57 -05002689
Len Brown144b44b2013-11-09 00:30:16 -05002690 rapl_time_units = 1.0 / (1 << (time_unit));
2691
2692 tdp = get_tdp(model);
Len Brown889facb2012-11-08 00:48:57 -05002693
2694 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
Len Brownd8af6f52015-02-10 01:56:38 -05002695 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05002696 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
Len Brown889facb2012-11-08 00:48:57 -05002697
2698 return;
2699}
2700
Colin Ian King1b693172016-03-02 13:50:25 +00002701void perf_limit_reasons_probe(unsigned int family, unsigned int model)
Len Brown3a9a9412014-08-15 02:39:52 -04002702{
2703 if (!genuine_intel)
2704 return;
2705
2706 if (family != 6)
2707 return;
2708
2709 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002710 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2711 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2712 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
Len Brown3a9a9412014-08-15 02:39:52 -04002713 do_gfx_perf_limit_reasons = 1;
Len Brown869ce69e2016-06-16 23:22:37 -04002714 case INTEL_FAM6_HASWELL_X: /* HSX */
Len Brown3a9a9412014-08-15 02:39:52 -04002715 do_core_perf_limit_reasons = 1;
2716 do_ring_perf_limit_reasons = 1;
2717 default:
2718 return;
2719 }
2720}
2721
Len Brown889facb2012-11-08 00:48:57 -05002722int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2723{
2724 unsigned long long msr;
2725 unsigned int dts;
2726 int cpu;
2727
2728 if (!(do_dts || do_ptm))
2729 return 0;
2730
2731 cpu = t->cpu_id;
2732
2733 /* DTS is per-core, no need to print for each thread */
2734 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
2735 return 0;
2736
2737 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002738 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002739 return -1;
2740 }
2741
2742 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
2743 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
2744 return 0;
2745
2746 dts = (msr >> 16) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05002747 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05002748 cpu, msr, tcc_activation_temp - dts);
2749
2750#ifdef THERM_DEBUG
2751 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
2752 return 0;
2753
2754 dts = (msr >> 16) & 0x7F;
2755 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05002756 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05002757 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
2758#endif
2759 }
2760
2761
2762 if (do_dts) {
2763 unsigned int resolution;
2764
2765 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
2766 return 0;
2767
2768 dts = (msr >> 16) & 0x7F;
2769 resolution = (msr >> 27) & 0xF;
Len Brownb7d8c142016-02-13 23:36:17 -05002770 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
Len Brown889facb2012-11-08 00:48:57 -05002771 cpu, msr, tcc_activation_temp - dts, resolution);
2772
2773#ifdef THERM_DEBUG
2774 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
2775 return 0;
2776
2777 dts = (msr >> 16) & 0x7F;
2778 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05002779 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05002780 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
2781#endif
2782 }
2783
2784 return 0;
2785}
Len Brown36229892016-02-26 20:51:02 -05002786
Len Brown889facb2012-11-08 00:48:57 -05002787void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
2788{
Len Brownb7d8c142016-02-13 23:36:17 -05002789 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05002790 cpu, label,
2791 ((msr >> 15) & 1) ? "EN" : "DIS",
2792 ((msr >> 0) & 0x7FFF) * rapl_power_units,
2793 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
2794 (((msr >> 16) & 1) ? "EN" : "DIS"));
2795
2796 return;
2797}
2798
2799int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2800{
2801 unsigned long long msr;
2802 int cpu;
Len Brown889facb2012-11-08 00:48:57 -05002803
2804 if (!do_rapl)
2805 return 0;
2806
2807 /* RAPL counters are per package, so print only for 1st thread/package */
2808 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2809 return 0;
2810
2811 cpu = t->cpu_id;
2812 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002813 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002814 return -1;
2815 }
2816
2817 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
2818 return -1;
2819
Len Brownd8af6f52015-02-10 01:56:38 -05002820 if (debug) {
Len Brownb7d8c142016-02-13 23:36:17 -05002821 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
Len Brown889facb2012-11-08 00:48:57 -05002822 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
Len Brown144b44b2013-11-09 00:30:16 -05002823 rapl_power_units, rapl_energy_units, rapl_time_units);
Len Brown889facb2012-11-08 00:48:57 -05002824 }
Len Brown144b44b2013-11-09 00:30:16 -05002825 if (do_rapl & RAPL_PKG_POWER_INFO) {
2826
Len Brown889facb2012-11-08 00:48:57 -05002827 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
2828 return -5;
2829
2830
Len Brownb7d8c142016-02-13 23:36:17 -05002831 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 -05002832 cpu, msr,
2833 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2834 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2835 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2836 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
2837
Len Brown144b44b2013-11-09 00:30:16 -05002838 }
2839 if (do_rapl & RAPL_PKG) {
2840
Len Brown889facb2012-11-08 00:48:57 -05002841 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
2842 return -9;
2843
Len Brownb7d8c142016-02-13 23:36:17 -05002844 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002845 cpu, msr, (msr >> 63) & 1 ? "": "UN");
2846
2847 print_power_limit_msr(cpu, msr, "PKG Limit #1");
Len Brownb7d8c142016-02-13 23:36:17 -05002848 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05002849 cpu,
2850 ((msr >> 47) & 1) ? "EN" : "DIS",
2851 ((msr >> 32) & 0x7FFF) * rapl_power_units,
2852 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
2853 ((msr >> 48) & 1) ? "EN" : "DIS");
2854 }
2855
Len Brown0b2bb692015-03-26 00:50:30 -04002856 if (do_rapl & RAPL_DRAM_POWER_INFO) {
Len Brown889facb2012-11-08 00:48:57 -05002857 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
2858 return -6;
2859
Len Brownb7d8c142016-02-13 23:36:17 -05002860 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 -05002861 cpu, msr,
2862 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2863 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2864 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
2865 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
Len Brown0b2bb692015-03-26 00:50:30 -04002866 }
2867 if (do_rapl & RAPL_DRAM) {
Len Brown889facb2012-11-08 00:48:57 -05002868 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
2869 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05002870 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002871 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2872
2873 print_power_limit_msr(cpu, msr, "DRAM Limit");
2874 }
Len Brown144b44b2013-11-09 00:30:16 -05002875 if (do_rapl & RAPL_CORE_POLICY) {
Len Brownd8af6f52015-02-10 01:56:38 -05002876 if (debug) {
Len Brown889facb2012-11-08 00:48:57 -05002877 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
2878 return -7;
2879
Len Brownb7d8c142016-02-13 23:36:17 -05002880 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown144b44b2013-11-09 00:30:16 -05002881 }
2882 }
Jacob Pan91484942016-06-16 09:48:20 -07002883 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
Len Brownd8af6f52015-02-10 01:56:38 -05002884 if (debug) {
Len Brown889facb2012-11-08 00:48:57 -05002885 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
2886 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05002887 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002888 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2889 print_power_limit_msr(cpu, msr, "Cores Limit");
2890 }
2891 }
2892 if (do_rapl & RAPL_GFX) {
Len Brownd8af6f52015-02-10 01:56:38 -05002893 if (debug) {
Len Brown889facb2012-11-08 00:48:57 -05002894 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
2895 return -8;
2896
Len Brownb7d8c142016-02-13 23:36:17 -05002897 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown889facb2012-11-08 00:48:57 -05002898
2899 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
2900 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05002901 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown889facb2012-11-08 00:48:57 -05002902 cpu, msr, (msr >> 31) & 1 ? "": "UN");
2903 print_power_limit_msr(cpu, msr, "GFX Limit");
2904 }
2905 }
2906 return 0;
2907}
2908
Len Brownd7899442015-01-23 00:12:33 -05002909/*
2910 * SNB adds support for additional MSRs:
2911 *
2912 * MSR_PKG_C7_RESIDENCY 0x000003fa
2913 * MSR_CORE_C7_RESIDENCY 0x000003fe
2914 * MSR_PKG_C2_RESIDENCY 0x0000060d
2915 */
Len Brown103a8fe2010-10-22 23:53:03 -04002916
Len Brownd7899442015-01-23 00:12:33 -05002917int has_snb_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04002918{
2919 if (!genuine_intel)
2920 return 0;
2921
2922 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002923 case INTEL_FAM6_SANDYBRIDGE:
2924 case INTEL_FAM6_SANDYBRIDGE_X:
2925 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2926 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2927 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2928 case INTEL_FAM6_HASWELL_X: /* HSW */
2929 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2930 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2931 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2932 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2933 case INTEL_FAM6_BROADWELL_X: /* BDX */
2934 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2935 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2936 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2937 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2938 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2939 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2940 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Xiaolong Wang5bbac262016-09-30 17:53:40 +08002941 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Brown103a8fe2010-10-22 23:53:03 -04002942 return 1;
2943 }
2944 return 0;
2945}
2946
Len Brownd7899442015-01-23 00:12:33 -05002947/*
2948 * HSW adds support for additional MSRs:
2949 *
Len Brown5a634262016-04-06 17:15:55 -04002950 * MSR_PKG_C8_RESIDENCY 0x00000630
2951 * MSR_PKG_C9_RESIDENCY 0x00000631
2952 * MSR_PKG_C10_RESIDENCY 0x00000632
2953 *
2954 * MSR_PKGC8_IRTL 0x00000633
2955 * MSR_PKGC9_IRTL 0x00000634
2956 * MSR_PKGC10_IRTL 0x00000635
2957 *
Len Brownd7899442015-01-23 00:12:33 -05002958 */
2959int has_hsw_msrs(unsigned int family, unsigned int model)
Kristen Carlson Accardica587102012-11-21 05:22:43 -08002960{
2961 if (!genuine_intel)
2962 return 0;
2963
2964 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002965 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2966 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2967 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2968 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2969 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2970 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2971 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Kristen Carlson Accardica587102012-11-21 05:22:43 -08002972 return 1;
2973 }
2974 return 0;
2975}
2976
Len Brown0b2bb692015-03-26 00:50:30 -04002977/*
2978 * SKL adds support for additional MSRS:
2979 *
2980 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
2981 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
2982 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
2983 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
2984 */
2985int has_skl_msrs(unsigned int family, unsigned int model)
2986{
2987 if (!genuine_intel)
2988 return 0;
2989
2990 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04002991 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2992 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2993 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2994 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04002995 return 1;
2996 }
2997 return 0;
2998}
2999
3000
Kristen Carlson Accardica587102012-11-21 05:22:43 -08003001
Len Brown144b44b2013-11-09 00:30:16 -05003002int is_slm(unsigned int family, unsigned int model)
3003{
3004 if (!genuine_intel)
3005 return 0;
3006 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04003007 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3008 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brown144b44b2013-11-09 00:30:16 -05003009 return 1;
3010 }
3011 return 0;
3012}
3013
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003014int is_knl(unsigned int family, unsigned int model)
3015{
3016 if (!genuine_intel)
3017 return 0;
3018 switch (model) {
Len Brown869ce69e2016-06-16 23:22:37 -04003019 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003020 return 1;
3021 }
3022 return 0;
3023}
3024
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02003025unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
3026{
3027 if (is_knl(family, model))
3028 return 1024;
3029 return 1;
3030}
3031
Len Brown144b44b2013-11-09 00:30:16 -05003032#define SLM_BCLK_FREQS 5
3033double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
3034
3035double slm_bclk(void)
3036{
3037 unsigned long long msr = 3;
3038 unsigned int i;
3039 double freq;
3040
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003041 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003042 fprintf(outf, "SLM BCLK: unknown\n");
Len Brown144b44b2013-11-09 00:30:16 -05003043
3044 i = msr & 0xf;
3045 if (i >= SLM_BCLK_FREQS) {
Len Brownb7d8c142016-02-13 23:36:17 -05003046 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
Colin Ian King0a91e552016-04-25 13:03:15 +01003047 i = 3;
Len Brown144b44b2013-11-09 00:30:16 -05003048 }
3049 freq = slm_freq_table[i];
3050
Len Brownb7d8c142016-02-13 23:36:17 -05003051 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
Len Brown144b44b2013-11-09 00:30:16 -05003052
3053 return freq;
3054}
3055
Len Brown103a8fe2010-10-22 23:53:03 -04003056double discover_bclk(unsigned int family, unsigned int model)
3057{
Chrzaniuk, Hubert121b48b2016-02-10 16:35:17 +01003058 if (has_snb_msrs(family, model) || is_knl(family, model))
Len Brown103a8fe2010-10-22 23:53:03 -04003059 return 100.00;
Len Brown144b44b2013-11-09 00:30:16 -05003060 else if (is_slm(family, model))
3061 return slm_bclk();
Len Brown103a8fe2010-10-22 23:53:03 -04003062 else
3063 return 133.33;
3064}
3065
Len Brown889facb2012-11-08 00:48:57 -05003066/*
3067 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
3068 * the Thermal Control Circuit (TCC) activates.
3069 * This is usually equal to tjMax.
3070 *
3071 * Older processors do not have this MSR, so there we guess,
3072 * but also allow cmdline over-ride with -T.
3073 *
3074 * Several MSR temperature values are in units of degrees-C
3075 * below this value, including the Digital Thermal Sensor (DTS),
3076 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
3077 */
3078int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3079{
3080 unsigned long long msr;
3081 unsigned int target_c_local;
3082 int cpu;
3083
3084 /* tcc_activation_temp is used only for dts or ptm */
3085 if (!(do_dts || do_ptm))
3086 return 0;
3087
3088 /* this is a per-package concept */
3089 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3090 return 0;
3091
3092 cpu = t->cpu_id;
3093 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003094 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003095 return -1;
3096 }
3097
3098 if (tcc_activation_temp_override != 0) {
3099 tcc_activation_temp = tcc_activation_temp_override;
Len Brownb7d8c142016-02-13 23:36:17 -05003100 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003101 cpu, tcc_activation_temp);
3102 return 0;
3103 }
3104
3105 /* Temperature Target MSR is Nehalem and newer only */
Len Brownd7899442015-01-23 00:12:33 -05003106 if (!do_nhm_platform_info)
Len Brown889facb2012-11-08 00:48:57 -05003107 goto guess;
3108
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003109 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
Len Brown889facb2012-11-08 00:48:57 -05003110 goto guess;
3111
Jean Delvare34821242014-05-01 11:40:19 +02003112 target_c_local = (msr >> 16) & 0xFF;
Len Brown889facb2012-11-08 00:48:57 -05003113
Len Brownd8af6f52015-02-10 01:56:38 -05003114 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003115 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003116 cpu, msr, target_c_local);
3117
Jean Delvare34821242014-05-01 11:40:19 +02003118 if (!target_c_local)
Len Brown889facb2012-11-08 00:48:57 -05003119 goto guess;
3120
3121 tcc_activation_temp = target_c_local;
3122
3123 return 0;
3124
3125guess:
3126 tcc_activation_temp = TJMAX_DEFAULT;
Len Brownb7d8c142016-02-13 23:36:17 -05003127 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
Len Brown889facb2012-11-08 00:48:57 -05003128 cpu, tcc_activation_temp);
3129
3130 return 0;
3131}
Len Brown69807a62015-11-21 12:22:47 -05003132
Len Brownaa8d8cc2016-03-11 13:26:03 -05003133void decode_feature_control_msr(void)
3134{
3135 unsigned long long msr;
3136
3137 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
3138 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
3139 base_cpu, msr,
3140 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
3141 msr & (1 << 18) ? "SGX" : "");
3142}
3143
Len Brown69807a62015-11-21 12:22:47 -05003144void decode_misc_enable_msr(void)
3145{
3146 unsigned long long msr;
3147
3148 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003149 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%s %s %s)\n",
Len Brown69807a62015-11-21 12:22:47 -05003150 base_cpu, msr,
3151 msr & (1 << 3) ? "TCC" : "",
3152 msr & (1 << 16) ? "EIST" : "",
3153 msr & (1 << 18) ? "MONITOR" : "");
3154}
3155
Len Brownf0057312015-12-03 01:35:36 -05003156/*
3157 * Decode MSR_MISC_PWR_MGMT
3158 *
3159 * Decode the bits according to the Nehalem documentation
3160 * bit[0] seems to continue to have same meaning going forward
3161 * bit[1] less so...
3162 */
3163void decode_misc_pwr_mgmt_msr(void)
3164{
3165 unsigned long long msr;
3166
3167 if (!do_nhm_platform_info)
3168 return;
3169
3170 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003171 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB)\n",
Len Brownf0057312015-12-03 01:35:36 -05003172 base_cpu, msr,
3173 msr & (1 << 0) ? "DIS" : "EN",
3174 msr & (1 << 1) ? "EN" : "DIS");
3175}
Len Brown7f5c2582015-12-01 01:36:39 -05003176
Len Brownfcd17212015-03-23 20:29:09 -04003177void process_cpuid()
Len Brown103a8fe2010-10-22 23:53:03 -04003178{
Len Brown61a87ba2015-11-23 02:30:51 -05003179 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
Len Brown103a8fe2010-10-22 23:53:03 -04003180 unsigned int fms, family, model, stepping;
3181
3182 eax = ebx = ecx = edx = 0;
3183
Len Brown5aea2f72016-03-13 03:14:35 -04003184 __cpuid(0, max_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003185
3186 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
3187 genuine_intel = 1;
3188
Len Brownd8af6f52015-02-10 01:56:38 -05003189 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003190 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
Len Brown103a8fe2010-10-22 23:53:03 -04003191 (char *)&ebx, (char *)&edx, (char *)&ecx);
3192
Len Brown5aea2f72016-03-13 03:14:35 -04003193 __cpuid(1, fms, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003194 family = (fms >> 8) & 0xf;
3195 model = (fms >> 4) & 0xf;
3196 stepping = fms & 0xf;
3197 if (family == 6 || family == 0xf)
3198 model += ((fms >> 16) & 0xf) << 4;
3199
Len Brown69807a62015-11-21 12:22:47 -05003200 if (debug) {
Len Brownb7d8c142016-02-13 23:36:17 -05003201 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
Len Brown103a8fe2010-10-22 23:53:03 -04003202 max_level, family, model, stepping, family, model, stepping);
Len Brownaa8d8cc2016-03-11 13:26:03 -05003203 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
Len Brown69807a62015-11-21 12:22:47 -05003204 ecx & (1 << 0) ? "SSE3" : "-",
3205 ecx & (1 << 3) ? "MONITOR" : "-",
Len Brownaa8d8cc2016-03-11 13:26:03 -05003206 ecx & (1 << 6) ? "SMX" : "-",
Len Brown69807a62015-11-21 12:22:47 -05003207 ecx & (1 << 7) ? "EIST" : "-",
3208 ecx & (1 << 8) ? "TM2" : "-",
3209 edx & (1 << 4) ? "TSC" : "-",
3210 edx & (1 << 5) ? "MSR" : "-",
3211 edx & (1 << 22) ? "ACPI-TM" : "-",
3212 edx & (1 << 29) ? "TM" : "-");
3213 }
Len Brown103a8fe2010-10-22 23:53:03 -04003214
Josh Triplettb2c95d92013-08-20 17:20:18 -07003215 if (!(edx & (1 << 5)))
3216 errx(1, "CPUID: no MSR");
Len Brown103a8fe2010-10-22 23:53:03 -04003217
3218 /*
3219 * check max extended function levels of CPUID.
3220 * This is needed to check for invariant TSC.
3221 * This check is valid for both Intel and AMD.
3222 */
3223 ebx = ecx = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003224 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003225
Len Brown61a87ba2015-11-23 02:30:51 -05003226 if (max_extended_level >= 0x80000007) {
Len Brown103a8fe2010-10-22 23:53:03 -04003227
Len Brownd7899442015-01-23 00:12:33 -05003228 /*
3229 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
3230 * this check is valid for both Intel and AMD
3231 */
Len Brown5aea2f72016-03-13 03:14:35 -04003232 __cpuid(0x80000007, eax, ebx, ecx, edx);
Len Brownd7899442015-01-23 00:12:33 -05003233 has_invariant_tsc = edx & (1 << 8);
3234 }
Len Brown103a8fe2010-10-22 23:53:03 -04003235
3236 /*
3237 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
3238 * this check is valid for both Intel and AMD
3239 */
3240
Len Brown5aea2f72016-03-13 03:14:35 -04003241 __cpuid(0x6, eax, ebx, ecx, edx);
Thomas Renninger8209e052011-01-21 15:11:19 +01003242 has_aperf = ecx & (1 << 0);
Len Brown889facb2012-11-08 00:48:57 -05003243 do_dts = eax & (1 << 0);
3244 do_ptm = eax & (1 << 6);
Len Brown7f5c2582015-12-01 01:36:39 -05003245 has_hwp = eax & (1 << 7);
3246 has_hwp_notify = eax & (1 << 8);
3247 has_hwp_activity_window = eax & (1 << 9);
3248 has_hwp_epp = eax & (1 << 10);
3249 has_hwp_pkg = eax & (1 << 11);
Len Brown889facb2012-11-08 00:48:57 -05003250 has_epb = ecx & (1 << 3);
3251
Len Brownd8af6f52015-02-10 01:56:38 -05003252 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003253 fprintf(outf, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sHWP, "
Len Brown7f5c2582015-12-01 01:36:39 -05003254 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
3255 has_aperf ? "" : "No-",
3256 do_dts ? "" : "No-",
3257 do_ptm ? "" : "No-",
3258 has_hwp ? "" : "No-",
3259 has_hwp_notify ? "" : "No-",
3260 has_hwp_activity_window ? "" : "No-",
3261 has_hwp_epp ? "" : "No-",
3262 has_hwp_pkg ? "" : "No-",
3263 has_epb ? "" : "No-");
Len Brown103a8fe2010-10-22 23:53:03 -04003264
Len Brown69807a62015-11-21 12:22:47 -05003265 if (debug)
3266 decode_misc_enable_msr();
3267
Len Brown8ae72252016-04-06 17:15:54 -04003268 if (max_level >= 0x7 && debug) {
Len Brownaa8d8cc2016-03-11 13:26:03 -05003269 int has_sgx;
3270
3271 ecx = 0;
3272
3273 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
3274
3275 has_sgx = ebx & (1 << 2);
3276 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
3277
3278 if (has_sgx)
3279 decode_feature_control_msr();
3280 }
3281
Len Brown61a87ba2015-11-23 02:30:51 -05003282 if (max_level >= 0x15) {
Len Brown8a5bdf42015-04-01 21:02:57 -04003283 unsigned int eax_crystal;
3284 unsigned int ebx_tsc;
3285
3286 /*
3287 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
3288 */
3289 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003290 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
Len Brown8a5bdf42015-04-01 21:02:57 -04003291
3292 if (ebx_tsc != 0) {
3293
3294 if (debug && (ebx != 0))
Len Brownb7d8c142016-02-13 23:36:17 -05003295 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003296 eax_crystal, ebx_tsc, crystal_hz);
3297
3298 if (crystal_hz == 0)
3299 switch(model) {
Len Brown869ce69e2016-06-16 23:22:37 -04003300 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3301 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3302 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3303 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Browne8efbc82016-04-06 17:15:57 -04003304 crystal_hz = 24000000; /* 24.0 MHz */
3305 break;
Len Brown869ce69e2016-06-16 23:22:37 -04003306 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brownec53e592016-04-06 17:15:58 -04003307 crystal_hz = 25000000; /* 25.0 MHz */
3308 break;
Len Brown869ce69e2016-06-16 23:22:37 -04003309 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
3310 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Browne8efbc82016-04-06 17:15:57 -04003311 crystal_hz = 19200000; /* 19.2 MHz */
Len Brown8a5bdf42015-04-01 21:02:57 -04003312 break;
3313 default:
3314 crystal_hz = 0;
3315 }
3316
3317 if (crystal_hz) {
3318 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
3319 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003320 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003321 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
3322 }
3323 }
3324 }
Len Brown61a87ba2015-11-23 02:30:51 -05003325 if (max_level >= 0x16) {
3326 unsigned int base_mhz, max_mhz, bus_mhz, edx;
3327
3328 /*
3329 * CPUID 16H Base MHz, Max MHz, Bus MHz
3330 */
3331 base_mhz = max_mhz = bus_mhz = edx = 0;
3332
Len Brown5aea2f72016-03-13 03:14:35 -04003333 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
Len Brown61a87ba2015-11-23 02:30:51 -05003334 if (debug)
Len Brownb7d8c142016-02-13 23:36:17 -05003335 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
Len Brown61a87ba2015-11-23 02:30:51 -05003336 base_mhz, max_mhz, bus_mhz);
3337 }
Len Brown8a5bdf42015-04-01 21:02:57 -04003338
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02003339 if (has_aperf)
3340 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
3341
Len Brownee7e38e2015-02-09 23:39:45 -05003342 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
Len Brownd7899442015-01-23 00:12:33 -05003343 do_snb_cstates = has_snb_msrs(family, model);
Len Brown5a634262016-04-06 17:15:55 -04003344 do_irtl_snb = has_snb_msrs(family, model);
Len Brownee7e38e2015-02-09 23:39:45 -05003345 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
3346 do_pc3 = (pkg_cstate_limit >= PCL__3);
3347 do_pc6 = (pkg_cstate_limit >= PCL__6);
3348 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
Len Brownd7899442015-01-23 00:12:33 -05003349 do_c8_c9_c10 = has_hsw_msrs(family, model);
Len Brown5a634262016-04-06 17:15:55 -04003350 do_irtl_hsw = has_hsw_msrs(family, model);
Len Brown0b2bb692015-03-26 00:50:30 -04003351 do_skl_residency = has_skl_msrs(family, model);
Len Brown144b44b2013-11-09 00:30:16 -05003352 do_slm_cstates = is_slm(family, model);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003353 do_knl_cstates = is_knl(family, model);
Len Brown103a8fe2010-10-22 23:53:03 -04003354
Len Brownf0057312015-12-03 01:35:36 -05003355 if (debug)
3356 decode_misc_pwr_mgmt_msr();
3357
Len Brown889facb2012-11-08 00:48:57 -05003358 rapl_probe(family, model);
Len Brown3a9a9412014-08-15 02:39:52 -04003359 perf_limit_reasons_probe(family, model);
Len Brown889facb2012-11-08 00:48:57 -05003360
Len Brownfcd17212015-03-23 20:29:09 -04003361 if (debug)
Colin Ian King1b693172016-03-02 13:50:25 +00003362 dump_cstate_pstate_config_info(family, model);
Len Brownfcd17212015-03-23 20:29:09 -04003363
Len Browna2b7b742015-09-26 00:12:38 -04003364 if (has_skl_msrs(family, model))
3365 calculate_tsc_tweak();
3366
Len Brownfdf676e2016-02-27 01:28:12 -05003367 do_gfx_rc6_ms = !access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK);
3368
Len Brown27d47352016-02-27 00:37:54 -05003369 do_gfx_mhz = !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK);
3370
Len Brown889facb2012-11-08 00:48:57 -05003371 return;
Len Brown103a8fe2010-10-22 23:53:03 -04003372}
3373
Len Brownd8af6f52015-02-10 01:56:38 -05003374void help()
Len Brown103a8fe2010-10-22 23:53:03 -04003375{
Len Brownb7d8c142016-02-13 23:36:17 -05003376 fprintf(outf,
Len Brownd8af6f52015-02-10 01:56:38 -05003377 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
3378 "\n"
3379 "Turbostat forks the specified COMMAND and prints statistics\n"
3380 "when COMMAND completes.\n"
3381 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
3382 "to print statistics, until interrupted.\n"
3383 "--debug run in \"debug\" mode\n"
3384 "--interval sec Override default 5-second measurement interval\n"
3385 "--help print this help message\n"
3386 "--counter msr print 32-bit counter at address \"msr\"\n"
3387 "--Counter msr print 64-bit Counter at address \"msr\"\n"
Len Brownb7d8c142016-02-13 23:36:17 -05003388 "--out file create or truncate \"file\" for all output\n"
Len Brownd8af6f52015-02-10 01:56:38 -05003389 "--msr msr print 32-bit value at address \"msr\"\n"
3390 "--MSR msr print 64-bit Value at address \"msr\"\n"
3391 "--version print version information\n"
3392 "\n"
3393 "For more help, run \"man turbostat\"\n");
Len Brown103a8fe2010-10-22 23:53:03 -04003394}
3395
3396
3397/*
3398 * in /dev/cpu/ return success for names that are numbers
3399 * ie. filter out ".", "..", "microcode".
3400 */
3401int dir_filter(const struct dirent *dirp)
3402{
3403 if (isdigit(dirp->d_name[0]))
3404 return 1;
3405 else
3406 return 0;
3407}
3408
3409int open_dev_cpu_msr(int dummy1)
3410{
3411 return 0;
3412}
3413
Len Brownc98d5d92012-06-04 00:56:40 -04003414void topology_probe()
3415{
3416 int i;
3417 int max_core_id = 0;
3418 int max_package_id = 0;
3419 int max_siblings = 0;
3420 struct cpu_topology {
3421 int core_id;
3422 int physical_package_id;
3423 } *cpus;
3424
3425 /* Initialize num_cpus, max_cpu_num */
3426 topo.num_cpus = 0;
3427 topo.max_cpu_num = 0;
3428 for_all_proc_cpus(count_cpus);
3429 if (!summary_only && topo.num_cpus > 1)
3430 show_cpu = 1;
3431
Len Brownd8af6f52015-02-10 01:56:38 -05003432 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003433 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
Len Brownc98d5d92012-06-04 00:56:40 -04003434
3435 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
Josh Triplettb2c95d92013-08-20 17:20:18 -07003436 if (cpus == NULL)
3437 err(1, "calloc cpus");
Len Brownc98d5d92012-06-04 00:56:40 -04003438
3439 /*
3440 * Allocate and initialize cpu_present_set
3441 */
3442 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07003443 if (cpu_present_set == NULL)
3444 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04003445 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3446 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
3447 for_all_proc_cpus(mark_cpu_present);
3448
3449 /*
3450 * Allocate and initialize cpu_affinity_set
3451 */
3452 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07003453 if (cpu_affinity_set == NULL)
3454 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04003455 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
3456 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
3457
3458
3459 /*
3460 * For online cpus
3461 * find max_core_id, max_package_id
3462 */
3463 for (i = 0; i <= topo.max_cpu_num; ++i) {
3464 int siblings;
3465
3466 if (cpu_is_not_present(i)) {
Len Brownd8af6f52015-02-10 01:56:38 -05003467 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003468 fprintf(outf, "cpu%d NOT PRESENT\n", i);
Len Brownc98d5d92012-06-04 00:56:40 -04003469 continue;
3470 }
3471 cpus[i].core_id = get_core_id(i);
3472 if (cpus[i].core_id > max_core_id)
3473 max_core_id = cpus[i].core_id;
3474
3475 cpus[i].physical_package_id = get_physical_package_id(i);
3476 if (cpus[i].physical_package_id > max_package_id)
3477 max_package_id = cpus[i].physical_package_id;
3478
3479 siblings = get_num_ht_siblings(i);
3480 if (siblings > max_siblings)
3481 max_siblings = siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05003482 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003483 fprintf(outf, "cpu %d pkg %d core %d\n",
Len Brownc98d5d92012-06-04 00:56:40 -04003484 i, cpus[i].physical_package_id, cpus[i].core_id);
3485 }
3486 topo.num_cores_per_pkg = max_core_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05003487 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003488 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
Len Brownc98d5d92012-06-04 00:56:40 -04003489 max_core_id, topo.num_cores_per_pkg);
Len Brown1cc21f72015-02-23 00:34:57 -05003490 if (debug && !summary_only && topo.num_cores_per_pkg > 1)
Len Brownc98d5d92012-06-04 00:56:40 -04003491 show_core = 1;
3492
3493 topo.num_packages = max_package_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05003494 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003495 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
Len Brownc98d5d92012-06-04 00:56:40 -04003496 max_package_id, topo.num_packages);
Len Brown1cc21f72015-02-23 00:34:57 -05003497 if (debug && !summary_only && topo.num_packages > 1)
Len Brownc98d5d92012-06-04 00:56:40 -04003498 show_pkg = 1;
3499
3500 topo.num_threads_per_core = max_siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05003501 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003502 fprintf(outf, "max_siblings %d\n", max_siblings);
Len Brownc98d5d92012-06-04 00:56:40 -04003503
3504 free(cpus);
3505}
3506
3507void
3508allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
3509{
3510 int i;
3511
3512 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
3513 topo.num_packages, sizeof(struct thread_data));
3514 if (*t == NULL)
3515 goto error;
3516
3517 for (i = 0; i < topo.num_threads_per_core *
3518 topo.num_cores_per_pkg * topo.num_packages; i++)
3519 (*t)[i].cpu_id = -1;
3520
3521 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
3522 sizeof(struct core_data));
3523 if (*c == NULL)
3524 goto error;
3525
3526 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
3527 (*c)[i].core_id = -1;
3528
3529 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
3530 if (*p == NULL)
3531 goto error;
3532
3533 for (i = 0; i < topo.num_packages; i++)
3534 (*p)[i].package_id = i;
3535
3536 return;
3537error:
Josh Triplettb2c95d92013-08-20 17:20:18 -07003538 err(1, "calloc counters");
Len Brownc98d5d92012-06-04 00:56:40 -04003539}
3540/*
3541 * init_counter()
3542 *
3543 * set cpu_id, core_num, pkg_num
3544 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
3545 *
3546 * increment topo.num_cores when 1st core in pkg seen
3547 */
3548void init_counter(struct thread_data *thread_base, struct core_data *core_base,
3549 struct pkg_data *pkg_base, int thread_num, int core_num,
3550 int pkg_num, int cpu_id)
3551{
3552 struct thread_data *t;
3553 struct core_data *c;
3554 struct pkg_data *p;
3555
3556 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num);
3557 c = GET_CORE(core_base, core_num, pkg_num);
3558 p = GET_PKG(pkg_base, pkg_num);
3559
3560 t->cpu_id = cpu_id;
3561 if (thread_num == 0) {
3562 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
3563 if (cpu_is_first_core_in_package(cpu_id))
3564 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
3565 }
3566
3567 c->core_id = core_num;
3568 p->package_id = pkg_num;
3569}
3570
3571
3572int initialize_counters(int cpu_id)
3573{
3574 int my_thread_id, my_core_id, my_package_id;
3575
3576 my_package_id = get_physical_package_id(cpu_id);
3577 my_core_id = get_core_id(cpu_id);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07003578 my_thread_id = get_cpu_position_in_core(cpu_id);
3579 if (!my_thread_id)
Len Brownc98d5d92012-06-04 00:56:40 -04003580 topo.num_cores++;
Len Brownc98d5d92012-06-04 00:56:40 -04003581
3582 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
3583 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
3584 return 0;
3585}
3586
3587void allocate_output_buffer()
3588{
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003589 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
Len Brownc98d5d92012-06-04 00:56:40 -04003590 outp = output_buffer;
Josh Triplettb2c95d92013-08-20 17:20:18 -07003591 if (outp == NULL)
3592 err(-1, "calloc output buffer");
Len Brownc98d5d92012-06-04 00:56:40 -04003593}
Len Brown36229892016-02-26 20:51:02 -05003594void allocate_fd_percpu(void)
3595{
Mika Westerberg01a67ad2016-04-22 11:13:23 +03003596 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown36229892016-02-26 20:51:02 -05003597 if (fd_percpu == NULL)
3598 err(-1, "calloc fd_percpu");
3599}
Len Brown562a2d32016-02-26 23:48:05 -05003600void allocate_irq_buffers(void)
3601{
3602 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
3603 if (irq_column_2_cpu == NULL)
3604 err(-1, "calloc %d", topo.num_cpus);
Len Brownc98d5d92012-06-04 00:56:40 -04003605
Mika Westerberg01a67ad2016-04-22 11:13:23 +03003606 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown562a2d32016-02-26 23:48:05 -05003607 if (irqs_per_cpu == NULL)
Mika Westerberg01a67ad2016-04-22 11:13:23 +03003608 err(-1, "calloc %d", topo.max_cpu_num + 1);
Len Brown562a2d32016-02-26 23:48:05 -05003609}
Len Brownc98d5d92012-06-04 00:56:40 -04003610void setup_all_buffers(void)
3611{
3612 topology_probe();
Len Brown562a2d32016-02-26 23:48:05 -05003613 allocate_irq_buffers();
Len Brown36229892016-02-26 20:51:02 -05003614 allocate_fd_percpu();
Len Brownc98d5d92012-06-04 00:56:40 -04003615 allocate_counters(&thread_even, &core_even, &package_even);
3616 allocate_counters(&thread_odd, &core_odd, &package_odd);
3617 allocate_output_buffer();
3618 for_all_proc_cpus(initialize_counters);
3619}
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003620
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003621void set_base_cpu(void)
3622{
3623 base_cpu = sched_getcpu();
3624 if (base_cpu < 0)
3625 err(-ENODEV, "No valid cpus found");
3626
3627 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05003628 fprintf(outf, "base_cpu = %d\n", base_cpu);
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003629}
3630
Len Brown103a8fe2010-10-22 23:53:03 -04003631void turbostat_init()
3632{
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003633 setup_all_buffers();
3634 set_base_cpu();
Len Brown103a8fe2010-10-22 23:53:03 -04003635 check_dev_msr();
Len Brown98481e72014-08-15 00:36:50 -04003636 check_permissions();
Len Brownfcd17212015-03-23 20:29:09 -04003637 process_cpuid();
Len Brown103a8fe2010-10-22 23:53:03 -04003638
Len Brown103a8fe2010-10-22 23:53:03 -04003639
Len Brownd8af6f52015-02-10 01:56:38 -05003640 if (debug)
Len Brown7f5c2582015-12-01 01:36:39 -05003641 for_all_cpus(print_hwp, ODD_COUNTERS);
3642
3643 if (debug)
Len Brown889facb2012-11-08 00:48:57 -05003644 for_all_cpus(print_epb, ODD_COUNTERS);
3645
Len Brownd8af6f52015-02-10 01:56:38 -05003646 if (debug)
Len Brown3a9a9412014-08-15 02:39:52 -04003647 for_all_cpus(print_perf_limit, ODD_COUNTERS);
3648
Len Brownd8af6f52015-02-10 01:56:38 -05003649 if (debug)
Len Brown889facb2012-11-08 00:48:57 -05003650 for_all_cpus(print_rapl, ODD_COUNTERS);
3651
3652 for_all_cpus(set_temperature_target, ODD_COUNTERS);
3653
Len Brownd8af6f52015-02-10 01:56:38 -05003654 if (debug)
Len Brown889facb2012-11-08 00:48:57 -05003655 for_all_cpus(print_thermal, ODD_COUNTERS);
Len Brown5a634262016-04-06 17:15:55 -04003656
3657 if (debug && do_irtl_snb)
3658 print_irtl();
Len Brown103a8fe2010-10-22 23:53:03 -04003659}
3660
3661int fork_it(char **argv)
3662{
Len Brown103a8fe2010-10-22 23:53:03 -04003663 pid_t child_pid;
Len Brownd91bb172012-11-01 00:08:19 -04003664 int status;
Len Brownd15cf7c2012-06-03 23:24:00 -04003665
Len Brownd91bb172012-11-01 00:08:19 -04003666 status = for_all_cpus(get_counters, EVEN_COUNTERS);
3667 if (status)
3668 exit(status);
Len Brownc98d5d92012-06-04 00:56:40 -04003669 /* clear affinity side-effect of get_counters() */
3670 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
Len Brown103a8fe2010-10-22 23:53:03 -04003671 gettimeofday(&tv_even, (struct timezone *)NULL);
3672
3673 child_pid = fork();
3674 if (!child_pid) {
3675 /* child */
3676 execvp(argv[0], argv);
3677 } else {
Len Brown103a8fe2010-10-22 23:53:03 -04003678
3679 /* parent */
Josh Triplettb2c95d92013-08-20 17:20:18 -07003680 if (child_pid == -1)
3681 err(1, "fork");
Len Brown103a8fe2010-10-22 23:53:03 -04003682
3683 signal(SIGINT, SIG_IGN);
3684 signal(SIGQUIT, SIG_IGN);
Josh Triplettb2c95d92013-08-20 17:20:18 -07003685 if (waitpid(child_pid, &status, 0) == -1)
3686 err(status, "waitpid");
Len Brown103a8fe2010-10-22 23:53:03 -04003687 }
Len Brownc98d5d92012-06-04 00:56:40 -04003688 /*
3689 * n.b. fork_it() does not check for errors from for_all_cpus()
3690 * because re-starting is problematic when forking
3691 */
3692 for_all_cpus(get_counters, ODD_COUNTERS);
Len Brown103a8fe2010-10-22 23:53:03 -04003693 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04003694 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04003695 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
3696 fprintf(outf, "%s: Counter reset detected\n", progname);
3697 else {
3698 compute_average(EVEN_COUNTERS);
3699 format_all_counters(EVEN_COUNTERS);
3700 }
Len Brown103a8fe2010-10-22 23:53:03 -04003701
Len Brownb7d8c142016-02-13 23:36:17 -05003702 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
3703
3704 flush_output_stderr();
Len Brown103a8fe2010-10-22 23:53:03 -04003705
Len Brownd91bb172012-11-01 00:08:19 -04003706 return status;
Len Brown103a8fe2010-10-22 23:53:03 -04003707}
3708
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003709int get_and_dump_counters(void)
3710{
3711 int status;
3712
3713 status = for_all_cpus(get_counters, ODD_COUNTERS);
3714 if (status)
3715 return status;
3716
3717 status = for_all_cpus(dump_counters, ODD_COUNTERS);
3718 if (status)
3719 return status;
3720
Len Brownb7d8c142016-02-13 23:36:17 -05003721 flush_output_stdout();
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003722
3723 return status;
3724}
3725
Len Brownd8af6f52015-02-10 01:56:38 -05003726void print_version() {
Len Brown3d109de2016-04-22 23:24:27 -04003727 fprintf(outf, "turbostat version 4.14 22 Apr 2016"
Len Brownd8af6f52015-02-10 01:56:38 -05003728 " - Len Brown <lenb@kernel.org>\n");
3729}
3730
Len Brown103a8fe2010-10-22 23:53:03 -04003731void cmdline(int argc, char **argv)
3732{
3733 int opt;
Len Brownd8af6f52015-02-10 01:56:38 -05003734 int option_index = 0;
3735 static struct option long_options[] = {
3736 {"Counter", required_argument, 0, 'C'},
3737 {"counter", required_argument, 0, 'c'},
3738 {"Dump", no_argument, 0, 'D'},
3739 {"debug", no_argument, 0, 'd'},
3740 {"interval", required_argument, 0, 'i'},
3741 {"help", no_argument, 0, 'h'},
3742 {"Joules", no_argument, 0, 'J'},
3743 {"MSR", required_argument, 0, 'M'},
3744 {"msr", required_argument, 0, 'm'},
Len Brownb7d8c142016-02-13 23:36:17 -05003745 {"out", required_argument, 0, 'o'},
Len Brownd8af6f52015-02-10 01:56:38 -05003746 {"Package", no_argument, 0, 'p'},
3747 {"processor", no_argument, 0, 'p'},
3748 {"Summary", no_argument, 0, 'S'},
3749 {"TCC", required_argument, 0, 'T'},
3750 {"version", no_argument, 0, 'v' },
3751 {0, 0, 0, 0 }
3752 };
Len Brown103a8fe2010-10-22 23:53:03 -04003753
3754 progname = argv[0];
3755
Len Brownb7d8c142016-02-13 23:36:17 -05003756 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v",
Len Brownd8af6f52015-02-10 01:56:38 -05003757 long_options, &option_index)) != -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04003758 switch (opt) {
Len Brownd8af6f52015-02-10 01:56:38 -05003759 case 'C':
3760 sscanf(optarg, "%x", &extra_delta_offset64);
Len Brown103a8fe2010-10-22 23:53:03 -04003761 break;
Len Brownf9240812012-10-06 15:26:31 -04003762 case 'c':
Len Brown8e180f32012-09-22 01:25:08 -04003763 sscanf(optarg, "%x", &extra_delta_offset32);
3764 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003765 case 'D':
3766 dump_only++;
Len Brown8e180f32012-09-22 01:25:08 -04003767 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003768 case 'd':
3769 debug++;
Len Brown2f32edf2012-09-21 23:45:46 -04003770 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003771 case 'h':
3772 default:
3773 help();
3774 exit(1);
3775 case 'i':
Len Brown2a0609c2016-02-12 22:44:48 -05003776 {
3777 double interval = strtod(optarg, NULL);
3778
3779 if (interval < 0.001) {
Len Brownb7d8c142016-02-13 23:36:17 -05003780 fprintf(outf, "interval %f seconds is too small\n",
Len Brown2a0609c2016-02-12 22:44:48 -05003781 interval);
3782 exit(2);
3783 }
3784
3785 interval_ts.tv_sec = interval;
3786 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
3787 }
Len Brown889facb2012-11-08 00:48:57 -05003788 break;
Dirk Brandewie5c56be92013-12-16 10:23:41 -08003789 case 'J':
3790 rapl_joules++;
3791 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003792 case 'M':
3793 sscanf(optarg, "%x", &extra_msr_offset64);
3794 break;
3795 case 'm':
3796 sscanf(optarg, "%x", &extra_msr_offset32);
3797 break;
Len Brownb7d8c142016-02-13 23:36:17 -05003798 case 'o':
3799 outf = fopen_or_die(optarg, "w");
3800 break;
Len Brownd8af6f52015-02-10 01:56:38 -05003801 case 'P':
3802 show_pkg_only++;
3803 break;
3804 case 'p':
3805 show_core_only++;
3806 break;
3807 case 'S':
3808 summary_only++;
3809 break;
3810 case 'T':
3811 tcc_activation_temp_override = atoi(optarg);
3812 break;
3813 case 'v':
3814 print_version();
3815 exit(0);
3816 break;
Len Brown103a8fe2010-10-22 23:53:03 -04003817 }
3818 }
3819}
3820
3821int main(int argc, char **argv)
3822{
Len Brownb7d8c142016-02-13 23:36:17 -05003823 outf = stderr;
3824
Len Brown103a8fe2010-10-22 23:53:03 -04003825 cmdline(argc, argv);
3826
Len Brownd8af6f52015-02-10 01:56:38 -05003827 if (debug)
3828 print_version();
Len Brown103a8fe2010-10-22 23:53:03 -04003829
3830 turbostat_init();
3831
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02003832 /* dump counters and exit */
3833 if (dump_only)
3834 return get_and_dump_counters();
3835
Len Brown103a8fe2010-10-22 23:53:03 -04003836 /*
3837 * if any params left, it must be a command to fork
3838 */
3839 if (argc - optind)
3840 return fork_it(argv + optind);
3841 else
3842 turbostat_loop();
3843
3844 return 0;
3845}