blob: 8c965bb2f4610b6fac51eec09ee64acf001f753a [file] [log] [blame]
Len Brown103a8fe2010-10-22 23:53:03 -04001/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
Len Brown144b44b2013-11-09 00:30:16 -05005 * Copyright (c) 2013 Intel Corporation.
Len Brown103a8fe2010-10-22 23:53:03 -04006 * Len Brown <len.brown@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
Len Brown88c32812012-03-29 21:44:40 -040022#define _GNU_SOURCE
Josh Triplettb731f312013-08-20 17:20:12 -070023#include MSRHEADER
Len Brown869ce692016-06-16 23:22:37 -040024#include INTEL_FAMILY_HEADER
Josh Triplett95aebc42013-08-20 17:20:16 -070025#include <stdarg.h>
Len Brown103a8fe2010-10-22 23:53:03 -040026#include <stdio.h>
Josh Triplettb2c95d92013-08-20 17:20:18 -070027#include <err.h>
Len Brown103a8fe2010-10-22 23:53:03 -040028#include <unistd.h>
29#include <sys/types.h>
30#include <sys/wait.h>
31#include <sys/stat.h>
32#include <sys/resource.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <sys/time.h>
36#include <stdlib.h>
Len Brownd8af6f52015-02-10 01:56:38 -050037#include <getopt.h>
Len Brown103a8fe2010-10-22 23:53:03 -040038#include <dirent.h>
39#include <string.h>
40#include <ctype.h>
Len Brown88c32812012-03-29 21:44:40 -040041#include <sched.h>
Len Brown2a0609c2016-02-12 22:44:48 -050042#include <time.h>
Josh Triplett2b928652013-08-20 17:20:14 -070043#include <cpuid.h>
Len Brown98481e72014-08-15 00:36:50 -040044#include <linux/capability.h>
45#include <errno.h>
Len Brown103a8fe2010-10-22 23:53:03 -040046
Len Brown103a8fe2010-10-22 23:53:03 -040047char *proc_stat = "/proc/stat";
Len Brownb7d8c142016-02-13 23:36:17 -050048FILE *outf;
Len Brown36229892016-02-26 20:51:02 -050049int *fd_percpu;
Len Brown2a0609c2016-02-12 22:44:48 -050050struct timespec interval_ts = {5, 0};
Len Brownd8af6f52015-02-10 01:56:38 -050051unsigned int debug;
Len Brown96e47152017-01-21 02:26:00 -050052unsigned int quiet;
Len Brownd8af6f52015-02-10 01:56:38 -050053unsigned int rapl_joules;
54unsigned int summary_only;
55unsigned int dump_only;
Len Brown103a8fe2010-10-22 23:53:03 -040056unsigned int do_snb_cstates;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -070057unsigned int do_knl_cstates;
Len Brown0b2bb692015-03-26 00:50:30 -040058unsigned int do_skl_residency;
Len Brown144b44b2013-11-09 00:30:16 -050059unsigned int do_slm_cstates;
60unsigned int use_c1_residency_msr;
Len Brown103a8fe2010-10-22 23:53:03 -040061unsigned int has_aperf;
Len Brown889facb2012-11-08 00:48:57 -050062unsigned int has_epb;
Len Brown5a634262016-04-06 17:15:55 -040063unsigned int do_irtl_snb;
64unsigned int do_irtl_hsw;
Len Brownfc04cc62014-02-06 00:55:19 -050065unsigned int units = 1000000; /* MHz etc */
Len Brown103a8fe2010-10-22 23:53:03 -040066unsigned int genuine_intel;
67unsigned int has_invariant_tsc;
Len Brownd7899442015-01-23 00:12:33 -050068unsigned int do_nhm_platform_info;
Len Browncf4cbe52017-01-01 13:08:33 -050069unsigned int no_MSR_MISC_PWR_MGMT;
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +020070unsigned int aperf_mperf_multiplier = 1;
Len Brown103a8fe2010-10-22 23:53:03 -040071double bclk;
Len Browna2b7b742015-09-26 00:12:38 -040072double base_hz;
Len Brown21ed5572015-10-19 22:37:40 -040073unsigned int has_base_hz;
Len Browna2b7b742015-09-26 00:12:38 -040074double tsc_tweak = 1.0;
Len Brownc98d5d92012-06-04 00:56:40 -040075unsigned int show_pkg_only;
76unsigned int show_core_only;
77char *output_buffer, *outp;
Len Brown889facb2012-11-08 00:48:57 -050078unsigned int do_rapl;
79unsigned int do_dts;
80unsigned int do_ptm;
Len Brownfdf676e2016-02-27 01:28:12 -050081unsigned long long gfx_cur_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -050082unsigned int gfx_cur_mhz;
Len Brown889facb2012-11-08 00:48:57 -050083unsigned int tcc_activation_temp;
84unsigned int tcc_activation_temp_override;
Andrey Semin40ee8e32014-12-05 00:07:00 -050085double rapl_power_units, rapl_time_units;
86double rapl_dram_energy_units, rapl_energy_units;
Len Brown889facb2012-11-08 00:48:57 -050087double rapl_joule_counter_range;
Len Brown3a9a9412014-08-15 02:39:52 -040088unsigned int do_core_perf_limit_reasons;
89unsigned int do_gfx_perf_limit_reasons;
90unsigned int do_ring_perf_limit_reasons;
Len Brown8a5bdf42015-04-01 21:02:57 -040091unsigned int crystal_hz;
92unsigned long long tsc_hz;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -040093int base_cpu;
Len Brown21ed5572015-10-19 22:37:40 -040094double discover_bclk(unsigned int family, unsigned int model);
Len Brown7f5c2582015-12-01 01:36:39 -050095unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
96 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
97unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
98unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
99unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
100unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
Len Brown33148d62017-01-21 01:26:16 -0500101unsigned int has_misc_feature_control;
Len Brown889facb2012-11-08 00:48:57 -0500102
Len Browne6f9bb32013-12-03 02:19:19 -0500103#define RAPL_PKG (1 << 0)
104 /* 0x610 MSR_PKG_POWER_LIMIT */
105 /* 0x611 MSR_PKG_ENERGY_STATUS */
106#define RAPL_PKG_PERF_STATUS (1 << 1)
107 /* 0x613 MSR_PKG_PERF_STATUS */
108#define RAPL_PKG_POWER_INFO (1 << 2)
109 /* 0x614 MSR_PKG_POWER_INFO */
110
111#define RAPL_DRAM (1 << 3)
112 /* 0x618 MSR_DRAM_POWER_LIMIT */
113 /* 0x619 MSR_DRAM_ENERGY_STATUS */
Len Browne6f9bb32013-12-03 02:19:19 -0500114#define RAPL_DRAM_PERF_STATUS (1 << 4)
115 /* 0x61b MSR_DRAM_PERF_STATUS */
Len Brown0b2bb692015-03-26 00:50:30 -0400116#define RAPL_DRAM_POWER_INFO (1 << 5)
117 /* 0x61c MSR_DRAM_POWER_INFO */
Len Browne6f9bb32013-12-03 02:19:19 -0500118
Jacob Pan91484942016-06-16 09:48:20 -0700119#define RAPL_CORES_POWER_LIMIT (1 << 6)
Len Browne6f9bb32013-12-03 02:19:19 -0500120 /* 0x638 MSR_PP0_POWER_LIMIT */
Len Brown0b2bb692015-03-26 00:50:30 -0400121#define RAPL_CORE_POLICY (1 << 7)
Len Browne6f9bb32013-12-03 02:19:19 -0500122 /* 0x63a MSR_PP0_POLICY */
123
Len Brown0b2bb692015-03-26 00:50:30 -0400124#define RAPL_GFX (1 << 8)
Len Browne6f9bb32013-12-03 02:19:19 -0500125 /* 0x640 MSR_PP1_POWER_LIMIT */
126 /* 0x641 MSR_PP1_ENERGY_STATUS */
127 /* 0x642 MSR_PP1_POLICY */
Jacob Pan91484942016-06-16 09:48:20 -0700128
129#define RAPL_CORES_ENERGY_STATUS (1 << 9)
130 /* 0x639 MSR_PP0_ENERGY_STATUS */
131#define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
Len Brown889facb2012-11-08 00:48:57 -0500132#define TJMAX_DEFAULT 100
133
134#define MAX(a, b) ((a) > (b) ? (a) : (b))
Len Brown103a8fe2010-10-22 23:53:03 -0400135
Len Brown388e9c82016-12-22 23:57:55 -0500136/*
137 * buffer size used by sscanf() for added column names
138 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
139 */
140#define NAME_BYTES 20
Len Brown495c76542017-02-08 02:41:51 -0500141#define PATH_BYTES 128
Len Brown388e9c82016-12-22 23:57:55 -0500142
Len Brown103a8fe2010-10-22 23:53:03 -0400143int backwards_count;
144char *progname;
Len Brown103a8fe2010-10-22 23:53:03 -0400145
Len Brown1ef7d212017-02-10 23:54:15 -0500146#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
147cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset;
148size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
Len Brown678a3bd2017-02-09 22:22:13 -0500149#define MAX_ADDED_COUNTERS 16
Len Brown103a8fe2010-10-22 23:53:03 -0400150
Len Brownc98d5d92012-06-04 00:56:40 -0400151struct thread_data {
152 unsigned long long tsc;
153 unsigned long long aperf;
154 unsigned long long mperf;
Len Brown144b44b2013-11-09 00:30:16 -0500155 unsigned long long c1;
Len Brown562a2d32016-02-26 23:48:05 -0500156 unsigned int irq_count;
Len Brown1ed51012013-02-10 17:19:24 -0500157 unsigned int smi_count;
Len Brownc98d5d92012-06-04 00:56:40 -0400158 unsigned int cpu_id;
159 unsigned int flags;
160#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
161#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
Len Brown678a3bd2017-02-09 22:22:13 -0500162 unsigned long long counter[MAX_ADDED_COUNTERS];
Len Brownc98d5d92012-06-04 00:56:40 -0400163} *thread_even, *thread_odd;
Len Brown103a8fe2010-10-22 23:53:03 -0400164
Len Brownc98d5d92012-06-04 00:56:40 -0400165struct core_data {
166 unsigned long long c3;
167 unsigned long long c6;
168 unsigned long long c7;
Len Brown0539ba12017-02-10 00:27:20 -0500169 unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */
Len Brown889facb2012-11-08 00:48:57 -0500170 unsigned int core_temp_c;
Len Brownc98d5d92012-06-04 00:56:40 -0400171 unsigned int core_id;
Len Brown678a3bd2017-02-09 22:22:13 -0500172 unsigned long long counter[MAX_ADDED_COUNTERS];
Len Brownc98d5d92012-06-04 00:56:40 -0400173} *core_even, *core_odd;
Len Brown103a8fe2010-10-22 23:53:03 -0400174
Len Brownc98d5d92012-06-04 00:56:40 -0400175struct pkg_data {
176 unsigned long long pc2;
177 unsigned long long pc3;
178 unsigned long long pc6;
179 unsigned long long pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800180 unsigned long long pc8;
181 unsigned long long pc9;
182 unsigned long long pc10;
Len Brown0b2bb692015-03-26 00:50:30 -0400183 unsigned long long pkg_wtd_core_c0;
184 unsigned long long pkg_any_core_c0;
185 unsigned long long pkg_any_gfxe_c0;
186 unsigned long long pkg_both_core_gfxe_c0;
Len Brown9185e982016-04-06 17:16:00 -0400187 long long gfx_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -0500188 unsigned int gfx_mhz;
Len Brownc98d5d92012-06-04 00:56:40 -0400189 unsigned int package_id;
Len Brown889facb2012-11-08 00:48:57 -0500190 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
191 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
192 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
193 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
194 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
195 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
196 unsigned int pkg_temp_c;
Len Brown678a3bd2017-02-09 22:22:13 -0500197 unsigned long long counter[MAX_ADDED_COUNTERS];
Len Brownc98d5d92012-06-04 00:56:40 -0400198} *package_even, *package_odd;
199
200#define ODD_COUNTERS thread_odd, core_odd, package_odd
201#define EVEN_COUNTERS thread_even, core_even, package_even
202
203#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \
204 (thread_base + (pkg_no) * topo.num_cores_per_pkg * \
205 topo.num_threads_per_core + \
206 (core_no) * topo.num_threads_per_core + (thread_no))
207#define GET_CORE(core_base, core_no, pkg_no) \
208 (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no))
209#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
210
Len Brown388e9c82016-12-22 23:57:55 -0500211enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE};
Len Brown41618e62017-02-09 18:25:22 -0500212enum counter_type {COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC};
Len Brown388e9c82016-12-22 23:57:55 -0500213enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT};
214
215struct msr_counter {
216 unsigned int msr_num;
217 char name[NAME_BYTES];
Len Brown495c76542017-02-08 02:41:51 -0500218 char path[PATH_BYTES];
Len Brown388e9c82016-12-22 23:57:55 -0500219 unsigned int width;
220 enum counter_type type;
221 enum counter_format format;
222 struct msr_counter *next;
Len Brown812db3f2017-02-10 00:25:41 -0500223 unsigned int flags;
224#define FLAGS_HIDE (1 << 0)
225#define FLAGS_SHOW (1 << 1)
Len Brown41618e62017-02-09 18:25:22 -0500226#define SYSFS_PERCPU (1 << 1)
Len Brown388e9c82016-12-22 23:57:55 -0500227};
228
229struct sys_counters {
Len Brown678a3bd2017-02-09 22:22:13 -0500230 unsigned int added_thread_counters;
231 unsigned int added_core_counters;
232 unsigned int added_package_counters;
Len Brown388e9c82016-12-22 23:57:55 -0500233 struct msr_counter *tp;
234 struct msr_counter *cp;
235 struct msr_counter *pp;
236} sys;
237
Len Brownc98d5d92012-06-04 00:56:40 -0400238struct system_summary {
239 struct thread_data threads;
240 struct core_data cores;
241 struct pkg_data packages;
Len Brown388e9c82016-12-22 23:57:55 -0500242} average;
Len Brownc98d5d92012-06-04 00:56:40 -0400243
244
245struct topo_params {
246 int num_packages;
247 int num_cpus;
248 int num_cores;
249 int max_cpu_num;
250 int num_cores_per_pkg;
251 int num_threads_per_core;
252} topo;
253
254struct timeval tv_even, tv_odd, tv_delta;
255
Len Brown562a2d32016-02-26 23:48:05 -0500256int *irq_column_2_cpu; /* /proc/interrupts column numbers */
257int *irqs_per_cpu; /* indexed by cpu_num */
258
Len Brownc98d5d92012-06-04 00:56:40 -0400259void setup_all_buffers(void);
260
261int cpu_is_not_present(int cpu)
Len Brownd15cf7c2012-06-03 23:24:00 -0400262{
Len Brownc98d5d92012-06-04 00:56:40 -0400263 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brownd15cf7c2012-06-03 23:24:00 -0400264}
Len Brown88c32812012-03-29 21:44:40 -0400265/*
Len Brownc98d5d92012-06-04 00:56:40 -0400266 * run func(thread, core, package) in topology order
267 * skip non-present cpus
Len Brown88c32812012-03-29 21:44:40 -0400268 */
Len Brownd15cf7c2012-06-03 23:24:00 -0400269
Len Brownc98d5d92012-06-04 00:56:40 -0400270int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
271 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
Len Brown88c32812012-03-29 21:44:40 -0400272{
Len Brownc98d5d92012-06-04 00:56:40 -0400273 int retval, pkg_no, core_no, thread_no;
274
275 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
276 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
277 for (thread_no = 0; thread_no <
278 topo.num_threads_per_core; ++thread_no) {
279 struct thread_data *t;
280 struct core_data *c;
281 struct pkg_data *p;
282
283 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
284
285 if (cpu_is_not_present(t->cpu_id))
286 continue;
287
288 c = GET_CORE(core_base, core_no, pkg_no);
289 p = GET_PKG(pkg_base, pkg_no);
290
291 retval = func(t, c, p);
292 if (retval)
293 return retval;
294 }
295 }
296 }
297 return 0;
Len Brown88c32812012-03-29 21:44:40 -0400298}
299
300int cpu_migrate(int cpu)
301{
Len Brownc98d5d92012-06-04 00:56:40 -0400302 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
303 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
304 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
Len Brown88c32812012-03-29 21:44:40 -0400305 return -1;
306 else
307 return 0;
308}
Len Brown36229892016-02-26 20:51:02 -0500309int get_msr_fd(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -0400310{
Len Brown103a8fe2010-10-22 23:53:03 -0400311 char pathname[32];
312 int fd;
313
Len Brown36229892016-02-26 20:51:02 -0500314 fd = fd_percpu[cpu];
315
316 if (fd)
317 return fd;
318
Len Brown103a8fe2010-10-22 23:53:03 -0400319 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
320 fd = open(pathname, O_RDONLY);
Len Brown15aaa342012-03-29 22:19:58 -0400321 if (fd < 0)
Len Brown98481e72014-08-15 00:36:50 -0400322 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 -0400323
Len Brown36229892016-02-26 20:51:02 -0500324 fd_percpu[cpu] = fd;
325
326 return fd;
327}
328
329int get_msr(int cpu, off_t offset, unsigned long long *msr)
330{
331 ssize_t retval;
332
333 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
Len Brown15aaa342012-03-29 22:19:58 -0400334
Len Brown98481e72014-08-15 00:36:50 -0400335 if (retval != sizeof *msr)
Len Browncf4cbe52017-01-01 13:08:33 -0500336 err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
Len Brown15aaa342012-03-29 22:19:58 -0400337
338 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400339}
340
Len Brownfc04cc62014-02-06 00:55:19 -0500341/*
Len Brown812db3f2017-02-10 00:25:41 -0500342 * Each string in this array is compared in --show and --hide cmdline.
343 * Thus, strings that are proper sub-sets must follow their more specific peers.
Len Brownfc04cc62014-02-06 00:55:19 -0500344 */
Len Brown812db3f2017-02-10 00:25:41 -0500345struct msr_counter bic[] = {
346 { 0x0, "Package" },
347 { 0x0, "Avg_MHz" },
348 { 0x0, "Bzy_MHz" },
349 { 0x0, "TSC_MHz" },
350 { 0x0, "IRQ" },
Len Brown495c76542017-02-08 02:41:51 -0500351 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL},
Len Brown812db3f2017-02-10 00:25:41 -0500352 { 0x0, "Busy%" },
353 { 0x0, "CPU%c1" },
354 { 0x0, "CPU%c3" },
355 { 0x0, "CPU%c6" },
356 { 0x0, "CPU%c7" },
357 { 0x0, "ThreadC" },
358 { 0x0, "CoreTmp" },
359 { 0x0, "CoreCnt" },
360 { 0x0, "PkgTmp" },
361 { 0x0, "GFX%rc6" },
362 { 0x0, "GFXMHz" },
363 { 0x0, "Pkg%pc2" },
364 { 0x0, "Pkg%pc3" },
365 { 0x0, "Pkg%pc6" },
366 { 0x0, "Pkg%pc7" },
Len Brown0f47c082017-01-27 00:50:45 -0500367 { 0x0, "Pkg%pc8" },
368 { 0x0, "Pkg%pc9" },
369 { 0x0, "Pkg%pc10" },
Len Brown812db3f2017-02-10 00:25:41 -0500370 { 0x0, "PkgWatt" },
371 { 0x0, "CorWatt" },
372 { 0x0, "GFXWatt" },
373 { 0x0, "PkgCnt" },
374 { 0x0, "RAMWatt" },
375 { 0x0, "PKG_%" },
376 { 0x0, "RAM_%" },
377 { 0x0, "Pkg_J" },
378 { 0x0, "Cor_J" },
379 { 0x0, "GFX_J" },
380 { 0x0, "RAM_J" },
381 { 0x0, "Core" },
382 { 0x0, "CPU" },
Len Brown0539ba12017-02-10 00:27:20 -0500383 { 0x0, "Mod%c6" },
Len Brown41618e62017-02-09 18:25:22 -0500384 { 0x0, "sysfs" },
Len Brown812db3f2017-02-10 00:25:41 -0500385};
386
387#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
388#define BIC_Package (1ULL << 0)
389#define BIC_Avg_MHz (1ULL << 1)
390#define BIC_Bzy_MHz (1ULL << 2)
391#define BIC_TSC_MHz (1ULL << 3)
392#define BIC_IRQ (1ULL << 4)
393#define BIC_SMI (1ULL << 5)
394#define BIC_Busy (1ULL << 6)
395#define BIC_CPU_c1 (1ULL << 7)
396#define BIC_CPU_c3 (1ULL << 8)
397#define BIC_CPU_c6 (1ULL << 9)
398#define BIC_CPU_c7 (1ULL << 10)
399#define BIC_ThreadC (1ULL << 11)
400#define BIC_CoreTmp (1ULL << 12)
401#define BIC_CoreCnt (1ULL << 13)
402#define BIC_PkgTmp (1ULL << 14)
403#define BIC_GFX_rc6 (1ULL << 15)
404#define BIC_GFXMHz (1ULL << 16)
405#define BIC_Pkgpc2 (1ULL << 17)
406#define BIC_Pkgpc3 (1ULL << 18)
407#define BIC_Pkgpc6 (1ULL << 19)
408#define BIC_Pkgpc7 (1ULL << 20)
Len Brown0f47c082017-01-27 00:50:45 -0500409#define BIC_Pkgpc8 (1ULL << 21)
410#define BIC_Pkgpc9 (1ULL << 22)
411#define BIC_Pkgpc10 (1ULL << 23)
412#define BIC_PkgWatt (1ULL << 24)
413#define BIC_CorWatt (1ULL << 25)
414#define BIC_GFXWatt (1ULL << 26)
415#define BIC_PkgCnt (1ULL << 27)
416#define BIC_RAMWatt (1ULL << 28)
417#define BIC_PKG__ (1ULL << 29)
418#define BIC_RAM__ (1ULL << 30)
419#define BIC_Pkg_J (1ULL << 31)
420#define BIC_Cor_J (1ULL << 32)
421#define BIC_GFX_J (1ULL << 33)
422#define BIC_RAM_J (1ULL << 34)
423#define BIC_Core (1ULL << 35)
424#define BIC_CPU (1ULL << 36)
425#define BIC_Mod_c6 (1ULL << 37)
Len Brown41618e62017-02-09 18:25:22 -0500426#define BIC_sysfs (1ULL << 38)
Len Brown812db3f2017-02-10 00:25:41 -0500427
428unsigned long long bic_enabled = 0xFFFFFFFFFFFFFFFFULL;
Len Brown41618e62017-02-09 18:25:22 -0500429unsigned long long bic_present = BIC_sysfs;
Len Brown812db3f2017-02-10 00:25:41 -0500430
431#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
432#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
Len Brown0f47c082017-01-27 00:50:45 -0500433#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
Len Brown812db3f2017-02-10 00:25:41 -0500434
435/*
436 * bic_lookup
437 * for all the strings in comma separate name_list,
438 * set the approprate bit in return value.
439 */
440unsigned long long bic_lookup(char *name_list)
441{
442 int i;
443 unsigned long long retval = 0;
444
445 while (name_list) {
446 char *comma;
447
448 comma = strchr(name_list, ',');
449
450 if (comma)
451 *comma = '\0';
452
453 for (i = 0; i < MAX_BIC; ++i) {
454 if (!strcmp(name_list, bic[i].name)) {
455 retval |= (1ULL << i);
456 break;
457 }
458 }
459 if (i == MAX_BIC) {
460 fprintf(stderr, "Invalid counter name: %s\n", name_list);
461 exit(-1);
462 }
463
464 name_list = comma;
465 if (name_list)
466 name_list++;
467
468 }
469 return retval;
470}
Len Brownfc04cc62014-02-06 00:55:19 -0500471
Len Browna829eb42011-02-10 23:36:34 -0500472void print_header(void)
Len Brown103a8fe2010-10-22 23:53:03 -0400473{
Len Brown388e9c82016-12-22 23:57:55 -0500474 struct msr_counter *mp;
475
Len Brown812db3f2017-02-10 00:25:41 -0500476 if (DO_BIC(BIC_Package))
Len Brown3d109de2016-04-22 23:24:27 -0400477 outp += sprintf(outp, "\tPackage");
Len Brown812db3f2017-02-10 00:25:41 -0500478 if (DO_BIC(BIC_Core))
Len Brown3d109de2016-04-22 23:24:27 -0400479 outp += sprintf(outp, "\tCore");
Len Brown812db3f2017-02-10 00:25:41 -0500480 if (DO_BIC(BIC_CPU))
Len Brown3d109de2016-04-22 23:24:27 -0400481 outp += sprintf(outp, "\tCPU");
Len Brown812db3f2017-02-10 00:25:41 -0500482 if (DO_BIC(BIC_Avg_MHz))
Len Brown3d109de2016-04-22 23:24:27 -0400483 outp += sprintf(outp, "\tAvg_MHz");
Len Brown812db3f2017-02-10 00:25:41 -0500484 if (DO_BIC(BIC_Busy))
Len Brown3d109de2016-04-22 23:24:27 -0400485 outp += sprintf(outp, "\tBusy%%");
Len Brown812db3f2017-02-10 00:25:41 -0500486 if (DO_BIC(BIC_Bzy_MHz))
Len Brown3d109de2016-04-22 23:24:27 -0400487 outp += sprintf(outp, "\tBzy_MHz");
Len Brown812db3f2017-02-10 00:25:41 -0500488 if (DO_BIC(BIC_TSC_MHz))
489 outp += sprintf(outp, "\tTSC_MHz");
Len Brown1cc21f72015-02-23 00:34:57 -0500490
Len Brown812db3f2017-02-10 00:25:41 -0500491 if (DO_BIC(BIC_IRQ))
Len Brown3d109de2016-04-22 23:24:27 -0400492 outp += sprintf(outp, "\tIRQ");
Len Brown812db3f2017-02-10 00:25:41 -0500493 if (DO_BIC(BIC_SMI))
Len Brown3d109de2016-04-22 23:24:27 -0400494 outp += sprintf(outp, "\tSMI");
Len Brown1cc21f72015-02-23 00:34:57 -0500495
Len Brown388e9c82016-12-22 23:57:55 -0500496 for (mp = sys.tp; mp; mp = mp->next) {
497 if (mp->format == FORMAT_RAW) {
498 if (mp->width == 64)
499 outp += sprintf(outp, "\t%18.18s", mp->name);
500 else
501 outp += sprintf(outp, "\t%10.10s", mp->name);
502 } else {
Len Brown41618e62017-02-09 18:25:22 -0500503 outp += sprintf(outp, "\t%s", mp->name);
Len Brown388e9c82016-12-22 23:57:55 -0500504 }
505 }
506
Len Brown41618e62017-02-09 18:25:22 -0500507 if (DO_BIC(BIC_CPU_c1))
508 outp += sprintf(outp, "\tCPU%%c1");
Len Brown812db3f2017-02-10 00:25:41 -0500509 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates)
Len Brown678a3bd2017-02-09 22:22:13 -0500510 outp += sprintf(outp, "\tCPU%%c3");
Len Brown812db3f2017-02-10 00:25:41 -0500511 if (DO_BIC(BIC_CPU_c6))
Len Brown678a3bd2017-02-09 22:22:13 -0500512 outp += sprintf(outp, "\tCPU%%c6");
Len Brown812db3f2017-02-10 00:25:41 -0500513 if (DO_BIC(BIC_CPU_c7))
Len Brown678a3bd2017-02-09 22:22:13 -0500514 outp += sprintf(outp, "\tCPU%%c7");
515
Len Brown0539ba12017-02-10 00:27:20 -0500516 if (DO_BIC(BIC_Mod_c6))
517 outp += sprintf(outp, "\tMod%%c6");
Len Brown678a3bd2017-02-09 22:22:13 -0500518
Len Brown812db3f2017-02-10 00:25:41 -0500519 if (DO_BIC(BIC_CoreTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400520 outp += sprintf(outp, "\tCoreTmp");
Len Brown388e9c82016-12-22 23:57:55 -0500521
522 for (mp = sys.cp; mp; mp = mp->next) {
523 if (mp->format == FORMAT_RAW) {
524 if (mp->width == 64)
525 outp += sprintf(outp, "\t%18.18s", mp->name);
526 else
527 outp += sprintf(outp, "\t%10.10s", mp->name);
528 } else {
Len Brown41618e62017-02-09 18:25:22 -0500529 outp += sprintf(outp, "\t%s", mp->name);
Len Brown388e9c82016-12-22 23:57:55 -0500530 }
531 }
532
Len Brown812db3f2017-02-10 00:25:41 -0500533 if (DO_BIC(BIC_PkgTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400534 outp += sprintf(outp, "\tPkgTmp");
Len Brown889facb2012-11-08 00:48:57 -0500535
Len Brown812db3f2017-02-10 00:25:41 -0500536 if (DO_BIC(BIC_GFX_rc6))
Len Brown3d109de2016-04-22 23:24:27 -0400537 outp += sprintf(outp, "\tGFX%%rc6");
Len Brownfdf676e2016-02-27 01:28:12 -0500538
Len Brown812db3f2017-02-10 00:25:41 -0500539 if (DO_BIC(BIC_GFXMHz))
Len Brown3d109de2016-04-22 23:24:27 -0400540 outp += sprintf(outp, "\tGFXMHz");
Len Brown27d47352016-02-27 00:37:54 -0500541
Len Brown0b2bb692015-03-26 00:50:30 -0400542 if (do_skl_residency) {
Len Brown3d109de2016-04-22 23:24:27 -0400543 outp += sprintf(outp, "\tTotl%%C0");
544 outp += sprintf(outp, "\tAny%%C0");
545 outp += sprintf(outp, "\tGFX%%C0");
546 outp += sprintf(outp, "\tCPUGFX%%");
Len Brown0b2bb692015-03-26 00:50:30 -0400547 }
548
Len Brown0f47c082017-01-27 00:50:45 -0500549 if (DO_BIC(BIC_Pkgpc2))
Len Brown3d109de2016-04-22 23:24:27 -0400550 outp += sprintf(outp, "\tPkg%%pc2");
Len Brown0f47c082017-01-27 00:50:45 -0500551 if (DO_BIC(BIC_Pkgpc3))
Len Brown3d109de2016-04-22 23:24:27 -0400552 outp += sprintf(outp, "\tPkg%%pc3");
Len Brown0f47c082017-01-27 00:50:45 -0500553 if (DO_BIC(BIC_Pkgpc6))
Len Brown3d109de2016-04-22 23:24:27 -0400554 outp += sprintf(outp, "\tPkg%%pc6");
Len Brown0f47c082017-01-27 00:50:45 -0500555 if (DO_BIC(BIC_Pkgpc7))
Len Brown3d109de2016-04-22 23:24:27 -0400556 outp += sprintf(outp, "\tPkg%%pc7");
Len Brown0f47c082017-01-27 00:50:45 -0500557 if (DO_BIC(BIC_Pkgpc8))
Len Brown3d109de2016-04-22 23:24:27 -0400558 outp += sprintf(outp, "\tPkg%%pc8");
Len Brown0f47c082017-01-27 00:50:45 -0500559 if (DO_BIC(BIC_Pkgpc9))
Len Brown3d109de2016-04-22 23:24:27 -0400560 outp += sprintf(outp, "\tPkg%%pc9");
Len Brown0f47c082017-01-27 00:50:45 -0500561 if (DO_BIC(BIC_Pkgpc10))
Len Brown3d109de2016-04-22 23:24:27 -0400562 outp += sprintf(outp, "\tPk%%pc10");
Len Brown103a8fe2010-10-22 23:53:03 -0400563
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800564 if (do_rapl && !rapl_joules) {
Len Brown812db3f2017-02-10 00:25:41 -0500565 if (DO_BIC(BIC_PkgWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400566 outp += sprintf(outp, "\tPkgWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500567 if (DO_BIC(BIC_CorWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400568 outp += sprintf(outp, "\tCorWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500569 if (DO_BIC(BIC_GFXWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400570 outp += sprintf(outp, "\tGFXWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500571 if (DO_BIC(BIC_RAMWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400572 outp += sprintf(outp, "\tRAMWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500573 if (DO_BIC(BIC_PKG__))
Len Brown3d109de2016-04-22 23:24:27 -0400574 outp += sprintf(outp, "\tPKG_%%");
Len Brown812db3f2017-02-10 00:25:41 -0500575 if (DO_BIC(BIC_RAM__))
Len Brown3d109de2016-04-22 23:24:27 -0400576 outp += sprintf(outp, "\tRAM_%%");
Len Brownd7899442015-01-23 00:12:33 -0500577 } else if (do_rapl && rapl_joules) {
Len Brown812db3f2017-02-10 00:25:41 -0500578 if (DO_BIC(BIC_Pkg_J))
Len Brown3d109de2016-04-22 23:24:27 -0400579 outp += sprintf(outp, "\tPkg_J");
Len Brown812db3f2017-02-10 00:25:41 -0500580 if (DO_BIC(BIC_Cor_J))
Len Brown3d109de2016-04-22 23:24:27 -0400581 outp += sprintf(outp, "\tCor_J");
Len Brown812db3f2017-02-10 00:25:41 -0500582 if (DO_BIC(BIC_GFX_J))
Len Brown3d109de2016-04-22 23:24:27 -0400583 outp += sprintf(outp, "\tGFX_J");
Len Brown812db3f2017-02-10 00:25:41 -0500584 if (DO_BIC(BIC_RAM_J))
Len Brown3d109de2016-04-22 23:24:27 -0400585 outp += sprintf(outp, "\tRAM_J");
Len Brown812db3f2017-02-10 00:25:41 -0500586 if (DO_BIC(BIC_PKG__))
Len Brown3d109de2016-04-22 23:24:27 -0400587 outp += sprintf(outp, "\tPKG_%%");
Len Brown812db3f2017-02-10 00:25:41 -0500588 if (DO_BIC(BIC_RAM__))
Len Brown3d109de2016-04-22 23:24:27 -0400589 outp += sprintf(outp, "\tRAM_%%");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800590 }
Len Brown388e9c82016-12-22 23:57:55 -0500591 for (mp = sys.pp; mp; mp = mp->next) {
592 if (mp->format == FORMAT_RAW) {
593 if (mp->width == 64)
594 outp += sprintf(outp, "\t%18.18s", mp->name);
595 else
596 outp += sprintf(outp, "\t%10.10s", mp->name);
597 } else {
Len Brown41618e62017-02-09 18:25:22 -0500598 outp += sprintf(outp, "\t%s", mp->name);
Len Brown388e9c82016-12-22 23:57:55 -0500599 }
600 }
601
Len Brownc98d5d92012-06-04 00:56:40 -0400602 outp += sprintf(outp, "\n");
Len Brown103a8fe2010-10-22 23:53:03 -0400603}
604
Len Brownc98d5d92012-06-04 00:56:40 -0400605int dump_counters(struct thread_data *t, struct core_data *c,
606 struct pkg_data *p)
Len Brown103a8fe2010-10-22 23:53:03 -0400607{
Len Brown388e9c82016-12-22 23:57:55 -0500608 int i;
609 struct msr_counter *mp;
610
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200611 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
Len Brown103a8fe2010-10-22 23:53:03 -0400612
Len Brownc98d5d92012-06-04 00:56:40 -0400613 if (t) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200614 outp += sprintf(outp, "CPU: %d flags 0x%x\n",
615 t->cpu_id, t->flags);
616 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
617 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
618 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
619 outp += sprintf(outp, "c1: %016llX\n", t->c1);
Len Brown6886fee2016-12-24 15:18:37 -0500620
Len Brown812db3f2017-02-10 00:25:41 -0500621 if (DO_BIC(BIC_IRQ))
Len Brown562a2d32016-02-26 23:48:05 -0500622 outp += sprintf(outp, "IRQ: %08X\n", t->irq_count);
Len Brown812db3f2017-02-10 00:25:41 -0500623 if (DO_BIC(BIC_SMI))
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200624 outp += sprintf(outp, "SMI: %08X\n", t->smi_count);
Len Brown388e9c82016-12-22 23:57:55 -0500625
626 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
627 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n",
628 i, mp->msr_num, t->counter[i]);
629 }
Len Brownc98d5d92012-06-04 00:56:40 -0400630 }
Len Brown103a8fe2010-10-22 23:53:03 -0400631
Len Brownc98d5d92012-06-04 00:56:40 -0400632 if (c) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200633 outp += sprintf(outp, "core: %d\n", c->core_id);
634 outp += sprintf(outp, "c3: %016llX\n", c->c3);
635 outp += sprintf(outp, "c6: %016llX\n", c->c6);
636 outp += sprintf(outp, "c7: %016llX\n", c->c7);
637 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
Len Brown388e9c82016-12-22 23:57:55 -0500638
639 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
640 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n",
641 i, mp->msr_num, c->counter[i]);
642 }
Len Brown0539ba12017-02-10 00:27:20 -0500643 outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
Len Brownc98d5d92012-06-04 00:56:40 -0400644 }
645
646 if (p) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200647 outp += sprintf(outp, "package: %d\n", p->package_id);
Len Brown0b2bb692015-03-26 00:50:30 -0400648
649 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
650 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
651 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
652 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
653
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200654 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
Len Brown0f47c082017-01-27 00:50:45 -0500655 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -0500656 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
Len Brown0f47c082017-01-27 00:50:45 -0500657 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -0500658 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
Len Brown0f47c082017-01-27 00:50:45 -0500659 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -0500660 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200661 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
662 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
663 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
664 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
665 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores);
666 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx);
667 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram);
668 outp += sprintf(outp, "Throttle PKG: %0X\n",
669 p->rapl_pkg_perf_status);
670 outp += sprintf(outp, "Throttle RAM: %0X\n",
671 p->rapl_dram_perf_status);
672 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
Len Brown388e9c82016-12-22 23:57:55 -0500673
674 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
675 outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n",
676 i, mp->msr_num, p->counter[i]);
677 }
Len Brownc98d5d92012-06-04 00:56:40 -0400678 }
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200679
680 outp += sprintf(outp, "\n");
681
Len Brownc98d5d92012-06-04 00:56:40 -0400682 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400683}
684
Len Browne23da032012-02-06 18:37:16 -0500685/*
686 * column formatting convention & formats
Len Browne23da032012-02-06 18:37:16 -0500687 */
Len Brownc98d5d92012-06-04 00:56:40 -0400688int format_counters(struct thread_data *t, struct core_data *c,
689 struct pkg_data *p)
Len Brown103a8fe2010-10-22 23:53:03 -0400690{
Len Brown008d396e2017-02-10 00:29:51 -0500691 double interval_float, tsc;
Len Brownfc04cc62014-02-06 00:55:19 -0500692 char *fmt8;
Len Brown388e9c82016-12-22 23:57:55 -0500693 int i;
694 struct msr_counter *mp;
Len Brown103a8fe2010-10-22 23:53:03 -0400695
Len Brownc98d5d92012-06-04 00:56:40 -0400696 /* if showing only 1st thread in core and this isn't one, bail out */
697 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
698 return 0;
699
700 /* if showing only 1st thread in pkg and this isn't one, bail out */
701 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
702 return 0;
703
Len Brown1ef7d212017-02-10 23:54:15 -0500704 /*if not summary line and --cpu is used */
705 if ((t != &average.threads) &&
706 (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
707 return 0;
708
Len Brown103a8fe2010-10-22 23:53:03 -0400709 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
710
Len Brown008d396e2017-02-10 00:29:51 -0500711 tsc = t->tsc * tsc_tweak;
712
Len Brownc98d5d92012-06-04 00:56:40 -0400713 /* topo columns, print blanks on 1st (average) line */
714 if (t == &average.threads) {
Len Brown812db3f2017-02-10 00:25:41 -0500715 if (DO_BIC(BIC_Package))
Len Brown3d109de2016-04-22 23:24:27 -0400716 outp += sprintf(outp, "\t-");
Len Brown812db3f2017-02-10 00:25:41 -0500717 if (DO_BIC(BIC_Core))
Len Brown3d109de2016-04-22 23:24:27 -0400718 outp += sprintf(outp, "\t-");
Len Brown812db3f2017-02-10 00:25:41 -0500719 if (DO_BIC(BIC_CPU))
Len Brown3d109de2016-04-22 23:24:27 -0400720 outp += sprintf(outp, "\t-");
Len Brown103a8fe2010-10-22 23:53:03 -0400721 } else {
Len Brown812db3f2017-02-10 00:25:41 -0500722 if (DO_BIC(BIC_Package)) {
Len Brownc98d5d92012-06-04 00:56:40 -0400723 if (p)
Len Brown3d109de2016-04-22 23:24:27 -0400724 outp += sprintf(outp, "\t%d", p->package_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400725 else
Len Brown3d109de2016-04-22 23:24:27 -0400726 outp += sprintf(outp, "\t-");
Len Brownc98d5d92012-06-04 00:56:40 -0400727 }
Len Brown812db3f2017-02-10 00:25:41 -0500728 if (DO_BIC(BIC_Core)) {
Len Brownc98d5d92012-06-04 00:56:40 -0400729 if (c)
Len Brown3d109de2016-04-22 23:24:27 -0400730 outp += sprintf(outp, "\t%d", c->core_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400731 else
Len Brown3d109de2016-04-22 23:24:27 -0400732 outp += sprintf(outp, "\t-");
Len Brownc98d5d92012-06-04 00:56:40 -0400733 }
Len Brown812db3f2017-02-10 00:25:41 -0500734 if (DO_BIC(BIC_CPU))
Len Brown3d109de2016-04-22 23:24:27 -0400735 outp += sprintf(outp, "\t%d", t->cpu_id);
Len Brown103a8fe2010-10-22 23:53:03 -0400736 }
Len Brownfc04cc62014-02-06 00:55:19 -0500737
Len Brown812db3f2017-02-10 00:25:41 -0500738 if (DO_BIC(BIC_Avg_MHz))
Len Brown3d109de2016-04-22 23:24:27 -0400739 outp += sprintf(outp, "\t%.0f",
Len Brownfc04cc62014-02-06 00:55:19 -0500740 1.0 / units * t->aperf / interval_float);
741
Len Brown812db3f2017-02-10 00:25:41 -0500742 if (DO_BIC(BIC_Busy))
Len Brown008d396e2017-02-10 00:29:51 -0500743 outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/tsc);
Len Brown103a8fe2010-10-22 23:53:03 -0400744
Len Brown812db3f2017-02-10 00:25:41 -0500745 if (DO_BIC(BIC_Bzy_MHz)) {
Len Brown21ed5572015-10-19 22:37:40 -0400746 if (has_base_hz)
Len Brown3d109de2016-04-22 23:24:27 -0400747 outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf);
Len Brown21ed5572015-10-19 22:37:40 -0400748 else
Len Brown3d109de2016-04-22 23:24:27 -0400749 outp += sprintf(outp, "\t%.0f",
Len Brown008d396e2017-02-10 00:29:51 -0500750 tsc / units * t->aperf / t->mperf / interval_float);
Len Brown21ed5572015-10-19 22:37:40 -0400751 }
Len Brown103a8fe2010-10-22 23:53:03 -0400752
Len Brown812db3f2017-02-10 00:25:41 -0500753 if (DO_BIC(BIC_TSC_MHz))
754 outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float);
Len Brown103a8fe2010-10-22 23:53:03 -0400755
Len Brown562a2d32016-02-26 23:48:05 -0500756 /* IRQ */
Len Brown812db3f2017-02-10 00:25:41 -0500757 if (DO_BIC(BIC_IRQ))
Len Brown3d109de2016-04-22 23:24:27 -0400758 outp += sprintf(outp, "\t%d", t->irq_count);
Len Brown562a2d32016-02-26 23:48:05 -0500759
Len Brown1cc21f72015-02-23 00:34:57 -0500760 /* SMI */
Len Brown812db3f2017-02-10 00:25:41 -0500761 if (DO_BIC(BIC_SMI))
Len Brown3d109de2016-04-22 23:24:27 -0400762 outp += sprintf(outp, "\t%d", t->smi_count);
Len Brown1cc21f72015-02-23 00:34:57 -0500763
Len Brown678a3bd2017-02-09 22:22:13 -0500764 /* Added counters */
765 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
766 if (mp->format == FORMAT_RAW) {
767 if (mp->width == 32)
768 outp += sprintf(outp, "\t0x%08lx", (unsigned long) t->counter[i]);
769 else
770 outp += sprintf(outp, "\t0x%016llx", t->counter[i]);
771 } else if (mp->format == FORMAT_DELTA) {
772 outp += sprintf(outp, "\t%lld", t->counter[i]);
773 } else if (mp->format == FORMAT_PERCENT) {
Len Brown41618e62017-02-09 18:25:22 -0500774 if (mp->type == COUNTER_USEC)
775 outp += sprintf(outp, "\t%.2f", t->counter[i]/interval_float/10000);
776 else
777 outp += sprintf(outp, "\t%.2f", 100.0 * t->counter[i]/tsc);
Len Brown678a3bd2017-02-09 22:22:13 -0500778 }
779 }
780
Len Brown41618e62017-02-09 18:25:22 -0500781 /* C1 */
782 if (DO_BIC(BIC_CPU_c1))
783 outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/tsc);
784
785
Len Brownc98d5d92012-06-04 00:56:40 -0400786 /* print per-core data only for 1st thread in core */
787 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
788 goto done;
789
Len Brown812db3f2017-02-10 00:25:41 -0500790 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates)
Len Brown008d396e2017-02-10 00:29:51 -0500791 outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/tsc);
Len Brown812db3f2017-02-10 00:25:41 -0500792 if (DO_BIC(BIC_CPU_c6))
Len Brown008d396e2017-02-10 00:29:51 -0500793 outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/tsc);
Len Brown812db3f2017-02-10 00:25:41 -0500794 if (DO_BIC(BIC_CPU_c7))
Len Brown008d396e2017-02-10 00:29:51 -0500795 outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/tsc);
Len Brownc98d5d92012-06-04 00:56:40 -0400796
Len Brown0539ba12017-02-10 00:27:20 -0500797 /* Mod%c6 */
798 if (DO_BIC(BIC_Mod_c6))
Len Brown008d396e2017-02-10 00:29:51 -0500799 outp += sprintf(outp, "\t%.2f", 100.0 * c->mc6_us / tsc);
Len Brown0539ba12017-02-10 00:27:20 -0500800
Len Brown812db3f2017-02-10 00:25:41 -0500801 if (DO_BIC(BIC_CoreTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400802 outp += sprintf(outp, "\t%d", c->core_temp_c);
Len Brown889facb2012-11-08 00:48:57 -0500803
Len Brown388e9c82016-12-22 23:57:55 -0500804 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
805 if (mp->format == FORMAT_RAW) {
806 if (mp->width == 32)
807 outp += sprintf(outp, "\t0x%08lx", (unsigned long) c->counter[i]);
808 else
809 outp += sprintf(outp, "\t0x%016llx", c->counter[i]);
810 } else if (mp->format == FORMAT_DELTA) {
Len Brown678a3bd2017-02-09 22:22:13 -0500811 outp += sprintf(outp, "\t%lld", c->counter[i]);
Len Brown388e9c82016-12-22 23:57:55 -0500812 } else if (mp->format == FORMAT_PERCENT) {
Len Brown008d396e2017-02-10 00:29:51 -0500813 outp += sprintf(outp, "\t%.2f", 100.0 * c->counter[i]/tsc);
Len Brown388e9c82016-12-22 23:57:55 -0500814 }
815 }
816
Len Brownc98d5d92012-06-04 00:56:40 -0400817 /* print per-package data only for 1st core in package */
818 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
819 goto done;
820
Len Brown0b2bb692015-03-26 00:50:30 -0400821 /* PkgTmp */
Len Brown812db3f2017-02-10 00:25:41 -0500822 if (DO_BIC(BIC_PkgTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400823 outp += sprintf(outp, "\t%d", p->pkg_temp_c);
Len Brown889facb2012-11-08 00:48:57 -0500824
Len Brownfdf676e2016-02-27 01:28:12 -0500825 /* GFXrc6 */
Len Brown812db3f2017-02-10 00:25:41 -0500826 if (DO_BIC(BIC_GFX_rc6)) {
Len Brownba3dec92016-04-22 20:31:46 -0400827 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
Len Brown3d109de2016-04-22 23:24:27 -0400828 outp += sprintf(outp, "\t**.**");
Len Brown9185e982016-04-06 17:16:00 -0400829 } else {
Len Brown3d109de2016-04-22 23:24:27 -0400830 outp += sprintf(outp, "\t%.2f",
Len Brown9185e982016-04-06 17:16:00 -0400831 p->gfx_rc6_ms / 10.0 / interval_float);
832 }
833 }
Len Brownfdf676e2016-02-27 01:28:12 -0500834
Len Brown27d47352016-02-27 00:37:54 -0500835 /* GFXMHz */
Len Brown812db3f2017-02-10 00:25:41 -0500836 if (DO_BIC(BIC_GFXMHz))
Len Brown3d109de2016-04-22 23:24:27 -0400837 outp += sprintf(outp, "\t%d", p->gfx_mhz);
Len Brown27d47352016-02-27 00:37:54 -0500838
Len Brown0b2bb692015-03-26 00:50:30 -0400839 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
840 if (do_skl_residency) {
Len Brown008d396e2017-02-10 00:29:51 -0500841 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/tsc);
842 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/tsc);
843 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/tsc);
844 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/tsc);
Len Brown0b2bb692015-03-26 00:50:30 -0400845 }
846
Len Brown0f47c082017-01-27 00:50:45 -0500847 if (DO_BIC(BIC_Pkgpc2))
Len Brown008d396e2017-02-10 00:29:51 -0500848 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500849 if (DO_BIC(BIC_Pkgpc3))
Len Brown008d396e2017-02-10 00:29:51 -0500850 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500851 if (DO_BIC(BIC_Pkgpc6))
Len Brown008d396e2017-02-10 00:29:51 -0500852 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500853 if (DO_BIC(BIC_Pkgpc7))
Len Brown008d396e2017-02-10 00:29:51 -0500854 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500855 if (DO_BIC(BIC_Pkgpc8))
Len Brown008d396e2017-02-10 00:29:51 -0500856 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500857 if (DO_BIC(BIC_Pkgpc9))
Len Brown008d396e2017-02-10 00:29:51 -0500858 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500859 if (DO_BIC(BIC_Pkgpc10))
Len Brown008d396e2017-02-10 00:29:51 -0500860 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/tsc);
Len Brown889facb2012-11-08 00:48:57 -0500861
862 /*
863 * If measurement interval exceeds minimum RAPL Joule Counter range,
864 * indicate that results are suspect by printing "**" in fraction place.
865 */
Len Brownfc04cc62014-02-06 00:55:19 -0500866 if (interval_float < rapl_joule_counter_range)
Len Brown3d109de2016-04-22 23:24:27 -0400867 fmt8 = "\t%.2f";
Len Brownfc04cc62014-02-06 00:55:19 -0500868 else
Len Browne975db52016-04-06 23:56:02 -0400869 fmt8 = "%6.0f**";
Len Brown889facb2012-11-08 00:48:57 -0500870
Len Brown812db3f2017-02-10 00:25:41 -0500871 if (DO_BIC(BIC_PkgWatt))
872 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float);
873 if (DO_BIC(BIC_CorWatt))
874 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float);
875 if (DO_BIC(BIC_GFXWatt))
876 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float);
877 if (DO_BIC(BIC_RAMWatt))
878 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units / interval_float);
879 if (DO_BIC(BIC_Pkg_J))
880 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units);
881 if (DO_BIC(BIC_Cor_J))
882 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units);
883 if (DO_BIC(BIC_GFX_J))
884 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units);
885 if (DO_BIC(BIC_RAM_J))
886 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units);
887 if (DO_BIC(BIC_PKG__))
888 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
889 if (DO_BIC(BIC_RAM__))
890 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
891
Len Brown388e9c82016-12-22 23:57:55 -0500892 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
893 if (mp->format == FORMAT_RAW) {
894 if (mp->width == 32)
895 outp += sprintf(outp, "\t0x%08lx", (unsigned long) p->counter[i]);
896 else
897 outp += sprintf(outp, "\t0x%016llx", p->counter[i]);
898 } else if (mp->format == FORMAT_DELTA) {
Len Brown678a3bd2017-02-09 22:22:13 -0500899 outp += sprintf(outp, "\t%lld", p->counter[i]);
Len Brown388e9c82016-12-22 23:57:55 -0500900 } else if (mp->format == FORMAT_PERCENT) {
Len Brown008d396e2017-02-10 00:29:51 -0500901 outp += sprintf(outp, "\t%.2f", 100.0 * p->counter[i]/tsc);
Len Brown388e9c82016-12-22 23:57:55 -0500902 }
903 }
904
Len Brownc98d5d92012-06-04 00:56:40 -0400905done:
Len Brownc98d5d92012-06-04 00:56:40 -0400906 outp += sprintf(outp, "\n");
907
908 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400909}
910
Len Brownb7d8c142016-02-13 23:36:17 -0500911void flush_output_stdout(void)
Len Brown103a8fe2010-10-22 23:53:03 -0400912{
Len Brownb7d8c142016-02-13 23:36:17 -0500913 FILE *filep;
914
915 if (outf == stderr)
916 filep = stdout;
917 else
918 filep = outf;
919
920 fputs(output_buffer, filep);
921 fflush(filep);
922
Len Brownc98d5d92012-06-04 00:56:40 -0400923 outp = output_buffer;
924}
Len Brownb7d8c142016-02-13 23:36:17 -0500925void flush_output_stderr(void)
Len Brownc98d5d92012-06-04 00:56:40 -0400926{
Len Brownb7d8c142016-02-13 23:36:17 -0500927 fputs(output_buffer, outf);
928 fflush(outf);
Len Brownc98d5d92012-06-04 00:56:40 -0400929 outp = output_buffer;
930}
931void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
932{
Len Browne23da032012-02-06 18:37:16 -0500933 static int printed;
Len Brown103a8fe2010-10-22 23:53:03 -0400934
Len Browne23da032012-02-06 18:37:16 -0500935 if (!printed || !summary_only)
936 print_header();
Len Brown103a8fe2010-10-22 23:53:03 -0400937
Len Brownc98d5d92012-06-04 00:56:40 -0400938 if (topo.num_cpus > 1)
939 format_counters(&average.threads, &average.cores,
940 &average.packages);
Len Brown103a8fe2010-10-22 23:53:03 -0400941
Len Browne23da032012-02-06 18:37:16 -0500942 printed = 1;
943
944 if (summary_only)
945 return;
946
Len Brownc98d5d92012-06-04 00:56:40 -0400947 for_all_cpus(format_counters, t, c, p);
Len Brown103a8fe2010-10-22 23:53:03 -0400948}
949
Len Brown889facb2012-11-08 00:48:57 -0500950#define DELTA_WRAP32(new, old) \
951 if (new > old) { \
952 old = new - old; \
953 } else { \
954 old = 0x100000000 + new - old; \
955 }
956
Len Brownba3dec92016-04-22 20:31:46 -0400957int
Len Brownc98d5d92012-06-04 00:56:40 -0400958delta_package(struct pkg_data *new, struct pkg_data *old)
Len Brown103a8fe2010-10-22 23:53:03 -0400959{
Len Brown388e9c82016-12-22 23:57:55 -0500960 int i;
961 struct msr_counter *mp;
Len Brown0b2bb692015-03-26 00:50:30 -0400962
963 if (do_skl_residency) {
964 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
965 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
966 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
967 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
968 }
Len Brownc98d5d92012-06-04 00:56:40 -0400969 old->pc2 = new->pc2 - old->pc2;
Len Brown0f47c082017-01-27 00:50:45 -0500970 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -0500971 old->pc3 = new->pc3 - old->pc3;
Len Brown0f47c082017-01-27 00:50:45 -0500972 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -0500973 old->pc6 = new->pc6 - old->pc6;
Len Brown0f47c082017-01-27 00:50:45 -0500974 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -0500975 old->pc7 = new->pc7 - old->pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800976 old->pc8 = new->pc8 - old->pc8;
977 old->pc9 = new->pc9 - old->pc9;
978 old->pc10 = new->pc10 - old->pc10;
Len Brown889facb2012-11-08 00:48:57 -0500979 old->pkg_temp_c = new->pkg_temp_c;
980
Len Brown9185e982016-04-06 17:16:00 -0400981 /* flag an error when rc6 counter resets/wraps */
982 if (old->gfx_rc6_ms > new->gfx_rc6_ms)
983 old->gfx_rc6_ms = -1;
984 else
985 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
986
Len Brown27d47352016-02-27 00:37:54 -0500987 old->gfx_mhz = new->gfx_mhz;
988
Len Brown889facb2012-11-08 00:48:57 -0500989 DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
990 DELTA_WRAP32(new->energy_cores, old->energy_cores);
991 DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
992 DELTA_WRAP32(new->energy_dram, old->energy_dram);
993 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
994 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
Len Brownba3dec92016-04-22 20:31:46 -0400995
Len Brown388e9c82016-12-22 23:57:55 -0500996 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
997 if (mp->format == FORMAT_RAW)
998 old->counter[i] = new->counter[i];
999 else
1000 old->counter[i] = new->counter[i] - old->counter[i];
1001 }
1002
Len Brownba3dec92016-04-22 20:31:46 -04001003 return 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001004}
Len Brown103a8fe2010-10-22 23:53:03 -04001005
Len Brownc98d5d92012-06-04 00:56:40 -04001006void
1007delta_core(struct core_data *new, struct core_data *old)
1008{
Len Brown388e9c82016-12-22 23:57:55 -05001009 int i;
1010 struct msr_counter *mp;
1011
Len Brownc98d5d92012-06-04 00:56:40 -04001012 old->c3 = new->c3 - old->c3;
1013 old->c6 = new->c6 - old->c6;
1014 old->c7 = new->c7 - old->c7;
Len Brown889facb2012-11-08 00:48:57 -05001015 old->core_temp_c = new->core_temp_c;
Len Brown0539ba12017-02-10 00:27:20 -05001016 old->mc6_us = new->mc6_us - old->mc6_us;
Len Brown388e9c82016-12-22 23:57:55 -05001017
1018 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1019 if (mp->format == FORMAT_RAW)
1020 old->counter[i] = new->counter[i];
1021 else
1022 old->counter[i] = new->counter[i] - old->counter[i];
1023 }
Len Brownc98d5d92012-06-04 00:56:40 -04001024}
Len Brown103a8fe2010-10-22 23:53:03 -04001025
Len Brownc3ae3312012-06-13 21:31:46 -04001026/*
1027 * old = new - old
1028 */
Len Brownba3dec92016-04-22 20:31:46 -04001029int
Len Brownc98d5d92012-06-04 00:56:40 -04001030delta_thread(struct thread_data *new, struct thread_data *old,
1031 struct core_data *core_delta)
1032{
Len Brown388e9c82016-12-22 23:57:55 -05001033 int i;
1034 struct msr_counter *mp;
1035
Len Brownc98d5d92012-06-04 00:56:40 -04001036 old->tsc = new->tsc - old->tsc;
Len Brown103a8fe2010-10-22 23:53:03 -04001037
Len Brownc98d5d92012-06-04 00:56:40 -04001038 /* check for TSC < 1 Mcycles over interval */
Josh Triplettb2c95d92013-08-20 17:20:18 -07001039 if (old->tsc < (1000 * 1000))
1040 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
1041 "You can disable all c-states by booting with \"idle=poll\"\n"
1042 "or just the deep ones with \"processor.max_cstate=1\"");
Len Brown103a8fe2010-10-22 23:53:03 -04001043
Len Brownc98d5d92012-06-04 00:56:40 -04001044 old->c1 = new->c1 - old->c1;
Len Brown103a8fe2010-10-22 23:53:03 -04001045
Len Brown812db3f2017-02-10 00:25:41 -05001046 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
Len Browna7296172015-01-23 01:33:58 -05001047 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
1048 old->aperf = new->aperf - old->aperf;
1049 old->mperf = new->mperf - old->mperf;
1050 } else {
Len Brownba3dec92016-04-22 20:31:46 -04001051 return -1;
Len Brownc98d5d92012-06-04 00:56:40 -04001052 }
Len Brownc98d5d92012-06-04 00:56:40 -04001053 }
Len Brown103a8fe2010-10-22 23:53:03 -04001054
Len Brown103a8fe2010-10-22 23:53:03 -04001055
Len Brown144b44b2013-11-09 00:30:16 -05001056 if (use_c1_residency_msr) {
1057 /*
1058 * Some models have a dedicated C1 residency MSR,
1059 * which should be more accurate than the derivation below.
1060 */
1061 } else {
1062 /*
1063 * As counter collection is not atomic,
1064 * it is possible for mperf's non-halted cycles + idle states
1065 * to exceed TSC's all cycles: show c1 = 0% in that case.
1066 */
1067 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
1068 old->c1 = 0;
1069 else {
1070 /* normal case, derive c1 */
Len Brown008d396e2017-02-10 00:29:51 -05001071 old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3
Len Brownc98d5d92012-06-04 00:56:40 -04001072 - core_delta->c6 - core_delta->c7;
Len Brown144b44b2013-11-09 00:30:16 -05001073 }
Len Brownc98d5d92012-06-04 00:56:40 -04001074 }
Len Brownc3ae3312012-06-13 21:31:46 -04001075
Len Brownc98d5d92012-06-04 00:56:40 -04001076 if (old->mperf == 0) {
Len Brownb7d8c142016-02-13 23:36:17 -05001077 if (debug > 1)
1078 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
Len Brownc98d5d92012-06-04 00:56:40 -04001079 old->mperf = 1; /* divide by 0 protection */
1080 }
1081
Len Brown812db3f2017-02-10 00:25:41 -05001082 if (DO_BIC(BIC_IRQ))
Len Brown562a2d32016-02-26 23:48:05 -05001083 old->irq_count = new->irq_count - old->irq_count;
1084
Len Brown812db3f2017-02-10 00:25:41 -05001085 if (DO_BIC(BIC_SMI))
Len Brown1ed51012013-02-10 17:19:24 -05001086 old->smi_count = new->smi_count - old->smi_count;
Len Brownba3dec92016-04-22 20:31:46 -04001087
Len Brown388e9c82016-12-22 23:57:55 -05001088 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1089 if (mp->format == FORMAT_RAW)
1090 old->counter[i] = new->counter[i];
1091 else
1092 old->counter[i] = new->counter[i] - old->counter[i];
1093 }
Len Brownba3dec92016-04-22 20:31:46 -04001094 return 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001095}
1096
1097int delta_cpu(struct thread_data *t, struct core_data *c,
1098 struct pkg_data *p, struct thread_data *t2,
1099 struct core_data *c2, struct pkg_data *p2)
1100{
Len Brownba3dec92016-04-22 20:31:46 -04001101 int retval = 0;
1102
Len Brownc98d5d92012-06-04 00:56:40 -04001103 /* calculate core delta only for 1st thread in core */
1104 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
1105 delta_core(c, c2);
1106
1107 /* always calculate thread delta */
Len Brownba3dec92016-04-22 20:31:46 -04001108 retval = delta_thread(t, t2, c2); /* c2 is core delta */
1109 if (retval)
1110 return retval;
Len Brownc98d5d92012-06-04 00:56:40 -04001111
1112 /* calculate package delta only for 1st core in package */
1113 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
Len Brownba3dec92016-04-22 20:31:46 -04001114 retval = delta_package(p, p2);
Len Brownc98d5d92012-06-04 00:56:40 -04001115
Len Brownba3dec92016-04-22 20:31:46 -04001116 return retval;
Len Brownc98d5d92012-06-04 00:56:40 -04001117}
1118
1119void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1120{
Len Brown388e9c82016-12-22 23:57:55 -05001121 int i;
1122 struct msr_counter *mp;
1123
Len Brownc98d5d92012-06-04 00:56:40 -04001124 t->tsc = 0;
1125 t->aperf = 0;
1126 t->mperf = 0;
1127 t->c1 = 0;
1128
Len Brown562a2d32016-02-26 23:48:05 -05001129 t->irq_count = 0;
1130 t->smi_count = 0;
1131
Len Brownc98d5d92012-06-04 00:56:40 -04001132 /* tells format_counters to dump all fields from this set */
1133 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
1134
1135 c->c3 = 0;
1136 c->c6 = 0;
1137 c->c7 = 0;
Len Brown0539ba12017-02-10 00:27:20 -05001138 c->mc6_us = 0;
Len Brown889facb2012-11-08 00:48:57 -05001139 c->core_temp_c = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001140
Len Brown0b2bb692015-03-26 00:50:30 -04001141 p->pkg_wtd_core_c0 = 0;
1142 p->pkg_any_core_c0 = 0;
1143 p->pkg_any_gfxe_c0 = 0;
1144 p->pkg_both_core_gfxe_c0 = 0;
1145
Len Brownc98d5d92012-06-04 00:56:40 -04001146 p->pc2 = 0;
Len Brown0f47c082017-01-27 00:50:45 -05001147 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -05001148 p->pc3 = 0;
Len Brown0f47c082017-01-27 00:50:45 -05001149 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -05001150 p->pc6 = 0;
Len Brown0f47c082017-01-27 00:50:45 -05001151 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -05001152 p->pc7 = 0;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001153 p->pc8 = 0;
1154 p->pc9 = 0;
1155 p->pc10 = 0;
Len Brown889facb2012-11-08 00:48:57 -05001156
1157 p->energy_pkg = 0;
1158 p->energy_dram = 0;
1159 p->energy_cores = 0;
1160 p->energy_gfx = 0;
1161 p->rapl_pkg_perf_status = 0;
1162 p->rapl_dram_perf_status = 0;
1163 p->pkg_temp_c = 0;
Len Brown27d47352016-02-27 00:37:54 -05001164
Len Brownfdf676e2016-02-27 01:28:12 -05001165 p->gfx_rc6_ms = 0;
Len Brown27d47352016-02-27 00:37:54 -05001166 p->gfx_mhz = 0;
Len Brown388e9c82016-12-22 23:57:55 -05001167 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
1168 t->counter[i] = 0;
1169
1170 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next)
1171 c->counter[i] = 0;
1172
1173 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
1174 p->counter[i] = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001175}
1176int sum_counters(struct thread_data *t, struct core_data *c,
1177 struct pkg_data *p)
1178{
Len Brown388e9c82016-12-22 23:57:55 -05001179 int i;
1180 struct msr_counter *mp;
1181
Len Brownc98d5d92012-06-04 00:56:40 -04001182 average.threads.tsc += t->tsc;
1183 average.threads.aperf += t->aperf;
1184 average.threads.mperf += t->mperf;
1185 average.threads.c1 += t->c1;
1186
Len Brown562a2d32016-02-26 23:48:05 -05001187 average.threads.irq_count += t->irq_count;
1188 average.threads.smi_count += t->smi_count;
1189
Len Brown388e9c82016-12-22 23:57:55 -05001190 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1191 if (mp->format == FORMAT_RAW)
1192 continue;
1193 average.threads.counter[i] += t->counter[i];
1194 }
1195
Len Brownc98d5d92012-06-04 00:56:40 -04001196 /* sum per-core values only for 1st thread in core */
1197 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1198 return 0;
1199
1200 average.cores.c3 += c->c3;
1201 average.cores.c6 += c->c6;
1202 average.cores.c7 += c->c7;
Len Brown0539ba12017-02-10 00:27:20 -05001203 average.cores.mc6_us += c->mc6_us;
Len Brownc98d5d92012-06-04 00:56:40 -04001204
Len Brown889facb2012-11-08 00:48:57 -05001205 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
1206
Len Brown388e9c82016-12-22 23:57:55 -05001207 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1208 if (mp->format == FORMAT_RAW)
1209 continue;
1210 average.cores.counter[i] += c->counter[i];
1211 }
1212
Len Brownc98d5d92012-06-04 00:56:40 -04001213 /* sum per-pkg values only for 1st core in pkg */
1214 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1215 return 0;
1216
Len Brown0b2bb692015-03-26 00:50:30 -04001217 if (do_skl_residency) {
1218 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
1219 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
1220 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
1221 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
1222 }
1223
Len Brownc98d5d92012-06-04 00:56:40 -04001224 average.packages.pc2 += p->pc2;
Len Brown0f47c082017-01-27 00:50:45 -05001225 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -05001226 average.packages.pc3 += p->pc3;
Len Brown0f47c082017-01-27 00:50:45 -05001227 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -05001228 average.packages.pc6 += p->pc6;
Len Brown0f47c082017-01-27 00:50:45 -05001229 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -05001230 average.packages.pc7 += p->pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001231 average.packages.pc8 += p->pc8;
1232 average.packages.pc9 += p->pc9;
1233 average.packages.pc10 += p->pc10;
Len Brownc98d5d92012-06-04 00:56:40 -04001234
Len Brown889facb2012-11-08 00:48:57 -05001235 average.packages.energy_pkg += p->energy_pkg;
1236 average.packages.energy_dram += p->energy_dram;
1237 average.packages.energy_cores += p->energy_cores;
1238 average.packages.energy_gfx += p->energy_gfx;
1239
Len Brownfdf676e2016-02-27 01:28:12 -05001240 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -05001241 average.packages.gfx_mhz = p->gfx_mhz;
1242
Len Brown889facb2012-11-08 00:48:57 -05001243 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
1244
1245 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
1246 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
Len Brown388e9c82016-12-22 23:57:55 -05001247
1248 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1249 if (mp->format == FORMAT_RAW)
1250 continue;
1251 average.packages.counter[i] += p->counter[i];
1252 }
Len Brownc98d5d92012-06-04 00:56:40 -04001253 return 0;
1254}
1255/*
1256 * sum the counters for all cpus in the system
1257 * compute the weighted average
1258 */
1259void compute_average(struct thread_data *t, struct core_data *c,
1260 struct pkg_data *p)
1261{
Len Brown388e9c82016-12-22 23:57:55 -05001262 int i;
1263 struct msr_counter *mp;
1264
Len Brownc98d5d92012-06-04 00:56:40 -04001265 clear_counters(&average.threads, &average.cores, &average.packages);
1266
1267 for_all_cpus(sum_counters, t, c, p);
1268
1269 average.threads.tsc /= topo.num_cpus;
1270 average.threads.aperf /= topo.num_cpus;
1271 average.threads.mperf /= topo.num_cpus;
1272 average.threads.c1 /= topo.num_cpus;
1273
1274 average.cores.c3 /= topo.num_cores;
1275 average.cores.c6 /= topo.num_cores;
1276 average.cores.c7 /= topo.num_cores;
Len Brown0539ba12017-02-10 00:27:20 -05001277 average.cores.mc6_us /= topo.num_cores;
Len Brownc98d5d92012-06-04 00:56:40 -04001278
Len Brown0b2bb692015-03-26 00:50:30 -04001279 if (do_skl_residency) {
1280 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
1281 average.packages.pkg_any_core_c0 /= topo.num_packages;
1282 average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
1283 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
1284 }
1285
Len Brownc98d5d92012-06-04 00:56:40 -04001286 average.packages.pc2 /= topo.num_packages;
Len Brown0f47c082017-01-27 00:50:45 -05001287 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -05001288 average.packages.pc3 /= topo.num_packages;
Len Brown0f47c082017-01-27 00:50:45 -05001289 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -05001290 average.packages.pc6 /= topo.num_packages;
Len Brown0f47c082017-01-27 00:50:45 -05001291 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -05001292 average.packages.pc7 /= topo.num_packages;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001293
1294 average.packages.pc8 /= topo.num_packages;
1295 average.packages.pc9 /= topo.num_packages;
1296 average.packages.pc10 /= topo.num_packages;
Len Brown388e9c82016-12-22 23:57:55 -05001297
1298 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1299 if (mp->format == FORMAT_RAW)
1300 continue;
Len Brown41618e62017-02-09 18:25:22 -05001301 if (mp->flags & SYSFS_PERCPU && mp->type == COUNTER_ITEMS)
1302 continue;
Len Brown388e9c82016-12-22 23:57:55 -05001303 average.threads.counter[i] /= topo.num_cpus;
1304 }
1305 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1306 if (mp->format == FORMAT_RAW)
1307 continue;
1308 average.cores.counter[i] /= topo.num_cores;
1309 }
1310 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1311 if (mp->format == FORMAT_RAW)
1312 continue;
1313 average.packages.counter[i] /= topo.num_packages;
1314 }
Len Brownc98d5d92012-06-04 00:56:40 -04001315}
1316
1317static unsigned long long rdtsc(void)
1318{
1319 unsigned int low, high;
1320
1321 asm volatile("rdtsc" : "=a" (low), "=d" (high));
1322
1323 return low | ((unsigned long long)high) << 32;
1324}
1325
Len Brownc98d5d92012-06-04 00:56:40 -04001326/*
Len Brown495c76542017-02-08 02:41:51 -05001327 * Open a file, and exit on failure
1328 */
1329FILE *fopen_or_die(const char *path, const char *mode)
1330{
1331 FILE *filep = fopen(path, mode);
1332
1333 if (!filep)
1334 err(1, "%s: open failed", path);
1335 return filep;
1336}
1337/*
1338 * snapshot_sysfs_counter()
1339 *
1340 * return snapshot of given counter
1341 */
1342unsigned long long snapshot_sysfs_counter(char *path)
1343{
1344 FILE *fp;
1345 int retval;
1346 unsigned long long counter;
1347
1348 fp = fopen_or_die(path, "r");
1349
1350 retval = fscanf(fp, "%lld", &counter);
1351 if (retval != 1)
1352 err(1, "snapshot_sysfs_counter(%s)", path);
1353
1354 fclose(fp);
1355
1356 return counter;
1357}
1358
1359int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
1360{
1361 if (mp->msr_num != 0) {
1362 if (get_msr(cpu, mp->msr_num, counterp))
1363 return -1;
1364 } else {
Len Brown41618e62017-02-09 18:25:22 -05001365 char path[128];
1366
1367 if (mp->flags & SYSFS_PERCPU) {
1368 sprintf(path, "/sys/devices/system/cpu/cpu%d/%s",
1369 cpu, mp->path);
1370
1371 *counterp = snapshot_sysfs_counter(path);
1372 } else {
1373 *counterp = snapshot_sysfs_counter(mp->path);
1374 }
Len Brown495c76542017-02-08 02:41:51 -05001375 }
1376
1377 return 0;
1378}
1379
1380/*
Len Brownc98d5d92012-06-04 00:56:40 -04001381 * get_counters(...)
1382 * migrate to cpu
1383 * acquire and record local counters for that cpu
1384 */
1385int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1386{
1387 int cpu = t->cpu_id;
Len Brown889facb2012-11-08 00:48:57 -05001388 unsigned long long msr;
Len Brown0102b062016-02-27 03:11:29 -05001389 int aperf_mperf_retry_count = 0;
Len Brown388e9c82016-12-22 23:57:55 -05001390 struct msr_counter *mp;
1391 int i;
Len Brownc98d5d92012-06-04 00:56:40 -04001392
Len Browne52966c2012-11-08 22:38:05 -05001393 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05001394 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brownc98d5d92012-06-04 00:56:40 -04001395 return -1;
Len Browne52966c2012-11-08 22:38:05 -05001396 }
Len Brownc98d5d92012-06-04 00:56:40 -04001397
Len Brown0102b062016-02-27 03:11:29 -05001398retry:
Len Brownc98d5d92012-06-04 00:56:40 -04001399 t->tsc = rdtsc(); /* we are running on local CPU of interest */
1400
Len Brown812db3f2017-02-10 00:25:41 -05001401 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
Len Brown0102b062016-02-27 03:11:29 -05001402 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
1403
1404 /*
1405 * The TSC, APERF and MPERF must be read together for
1406 * APERF/MPERF and MPERF/TSC to give accurate results.
1407 *
1408 * Unfortunately, APERF and MPERF are read by
1409 * individual system call, so delays may occur
1410 * between them. If the time to read them
1411 * varies by a large amount, we re-read them.
1412 */
1413
1414 /*
1415 * This initial dummy APERF read has been seen to
1416 * reduce jitter in the subsequent reads.
1417 */
1418
Len Brown9c63a652012-10-31 01:29:52 -04001419 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
Len Brownc98d5d92012-06-04 00:56:40 -04001420 return -3;
Len Brown0102b062016-02-27 03:11:29 -05001421
1422 t->tsc = rdtsc(); /* re-read close to APERF */
1423
1424 tsc_before = t->tsc;
1425
1426 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
1427 return -3;
1428
1429 tsc_between = rdtsc();
1430
Len Brown9c63a652012-10-31 01:29:52 -04001431 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
Len Brownc98d5d92012-06-04 00:56:40 -04001432 return -4;
Len Brown0102b062016-02-27 03:11:29 -05001433
1434 tsc_after = rdtsc();
1435
1436 aperf_time = tsc_between - tsc_before;
1437 mperf_time = tsc_after - tsc_between;
1438
1439 /*
1440 * If the system call latency to read APERF and MPERF
1441 * differ by more than 2x, then try again.
1442 */
1443 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
1444 aperf_mperf_retry_count++;
1445 if (aperf_mperf_retry_count < 5)
1446 goto retry;
1447 else
1448 warnx("cpu%d jitter %lld %lld",
1449 cpu, aperf_time, mperf_time);
1450 }
1451 aperf_mperf_retry_count = 0;
1452
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02001453 t->aperf = t->aperf * aperf_mperf_multiplier;
1454 t->mperf = t->mperf * aperf_mperf_multiplier;
Len Brownc98d5d92012-06-04 00:56:40 -04001455 }
1456
Len Brown812db3f2017-02-10 00:25:41 -05001457 if (DO_BIC(BIC_IRQ))
Len Brown562a2d32016-02-26 23:48:05 -05001458 t->irq_count = irqs_per_cpu[cpu];
Len Brown812db3f2017-02-10 00:25:41 -05001459 if (DO_BIC(BIC_SMI)) {
Len Brown1ed51012013-02-10 17:19:24 -05001460 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
1461 return -5;
1462 t->smi_count = msr & 0xFFFFFFFF;
1463 }
Len Brown0539ba12017-02-10 00:27:20 -05001464 if (DO_BIC(BIC_CPU_c1) && use_c1_residency_msr) {
Len Brown144b44b2013-11-09 00:30:16 -05001465 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
1466 return -6;
1467 }
1468
Len Brown388e9c82016-12-22 23:57:55 -05001469 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
Len Brown495c76542017-02-08 02:41:51 -05001470 if (get_mp(cpu, mp, &t->counter[i]))
Len Brown388e9c82016-12-22 23:57:55 -05001471 return -10;
1472 }
1473
Len Brownc98d5d92012-06-04 00:56:40 -04001474 /* collect core counters only for 1st thread in core */
1475 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1476 return 0;
1477
Len Brown812db3f2017-02-10 00:25:41 -05001478 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates) {
Len Brownc98d5d92012-06-04 00:56:40 -04001479 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
1480 return -6;
Len Brown144b44b2013-11-09 00:30:16 -05001481 }
1482
Len Brown812db3f2017-02-10 00:25:41 -05001483 if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) {
Len Brownc98d5d92012-06-04 00:56:40 -04001484 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
1485 return -7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001486 } else if (do_knl_cstates) {
1487 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
1488 return -7;
Len Brownc98d5d92012-06-04 00:56:40 -04001489 }
1490
Len Brown812db3f2017-02-10 00:25:41 -05001491 if (DO_BIC(BIC_CPU_c7))
Len Brownc98d5d92012-06-04 00:56:40 -04001492 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
1493 return -8;
1494
Len Brown0539ba12017-02-10 00:27:20 -05001495 if (DO_BIC(BIC_Mod_c6))
1496 if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
1497 return -8;
1498
Len Brown812db3f2017-02-10 00:25:41 -05001499 if (DO_BIC(BIC_CoreTmp)) {
Len Brown889facb2012-11-08 00:48:57 -05001500 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1501 return -9;
1502 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1503 }
1504
Len Brown388e9c82016-12-22 23:57:55 -05001505 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
Len Brown495c76542017-02-08 02:41:51 -05001506 if (get_mp(cpu, mp, &c->counter[i]))
Len Brown388e9c82016-12-22 23:57:55 -05001507 return -10;
1508 }
Len Brown889facb2012-11-08 00:48:57 -05001509
Len Brownc98d5d92012-06-04 00:56:40 -04001510 /* collect package counters only for 1st core in package */
1511 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1512 return 0;
1513
Len Brown0b2bb692015-03-26 00:50:30 -04001514 if (do_skl_residency) {
1515 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
1516 return -10;
1517 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
1518 return -11;
1519 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
1520 return -12;
1521 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
1522 return -13;
1523 }
Len Brown0f47c082017-01-27 00:50:45 -05001524 if (DO_BIC(BIC_Pkgpc3))
Len Brownc98d5d92012-06-04 00:56:40 -04001525 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
1526 return -9;
Len Brown0f47c082017-01-27 00:50:45 -05001527 if (DO_BIC(BIC_Pkgpc6)) {
Len Brown0539ba12017-02-10 00:27:20 -05001528 if (do_slm_cstates) {
1529 if (get_msr(cpu, MSR_ATOM_PKG_C6_RESIDENCY, &p->pc6))
1530 return -10;
1531 } else {
1532 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
1533 return -10;
1534 }
1535 }
1536
Len Brown0f47c082017-01-27 00:50:45 -05001537 if (DO_BIC(BIC_Pkgpc2))
Len Brownc98d5d92012-06-04 00:56:40 -04001538 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
1539 return -11;
Len Brown0f47c082017-01-27 00:50:45 -05001540 if (DO_BIC(BIC_Pkgpc7))
Len Brownc98d5d92012-06-04 00:56:40 -04001541 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
1542 return -12;
Len Brown0f47c082017-01-27 00:50:45 -05001543 if (DO_BIC(BIC_Pkgpc8))
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001544 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
1545 return -13;
Len Brown0f47c082017-01-27 00:50:45 -05001546 if (DO_BIC(BIC_Pkgpc9))
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001547 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
1548 return -13;
Len Brown0f47c082017-01-27 00:50:45 -05001549 if (DO_BIC(BIC_Pkgpc10))
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001550 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
1551 return -13;
Len Brown0f47c082017-01-27 00:50:45 -05001552
Len Brown889facb2012-11-08 00:48:57 -05001553 if (do_rapl & RAPL_PKG) {
1554 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
1555 return -13;
1556 p->energy_pkg = msr & 0xFFFFFFFF;
1557 }
Jacob Pan91484942016-06-16 09:48:20 -07001558 if (do_rapl & RAPL_CORES_ENERGY_STATUS) {
Len Brown889facb2012-11-08 00:48:57 -05001559 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr))
1560 return -14;
1561 p->energy_cores = msr & 0xFFFFFFFF;
1562 }
1563 if (do_rapl & RAPL_DRAM) {
1564 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
1565 return -15;
1566 p->energy_dram = msr & 0xFFFFFFFF;
1567 }
1568 if (do_rapl & RAPL_GFX) {
1569 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr))
1570 return -16;
1571 p->energy_gfx = msr & 0xFFFFFFFF;
1572 }
1573 if (do_rapl & RAPL_PKG_PERF_STATUS) {
1574 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr))
1575 return -16;
1576 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
1577 }
1578 if (do_rapl & RAPL_DRAM_PERF_STATUS) {
1579 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr))
1580 return -16;
1581 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
1582 }
Len Brown812db3f2017-02-10 00:25:41 -05001583 if (DO_BIC(BIC_PkgTmp)) {
Len Brown889facb2012-11-08 00:48:57 -05001584 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1585 return -17;
1586 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1587 }
Len Brownfdf676e2016-02-27 01:28:12 -05001588
Len Brown812db3f2017-02-10 00:25:41 -05001589 if (DO_BIC(BIC_GFX_rc6))
Len Brownfdf676e2016-02-27 01:28:12 -05001590 p->gfx_rc6_ms = gfx_cur_rc6_ms;
1591
Len Brown812db3f2017-02-10 00:25:41 -05001592 if (DO_BIC(BIC_GFXMHz))
Len Brown27d47352016-02-27 00:37:54 -05001593 p->gfx_mhz = gfx_cur_mhz;
1594
Len Brown388e9c82016-12-22 23:57:55 -05001595 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
Len Brown495c76542017-02-08 02:41:51 -05001596 if (get_mp(cpu, mp, &p->counter[i]))
Len Brown388e9c82016-12-22 23:57:55 -05001597 return -10;
1598 }
1599
Len Brown103a8fe2010-10-22 23:53:03 -04001600 return 0;
1601}
1602
Len Brownee7e38e2015-02-09 23:39:45 -05001603/*
1604 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1605 * If you change the values, note they are used both in comparisons
1606 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1607 */
1608
1609#define PCLUKN 0 /* Unknown */
1610#define PCLRSV 1 /* Reserved */
1611#define PCL__0 2 /* PC0 */
1612#define PCL__1 3 /* PC1 */
1613#define PCL__2 4 /* PC2 */
1614#define PCL__3 5 /* PC3 */
1615#define PCL__4 6 /* PC4 */
1616#define PCL__6 7 /* PC6 */
1617#define PCL_6N 8 /* PC6 No Retention */
1618#define PCL_6R 9 /* PC6 Retention */
1619#define PCL__7 10 /* PC7 */
1620#define PCL_7S 11 /* PC7 Shrink */
Len Brown0b2bb692015-03-26 00:50:30 -04001621#define PCL__8 12 /* PC8 */
1622#define PCL__9 13 /* PC9 */
1623#define PCLUNL 14 /* Unlimited */
Len Brownee7e38e2015-02-09 23:39:45 -05001624
1625int pkg_cstate_limit = PCLUKN;
1626char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
Len Brown0b2bb692015-03-26 00:50:30 -04001627 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"};
Len Brownee7e38e2015-02-09 23:39:45 -05001628
Len Browne9257f52015-04-01 21:02:57 -04001629int 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};
1630int 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};
1631int 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};
Len Brown0539ba12017-02-10 00:27:20 -05001632int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
Len Brownf2642882017-01-07 23:13:15 -05001633int amt_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Browne9257f52015-04-01 21:02:57 -04001634int 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 -04001635int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Brownd8ebb442016-12-01 20:27:46 -05001636int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Brownee7e38e2015-02-09 23:39:45 -05001637
Len Browna2b7b742015-09-26 00:12:38 -04001638
1639static void
1640calculate_tsc_tweak()
1641{
Len Browna2b7b742015-09-26 00:12:38 -04001642 tsc_tweak = base_hz / tsc_hz;
1643}
1644
Len Brownfcd17212015-03-23 20:29:09 -04001645static void
1646dump_nhm_platform_info(void)
Len Brown103a8fe2010-10-22 23:53:03 -04001647{
1648 unsigned long long msr;
1649 unsigned int ratio;
1650
Len Brownec0adc52015-11-12 02:42:31 -05001651 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown103a8fe2010-10-22 23:53:03 -04001652
Len Brownb7d8c142016-02-13 23:36:17 -05001653 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001654
Len Brown103a8fe2010-10-22 23:53:03 -04001655 ratio = (msr >> 40) & 0xFF;
Len Brown710f2732017-01-11 22:12:25 -05001656 fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001657 ratio, bclk, ratio * bclk);
1658
1659 ratio = (msr >> 8) & 0xFF;
Len Brown710f2732017-01-11 22:12:25 -05001660 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001661 ratio, bclk, ratio * bclk);
1662
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001663 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001664 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
Len Brownbfae2052015-06-17 12:27:21 -04001665 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
Len Brown67920412013-01-31 15:22:15 -05001666
Len Brownfcd17212015-03-23 20:29:09 -04001667 return;
1668}
1669
1670static void
1671dump_hsw_turbo_ratio_limits(void)
1672{
1673 unsigned long long msr;
1674 unsigned int ratio;
1675
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001676 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001677
Len Brownb7d8c142016-02-13 23:36:17 -05001678 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001679
1680 ratio = (msr >> 8) & 0xFF;
1681 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001682 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001683 ratio, bclk, ratio * bclk);
1684
1685 ratio = (msr >> 0) & 0xFF;
1686 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001687 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001688 ratio, bclk, ratio * bclk);
1689 return;
1690}
1691
1692static void
1693dump_ivt_turbo_ratio_limits(void)
1694{
1695 unsigned long long msr;
1696 unsigned int ratio;
Len Brown6574a5d2012-09-21 00:01:31 -04001697
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001698 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001699
Len Brownb7d8c142016-02-13 23:36:17 -05001700 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001701
1702 ratio = (msr >> 56) & 0xFF;
1703 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001704 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001705 ratio, bclk, ratio * bclk);
1706
1707 ratio = (msr >> 48) & 0xFF;
1708 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001709 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001710 ratio, bclk, ratio * bclk);
1711
1712 ratio = (msr >> 40) & 0xFF;
1713 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001714 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001715 ratio, bclk, ratio * bclk);
1716
1717 ratio = (msr >> 32) & 0xFF;
1718 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001719 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001720 ratio, bclk, ratio * bclk);
1721
1722 ratio = (msr >> 24) & 0xFF;
1723 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001724 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001725 ratio, bclk, ratio * bclk);
1726
1727 ratio = (msr >> 16) & 0xFF;
1728 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001729 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001730 ratio, bclk, ratio * bclk);
1731
1732 ratio = (msr >> 8) & 0xFF;
1733 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001734 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001735 ratio, bclk, ratio * bclk);
1736
1737 ratio = (msr >> 0) & 0xFF;
1738 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001739 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001740 ratio, bclk, ratio * bclk);
Len Brownfcd17212015-03-23 20:29:09 -04001741 return;
1742}
Len Brown31e07522017-01-31 23:07:49 -05001743int has_turbo_ratio_group_limits(int family, int model)
1744{
1745
1746 if (!genuine_intel)
1747 return 0;
1748
1749 switch (model) {
1750 case INTEL_FAM6_ATOM_GOLDMONT:
1751 case INTEL_FAM6_SKYLAKE_X:
1752 case INTEL_FAM6_ATOM_DENVERTON:
1753 return 1;
1754 }
1755 return 0;
1756}
Len Brown6574a5d2012-09-21 00:01:31 -04001757
Len Brownfcd17212015-03-23 20:29:09 -04001758static void
Len Brown31e07522017-01-31 23:07:49 -05001759dump_turbo_ratio_limits(int family, int model)
Len Brownfcd17212015-03-23 20:29:09 -04001760{
Len Brown31e07522017-01-31 23:07:49 -05001761 unsigned long long msr, core_counts;
1762 unsigned int ratio, group_size;
Len Brown103a8fe2010-10-22 23:53:03 -04001763
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001764 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001765 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001766
Len Brown31e07522017-01-31 23:07:49 -05001767 if (has_turbo_ratio_group_limits(family, model)) {
1768 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
1769 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
1770 } else {
1771 core_counts = 0x0807060504030201;
1772 }
1773
Len Brown6574a5d2012-09-21 00:01:31 -04001774 ratio = (msr >> 56) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001775 group_size = (core_counts >> 56) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001776 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001777 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1778 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001779
1780 ratio = (msr >> 48) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001781 group_size = (core_counts >> 48) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001782 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001783 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1784 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001785
1786 ratio = (msr >> 40) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001787 group_size = (core_counts >> 40) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001788 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001789 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1790 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001791
1792 ratio = (msr >> 32) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001793 group_size = (core_counts >> 32) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001794 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001795 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1796 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001797
Len Brown103a8fe2010-10-22 23:53:03 -04001798 ratio = (msr >> 24) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001799 group_size = (core_counts >> 24) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001800 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001801 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1802 ratio, bclk, ratio * bclk, group_size);
Len Brown103a8fe2010-10-22 23:53:03 -04001803
1804 ratio = (msr >> 16) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001805 group_size = (core_counts >> 16) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001806 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001807 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1808 ratio, bclk, ratio * bclk, group_size);
Len Brown103a8fe2010-10-22 23:53:03 -04001809
1810 ratio = (msr >> 8) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001811 group_size = (core_counts >> 8) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001812 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001813 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1814 ratio, bclk, ratio * bclk, group_size);
Len Brown103a8fe2010-10-22 23:53:03 -04001815
1816 ratio = (msr >> 0) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001817 group_size = (core_counts >> 0) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001818 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001819 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1820 ratio, bclk, ratio * bclk, group_size);
Len Brownfcd17212015-03-23 20:29:09 -04001821 return;
1822}
Len Brown3a9a9412014-08-15 02:39:52 -04001823
Len Brownfcd17212015-03-23 20:29:09 -04001824static void
Len Brown0f7887c2017-01-12 23:49:18 -05001825dump_atom_turbo_ratio_limits(void)
1826{
1827 unsigned long long msr;
1828 unsigned int ratio;
1829
1830 get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
1831 fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
1832
1833 ratio = (msr >> 0) & 0x3F;
1834 if (ratio)
1835 fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n",
1836 ratio, bclk, ratio * bclk);
1837
1838 ratio = (msr >> 8) & 0x3F;
1839 if (ratio)
1840 fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n",
1841 ratio, bclk, ratio * bclk);
1842
1843 ratio = (msr >> 16) & 0x3F;
1844 if (ratio)
1845 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
1846 ratio, bclk, ratio * bclk);
1847
1848 get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
1849 fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
1850
1851 ratio = (msr >> 24) & 0x3F;
1852 if (ratio)
1853 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n",
1854 ratio, bclk, ratio * bclk);
1855
1856 ratio = (msr >> 16) & 0x3F;
1857 if (ratio)
1858 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n",
1859 ratio, bclk, ratio * bclk);
1860
1861 ratio = (msr >> 8) & 0x3F;
1862 if (ratio)
1863 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n",
1864 ratio, bclk, ratio * bclk);
1865
1866 ratio = (msr >> 0) & 0x3F;
1867 if (ratio)
1868 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n",
1869 ratio, bclk, ratio * bclk);
1870}
1871
1872static void
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001873dump_knl_turbo_ratio_limits(void)
1874{
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001875 const unsigned int buckets_no = 7;
1876
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001877 unsigned long long msr;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001878 int delta_cores, delta_ratio;
1879 int i, b_nr;
1880 unsigned int cores[buckets_no];
1881 unsigned int ratio[buckets_no];
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001882
Srinivas Pandruvadaebf59262016-07-06 16:07:56 -07001883 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001884
Len Brownb7d8c142016-02-13 23:36:17 -05001885 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
Len Brownbfae2052015-06-17 12:27:21 -04001886 base_cpu, msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001887
1888 /**
1889 * Turbo encoding in KNL is as follows:
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001890 * [0] -- Reserved
1891 * [7:1] -- Base value of number of active cores of bucket 1.
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001892 * [15:8] -- Base value of freq ratio of bucket 1.
1893 * [20:16] -- +ve delta of number of active cores of bucket 2.
1894 * i.e. active cores of bucket 2 =
1895 * active cores of bucket 1 + delta
1896 * [23:21] -- Negative delta of freq ratio of bucket 2.
1897 * i.e. freq ratio of bucket 2 =
1898 * freq ratio of bucket 1 - delta
1899 * [28:24]-- +ve delta of number of active cores of bucket 3.
1900 * [31:29]-- -ve delta of freq ratio of bucket 3.
1901 * [36:32]-- +ve delta of number of active cores of bucket 4.
1902 * [39:37]-- -ve delta of freq ratio of bucket 4.
1903 * [44:40]-- +ve delta of number of active cores of bucket 5.
1904 * [47:45]-- -ve delta of freq ratio of bucket 5.
1905 * [52:48]-- +ve delta of number of active cores of bucket 6.
1906 * [55:53]-- -ve delta of freq ratio of bucket 6.
1907 * [60:56]-- +ve delta of number of active cores of bucket 7.
1908 * [63:61]-- -ve delta of freq ratio of bucket 7.
1909 */
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001910
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001911 b_nr = 0;
1912 cores[b_nr] = (msr & 0xFF) >> 1;
1913 ratio[b_nr] = (msr >> 8) & 0xFF;
1914
1915 for (i = 16; i < 64; i += 8) {
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001916 delta_cores = (msr >> i) & 0x1F;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001917 delta_ratio = (msr >> (i + 5)) & 0x7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001918
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001919 cores[b_nr + 1] = cores[b_nr] + delta_cores;
1920 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
1921 b_nr++;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001922 }
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001923
1924 for (i = buckets_no - 1; i >= 0; i--)
1925 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
Len Brownb7d8c142016-02-13 23:36:17 -05001926 fprintf(outf,
Len Brown710f2732017-01-11 22:12:25 -05001927 "%d * %.1f = %.1f MHz max turbo %d active cores\n",
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001928 ratio[i], bclk, ratio[i] * bclk, cores[i]);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001929}
1930
1931static void
Len Brownfcd17212015-03-23 20:29:09 -04001932dump_nhm_cst_cfg(void)
1933{
1934 unsigned long long msr;
1935
Len Brown1df2e552017-01-07 23:24:57 -05001936 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001937
1938#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
1939#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
1940
Len Brown1df2e552017-01-07 23:24:57 -05001941 fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001942
Len Brownb7d8c142016-02-13 23:36:17 -05001943 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
Len Brownfcd17212015-03-23 20:29:09 -04001944 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1945 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1946 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1947 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1948 (msr & (1 << 15)) ? "" : "UN",
Len Brown6c34f162016-03-13 03:21:22 -04001949 (unsigned int)msr & 0xF,
Len Brownfcd17212015-03-23 20:29:09 -04001950 pkg_cstate_limit_strings[pkg_cstate_limit]);
1951 return;
Len Brown103a8fe2010-10-22 23:53:03 -04001952}
1953
Len Brown6fb31432015-06-17 16:23:45 -04001954static void
1955dump_config_tdp(void)
1956{
1957 unsigned long long msr;
1958
1959 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001960 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001961 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
Len Brown6fb31432015-06-17 16:23:45 -04001962
1963 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001964 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001965 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001966 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1967 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1968 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1969 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001970 }
Len Brownb7d8c142016-02-13 23:36:17 -05001971 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001972
1973 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001974 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001975 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001976 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1977 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1978 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1979 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001980 }
Len Brownb7d8c142016-02-13 23:36:17 -05001981 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001982
1983 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001984 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001985 if ((msr) & 0x3)
Len Brownb7d8c142016-02-13 23:36:17 -05001986 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
1987 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1988 fprintf(outf, ")\n");
Len Brown36229892016-02-26 20:51:02 -05001989
Len Brown6fb31432015-06-17 16:23:45 -04001990 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001991 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001992 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
Len Brownb7d8c142016-02-13 23:36:17 -05001993 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1994 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001995}
Len Brown5a634262016-04-06 17:15:55 -04001996
1997unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
1998
1999void print_irtl(void)
2000{
2001 unsigned long long msr;
2002
2003 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
2004 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
2005 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2006 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2007
2008 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
2009 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
2010 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2011 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2012
2013 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
2014 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
2015 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2016 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2017
2018 if (!do_irtl_hsw)
2019 return;
2020
2021 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
2022 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
2023 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2024 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2025
2026 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
2027 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
2028 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2029 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2030
2031 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
2032 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
2033 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2034 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2035
2036}
Len Brown36229892016-02-26 20:51:02 -05002037void free_fd_percpu(void)
2038{
2039 int i;
2040
Mika Westerberg01a67ad2016-04-22 11:13:23 +03002041 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
Len Brown36229892016-02-26 20:51:02 -05002042 if (fd_percpu[i] != 0)
2043 close(fd_percpu[i]);
2044 }
2045
2046 free(fd_percpu);
Len Brown6fb31432015-06-17 16:23:45 -04002047}
2048
Len Brownc98d5d92012-06-04 00:56:40 -04002049void free_all_buffers(void)
Len Brown103a8fe2010-10-22 23:53:03 -04002050{
Len Brownc98d5d92012-06-04 00:56:40 -04002051 CPU_FREE(cpu_present_set);
2052 cpu_present_set = NULL;
Len Brown36229892016-02-26 20:51:02 -05002053 cpu_present_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002054
Len Brownc98d5d92012-06-04 00:56:40 -04002055 CPU_FREE(cpu_affinity_set);
2056 cpu_affinity_set = NULL;
2057 cpu_affinity_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002058
Len Brownc98d5d92012-06-04 00:56:40 -04002059 free(thread_even);
2060 free(core_even);
2061 free(package_even);
2062
2063 thread_even = NULL;
2064 core_even = NULL;
2065 package_even = NULL;
2066
2067 free(thread_odd);
2068 free(core_odd);
2069 free(package_odd);
2070
2071 thread_odd = NULL;
2072 core_odd = NULL;
2073 package_odd = NULL;
2074
2075 free(output_buffer);
2076 output_buffer = NULL;
2077 outp = NULL;
Len Brown36229892016-02-26 20:51:02 -05002078
2079 free_fd_percpu();
Len Brown562a2d32016-02-26 23:48:05 -05002080
2081 free(irq_column_2_cpu);
2082 free(irqs_per_cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002083}
2084
Josh Triplett57a42a32013-08-20 17:20:17 -07002085
2086/*
Josh Triplett95aebc42013-08-20 17:20:16 -07002087 * Parse a file containing a single int.
2088 */
2089int parse_int_file(const char *fmt, ...)
2090{
2091 va_list args;
2092 char path[PATH_MAX];
2093 FILE *filep;
2094 int value;
2095
2096 va_start(args, fmt);
2097 vsnprintf(path, sizeof(path), fmt, args);
2098 va_end(args);
Josh Triplett57a42a32013-08-20 17:20:17 -07002099 filep = fopen_or_die(path, "r");
Josh Triplettb2c95d92013-08-20 17:20:18 -07002100 if (fscanf(filep, "%d", &value) != 1)
2101 err(1, "%s: failed to parse number from file", path);
Josh Triplett95aebc42013-08-20 17:20:16 -07002102 fclose(filep);
2103 return value;
2104}
2105
2106/*
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002107 * get_cpu_position_in_core(cpu)
2108 * return the position of the CPU among its HT siblings in the core
2109 * return -1 if the sibling is not in list
Len Brownc98d5d92012-06-04 00:56:40 -04002110 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002111int get_cpu_position_in_core(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04002112{
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002113 char path[64];
2114 FILE *filep;
2115 int this_cpu;
2116 char character;
2117 int i;
2118
2119 sprintf(path,
2120 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
2121 cpu);
2122 filep = fopen(path, "r");
2123 if (filep == NULL) {
2124 perror(path);
2125 exit(1);
2126 }
2127
2128 for (i = 0; i < topo.num_threads_per_core; i++) {
2129 fscanf(filep, "%d", &this_cpu);
2130 if (this_cpu == cpu) {
2131 fclose(filep);
2132 return i;
2133 }
2134
2135 /* Account for no separator after last thread*/
2136 if (i != (topo.num_threads_per_core - 1))
2137 fscanf(filep, "%c", &character);
2138 }
2139
2140 fclose(filep);
2141 return -1;
Len Brown103a8fe2010-10-22 23:53:03 -04002142}
2143
Len Brownc98d5d92012-06-04 00:56:40 -04002144/*
2145 * cpu_is_first_core_in_package(cpu)
2146 * return 1 if given CPU is 1st core in package
2147 */
2148int cpu_is_first_core_in_package(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04002149{
Josh Triplett95aebc42013-08-20 17:20:16 -07002150 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002151}
2152
2153int get_physical_package_id(int cpu)
2154{
Josh Triplett95aebc42013-08-20 17:20:16 -07002155 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002156}
2157
2158int get_core_id(int cpu)
2159{
Josh Triplett95aebc42013-08-20 17:20:16 -07002160 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002161}
2162
Len Brownc98d5d92012-06-04 00:56:40 -04002163int get_num_ht_siblings(int cpu)
2164{
2165 char path[80];
2166 FILE *filep;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002167 int sib1;
2168 int matches = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04002169 char character;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002170 char str[100];
2171 char *ch;
Len Brownc98d5d92012-06-04 00:56:40 -04002172
2173 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
Josh Triplett57a42a32013-08-20 17:20:17 -07002174 filep = fopen_or_die(path, "r");
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002175
Len Brownc98d5d92012-06-04 00:56:40 -04002176 /*
2177 * file format:
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002178 * A ',' separated or '-' separated set of numbers
2179 * (eg 1-2 or 1,3,4,5)
Len Brownc98d5d92012-06-04 00:56:40 -04002180 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002181 fscanf(filep, "%d%c\n", &sib1, &character);
2182 fseek(filep, 0, SEEK_SET);
2183 fgets(str, 100, filep);
2184 ch = strchr(str, character);
2185 while (ch != NULL) {
2186 matches++;
2187 ch = strchr(ch+1, character);
2188 }
Len Brownc98d5d92012-06-04 00:56:40 -04002189
2190 fclose(filep);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002191 return matches+1;
Len Brownc98d5d92012-06-04 00:56:40 -04002192}
2193
Len Brown103a8fe2010-10-22 23:53:03 -04002194/*
Len Brownc98d5d92012-06-04 00:56:40 -04002195 * run func(thread, core, package) in topology order
2196 * skip non-present cpus
Len Brown103a8fe2010-10-22 23:53:03 -04002197 */
2198
Len Brownc98d5d92012-06-04 00:56:40 -04002199int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
2200 struct pkg_data *, struct thread_data *, struct core_data *,
2201 struct pkg_data *), struct thread_data *thread_base,
2202 struct core_data *core_base, struct pkg_data *pkg_base,
2203 struct thread_data *thread_base2, struct core_data *core_base2,
2204 struct pkg_data *pkg_base2)
2205{
2206 int retval, pkg_no, core_no, thread_no;
2207
2208 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
2209 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
2210 for (thread_no = 0; thread_no <
2211 topo.num_threads_per_core; ++thread_no) {
2212 struct thread_data *t, *t2;
2213 struct core_data *c, *c2;
2214 struct pkg_data *p, *p2;
2215
2216 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
2217
2218 if (cpu_is_not_present(t->cpu_id))
2219 continue;
2220
2221 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no);
2222
2223 c = GET_CORE(core_base, core_no, pkg_no);
2224 c2 = GET_CORE(core_base2, core_no, pkg_no);
2225
2226 p = GET_PKG(pkg_base, pkg_no);
2227 p2 = GET_PKG(pkg_base2, pkg_no);
2228
2229 retval = func(t, c, p, t2, c2, p2);
2230 if (retval)
2231 return retval;
2232 }
2233 }
2234 }
2235 return 0;
2236}
2237
2238/*
2239 * run func(cpu) on every cpu in /proc/stat
2240 * return max_cpu number
2241 */
2242int for_all_proc_cpus(int (func)(int))
Len Brown103a8fe2010-10-22 23:53:03 -04002243{
2244 FILE *fp;
Len Brownc98d5d92012-06-04 00:56:40 -04002245 int cpu_num;
Len Brown103a8fe2010-10-22 23:53:03 -04002246 int retval;
2247
Josh Triplett57a42a32013-08-20 17:20:17 -07002248 fp = fopen_or_die(proc_stat, "r");
Len Brown103a8fe2010-10-22 23:53:03 -04002249
2250 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
Josh Triplettb2c95d92013-08-20 17:20:18 -07002251 if (retval != 0)
2252 err(1, "%s: failed to parse format", proc_stat);
Len Brown103a8fe2010-10-22 23:53:03 -04002253
Len Brownc98d5d92012-06-04 00:56:40 -04002254 while (1) {
2255 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 -04002256 if (retval != 1)
2257 break;
2258
Len Brownc98d5d92012-06-04 00:56:40 -04002259 retval = func(cpu_num);
2260 if (retval) {
2261 fclose(fp);
2262 return(retval);
2263 }
Len Brown103a8fe2010-10-22 23:53:03 -04002264 }
2265 fclose(fp);
Len Brownc98d5d92012-06-04 00:56:40 -04002266 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002267}
2268
2269void re_initialize(void)
2270{
Len Brownc98d5d92012-06-04 00:56:40 -04002271 free_all_buffers();
2272 setup_all_buffers();
2273 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
Len Brown103a8fe2010-10-22 23:53:03 -04002274}
2275
Len Brownc98d5d92012-06-04 00:56:40 -04002276
Len Brown103a8fe2010-10-22 23:53:03 -04002277/*
Len Brownc98d5d92012-06-04 00:56:40 -04002278 * count_cpus()
2279 * remember the last one seen, it will be the max
Len Brown103a8fe2010-10-22 23:53:03 -04002280 */
Len Brownc98d5d92012-06-04 00:56:40 -04002281int count_cpus(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04002282{
Len Brownc98d5d92012-06-04 00:56:40 -04002283 if (topo.max_cpu_num < cpu)
2284 topo.max_cpu_num = cpu;
Len Brown103a8fe2010-10-22 23:53:03 -04002285
Len Brownc98d5d92012-06-04 00:56:40 -04002286 topo.num_cpus += 1;
2287 return 0;
2288}
2289int mark_cpu_present(int cpu)
2290{
2291 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brown15aaa342012-03-29 22:19:58 -04002292 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002293}
2294
Len Brown562a2d32016-02-26 23:48:05 -05002295/*
2296 * snapshot_proc_interrupts()
2297 *
2298 * read and record summary of /proc/interrupts
2299 *
2300 * return 1 if config change requires a restart, else return 0
2301 */
2302int snapshot_proc_interrupts(void)
2303{
2304 static FILE *fp;
2305 int column, retval;
2306
2307 if (fp == NULL)
2308 fp = fopen_or_die("/proc/interrupts", "r");
2309 else
2310 rewind(fp);
2311
2312 /* read 1st line of /proc/interrupts to get cpu* name for each column */
2313 for (column = 0; column < topo.num_cpus; ++column) {
2314 int cpu_number;
2315
2316 retval = fscanf(fp, " CPU%d", &cpu_number);
2317 if (retval != 1)
2318 break;
2319
2320 if (cpu_number > topo.max_cpu_num) {
2321 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
2322 return 1;
2323 }
2324
2325 irq_column_2_cpu[column] = cpu_number;
2326 irqs_per_cpu[cpu_number] = 0;
2327 }
2328
2329 /* read /proc/interrupt count lines and sum up irqs per cpu */
2330 while (1) {
2331 int column;
2332 char buf[64];
2333
2334 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
2335 if (retval != 1)
2336 break;
2337
2338 /* read the count per cpu */
2339 for (column = 0; column < topo.num_cpus; ++column) {
2340
2341 int cpu_number, irq_count;
2342
2343 retval = fscanf(fp, " %d", &irq_count);
2344 if (retval != 1)
2345 break;
2346
2347 cpu_number = irq_column_2_cpu[column];
2348 irqs_per_cpu[cpu_number] += irq_count;
2349
2350 }
2351
2352 while (getc(fp) != '\n')
2353 ; /* flush interrupt description */
2354
2355 }
2356 return 0;
2357}
Len Brown27d47352016-02-27 00:37:54 -05002358/*
Len Brownfdf676e2016-02-27 01:28:12 -05002359 * snapshot_gfx_rc6_ms()
2360 *
2361 * record snapshot of
2362 * /sys/class/drm/card0/power/rc6_residency_ms
2363 *
2364 * return 1 if config change requires a restart, else return 0
2365 */
2366int snapshot_gfx_rc6_ms(void)
2367{
2368 FILE *fp;
2369 int retval;
2370
2371 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
2372
2373 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
2374 if (retval != 1)
2375 err(1, "GFX rc6");
2376
2377 fclose(fp);
2378
2379 return 0;
2380}
2381/*
Len Brown27d47352016-02-27 00:37:54 -05002382 * snapshot_gfx_mhz()
2383 *
2384 * record snapshot of
2385 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
2386 *
2387 * return 1 if config change requires a restart, else return 0
2388 */
2389int snapshot_gfx_mhz(void)
2390{
2391 static FILE *fp;
2392 int retval;
2393
2394 if (fp == NULL)
2395 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
2396 else
2397 rewind(fp);
2398
2399 retval = fscanf(fp, "%d", &gfx_cur_mhz);
2400 if (retval != 1)
2401 err(1, "GFX MHz");
2402
2403 return 0;
2404}
Len Brown562a2d32016-02-26 23:48:05 -05002405
2406/*
2407 * snapshot /proc and /sys files
2408 *
2409 * return 1 if configuration restart needed, else return 0
2410 */
2411int snapshot_proc_sysfs_files(void)
2412{
2413 if (snapshot_proc_interrupts())
2414 return 1;
2415
Len Brown812db3f2017-02-10 00:25:41 -05002416 if (DO_BIC(BIC_GFX_rc6))
Len Brownfdf676e2016-02-27 01:28:12 -05002417 snapshot_gfx_rc6_ms();
2418
Len Brown812db3f2017-02-10 00:25:41 -05002419 if (DO_BIC(BIC_GFXMHz))
Len Brown27d47352016-02-27 00:37:54 -05002420 snapshot_gfx_mhz();
2421
Len Brown562a2d32016-02-26 23:48:05 -05002422 return 0;
2423}
2424
Len Brown103a8fe2010-10-22 23:53:03 -04002425void turbostat_loop()
2426{
Len Brownc98d5d92012-06-04 00:56:40 -04002427 int retval;
Len Browne52966c2012-11-08 22:38:05 -05002428 int restarted = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04002429
Len Brown103a8fe2010-10-22 23:53:03 -04002430restart:
Len Browne52966c2012-11-08 22:38:05 -05002431 restarted++;
2432
Len Brown562a2d32016-02-26 23:48:05 -05002433 snapshot_proc_sysfs_files();
Len Brownc98d5d92012-06-04 00:56:40 -04002434 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002435 if (retval < -1) {
2436 exit(retval);
2437 } else if (retval == -1) {
Len Browne52966c2012-11-08 22:38:05 -05002438 if (restarted > 1) {
2439 exit(retval);
2440 }
Len Brownc98d5d92012-06-04 00:56:40 -04002441 re_initialize();
2442 goto restart;
2443 }
Len Browne52966c2012-11-08 22:38:05 -05002444 restarted = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002445 gettimeofday(&tv_even, (struct timezone *)NULL);
2446
2447 while (1) {
Len Brownc98d5d92012-06-04 00:56:40 -04002448 if (for_all_proc_cpus(cpu_is_not_present)) {
Len Brown103a8fe2010-10-22 23:53:03 -04002449 re_initialize();
2450 goto restart;
2451 }
Len Brown2a0609c2016-02-12 22:44:48 -05002452 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002453 if (snapshot_proc_sysfs_files())
2454 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002455 retval = for_all_cpus(get_counters, ODD_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002456 if (retval < -1) {
2457 exit(retval);
2458 } else if (retval == -1) {
Len Brown15aaa342012-03-29 22:19:58 -04002459 re_initialize();
2460 goto restart;
2461 }
Len Brown103a8fe2010-10-22 23:53:03 -04002462 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002463 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002464 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
2465 re_initialize();
2466 goto restart;
2467 }
Len Brownc98d5d92012-06-04 00:56:40 -04002468 compute_average(EVEN_COUNTERS);
2469 format_all_counters(EVEN_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002470 flush_output_stdout();
Len Brown2a0609c2016-02-12 22:44:48 -05002471 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002472 if (snapshot_proc_sysfs_files())
2473 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002474 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002475 if (retval < -1) {
2476 exit(retval);
2477 } else if (retval == -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04002478 re_initialize();
2479 goto restart;
2480 }
Len Brown103a8fe2010-10-22 23:53:03 -04002481 gettimeofday(&tv_even, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002482 timersub(&tv_even, &tv_odd, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002483 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
2484 re_initialize();
2485 goto restart;
2486 }
Len Brownc98d5d92012-06-04 00:56:40 -04002487 compute_average(ODD_COUNTERS);
2488 format_all_counters(ODD_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002489 flush_output_stdout();
Len Brown103a8fe2010-10-22 23:53:03 -04002490 }
2491}
2492
2493void check_dev_msr()
2494{
2495 struct stat sb;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002496 char pathname[32];
Len Brown103a8fe2010-10-22 23:53:03 -04002497
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002498 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2499 if (stat(pathname, &sb))
Len Browna21d38c2015-03-24 16:37:35 -04002500 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
2501 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
Len Brown103a8fe2010-10-22 23:53:03 -04002502}
2503
Len Brown98481e72014-08-15 00:36:50 -04002504void check_permissions()
Len Brown103a8fe2010-10-22 23:53:03 -04002505{
Len Brown98481e72014-08-15 00:36:50 -04002506 struct __user_cap_header_struct cap_header_data;
2507 cap_user_header_t cap_header = &cap_header_data;
2508 struct __user_cap_data_struct cap_data_data;
2509 cap_user_data_t cap_data = &cap_data_data;
2510 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
2511 int do_exit = 0;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002512 char pathname[32];
Len Brown98481e72014-08-15 00:36:50 -04002513
2514 /* check for CAP_SYS_RAWIO */
2515 cap_header->pid = getpid();
2516 cap_header->version = _LINUX_CAPABILITY_VERSION;
2517 if (capget(cap_header, cap_data) < 0)
2518 err(-6, "capget(2) failed");
2519
2520 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
2521 do_exit++;
2522 warnx("capget(CAP_SYS_RAWIO) failed,"
2523 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
2524 }
2525
2526 /* test file permissions */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002527 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2528 if (euidaccess(pathname, R_OK)) {
Len Brown98481e72014-08-15 00:36:50 -04002529 do_exit++;
2530 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
2531 }
2532
2533 /* if all else fails, thell them to be root */
2534 if (do_exit)
2535 if (getuid() != 0)
Len Brownd7899442015-01-23 00:12:33 -05002536 warnx("... or simply run as root");
Len Brown98481e72014-08-15 00:36:50 -04002537
2538 if (do_exit)
2539 exit(-6);
Len Brown103a8fe2010-10-22 23:53:03 -04002540}
2541
Len Brownd7899442015-01-23 00:12:33 -05002542/*
2543 * NHM adds support for additional MSRs:
2544 *
2545 * MSR_SMI_COUNT 0x00000034
2546 *
Len Brownec0adc52015-11-12 02:42:31 -05002547 * MSR_PLATFORM_INFO 0x000000ce
Len Brown1df2e552017-01-07 23:24:57 -05002548 * MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
Len Brownd7899442015-01-23 00:12:33 -05002549 *
Len Browncf4cbe52017-01-01 13:08:33 -05002550 * MSR_MISC_PWR_MGMT 0x000001aa
2551 *
Len Brownd7899442015-01-23 00:12:33 -05002552 * MSR_PKG_C3_RESIDENCY 0x000003f8
2553 * MSR_PKG_C6_RESIDENCY 0x000003f9
2554 * MSR_CORE_C3_RESIDENCY 0x000003fc
2555 * MSR_CORE_C6_RESIDENCY 0x000003fd
2556 *
Len Brownee7e38e2015-02-09 23:39:45 -05002557 * Side effect:
Len Brown1df2e552017-01-07 23:24:57 -05002558 * sets global pkg_cstate_limit to decode MSR_PKG_CST_CONFIG_CONTROL
Len Brown33148d62017-01-21 01:26:16 -05002559 * sets has_misc_feature_control
Len Brownd7899442015-01-23 00:12:33 -05002560 */
Len Brownee7e38e2015-02-09 23:39:45 -05002561int probe_nhm_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04002562{
Len Brownee7e38e2015-02-09 23:39:45 -05002563 unsigned long long msr;
Len Brown21ed5572015-10-19 22:37:40 -04002564 unsigned int base_ratio;
Len Brownee7e38e2015-02-09 23:39:45 -05002565 int *pkg_cstate_limits;
2566
Len Brown103a8fe2010-10-22 23:53:03 -04002567 if (!genuine_intel)
2568 return 0;
2569
2570 if (family != 6)
2571 return 0;
2572
Len Brown21ed5572015-10-19 22:37:40 -04002573 bclk = discover_bclk(family, model);
2574
Len Brown103a8fe2010-10-22 23:53:03 -04002575 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002576 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
2577 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
Len Brown103a8fe2010-10-22 23:53:03 -04002578 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
Len Brown869ce692016-06-16 23:22:37 -04002579 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
2580 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
2581 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2582 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
Len Brownee7e38e2015-02-09 23:39:45 -05002583 pkg_cstate_limits = nhm_pkg_cstate_limits;
2584 break;
Len Brown869ce692016-06-16 23:22:37 -04002585 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
2586 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */
2587 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2588 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
Len Brownee7e38e2015-02-09 23:39:45 -05002589 pkg_cstate_limits = snb_pkg_cstate_limits;
Len Brown33148d62017-01-21 01:26:16 -05002590 has_misc_feature_control = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002591 break;
Len Brown869ce692016-06-16 23:22:37 -04002592 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2593 case INTEL_FAM6_HASWELL_X: /* HSX */
2594 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2595 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2596 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2597 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2598 case INTEL_FAM6_BROADWELL_X: /* BDX */
2599 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2600 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2601 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2602 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2603 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brownee7e38e2015-02-09 23:39:45 -05002604 pkg_cstate_limits = hsw_pkg_cstate_limits;
Len Brown33148d62017-01-21 01:26:16 -05002605 has_misc_feature_control = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002606 break;
Len Brownd8ebb442016-12-01 20:27:46 -05002607 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2608 pkg_cstate_limits = skx_pkg_cstate_limits;
Len Brown33148d62017-01-21 01:26:16 -05002609 has_misc_feature_control = 1;
Len Brownd8ebb442016-12-01 20:27:46 -05002610 break;
Len Brown869ce692016-06-16 23:22:37 -04002611 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
Len Browncf4cbe52017-01-01 13:08:33 -05002612 no_MSR_MISC_PWR_MGMT = 1;
Len Brown869ce692016-06-16 23:22:37 -04002613 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brownee7e38e2015-02-09 23:39:45 -05002614 pkg_cstate_limits = slv_pkg_cstate_limits;
2615 break;
Len Brown869ce692016-06-16 23:22:37 -04002616 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
Len Brownee7e38e2015-02-09 23:39:45 -05002617 pkg_cstate_limits = amt_pkg_cstate_limits;
Len Browncf4cbe52017-01-01 13:08:33 -05002618 no_MSR_MISC_PWR_MGMT = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002619 break;
Len Brown869ce692016-06-16 23:22:37 -04002620 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
Len Brown005c82d2016-12-01 01:35:38 -05002621 case INTEL_FAM6_XEON_PHI_KNM:
Len Brownee7e38e2015-02-09 23:39:45 -05002622 pkg_cstate_limits = phi_pkg_cstate_limits;
2623 break;
Len Brown869ce692016-06-16 23:22:37 -04002624 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05002625 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Len Brown869ce692016-06-16 23:22:37 -04002626 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Browne4085d52016-04-06 17:15:56 -04002627 pkg_cstate_limits = bxt_pkg_cstate_limits;
2628 break;
Len Brown103a8fe2010-10-22 23:53:03 -04002629 default:
2630 return 0;
2631 }
Len Brown1df2e552017-01-07 23:24:57 -05002632 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
Len Browne9257f52015-04-01 21:02:57 -04002633 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
Len Brownee7e38e2015-02-09 23:39:45 -05002634
Len Brownec0adc52015-11-12 02:42:31 -05002635 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown21ed5572015-10-19 22:37:40 -04002636 base_ratio = (msr >> 8) & 0xFF;
2637
2638 base_hz = base_ratio * bclk * 1000000;
2639 has_base_hz = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002640 return 1;
Len Brown103a8fe2010-10-22 23:53:03 -04002641}
Len Brown0f7887c2017-01-12 23:49:18 -05002642/*
Len Brown495c76542017-02-08 02:41:51 -05002643 * SLV client has support for unique MSRs:
Len Brown0f7887c2017-01-12 23:49:18 -05002644 *
2645 * MSR_CC6_DEMOTION_POLICY_CONFIG
2646 * MSR_MC6_DEMOTION_POLICY_CONFIG
2647 */
2648
2649int has_slv_msrs(unsigned int family, unsigned int model)
2650{
2651 if (!genuine_intel)
2652 return 0;
2653
2654 switch (model) {
2655 case INTEL_FAM6_ATOM_SILVERMONT1:
2656 case INTEL_FAM6_ATOM_MERRIFIELD:
2657 case INTEL_FAM6_ATOM_MOOREFIELD:
2658 return 1;
2659 }
2660 return 0;
2661}
Len Brown7170a372017-01-27 02:13:27 -05002662int is_dnv(unsigned int family, unsigned int model)
2663{
2664
2665 if (!genuine_intel)
2666 return 0;
2667
2668 switch (model) {
2669 case INTEL_FAM6_ATOM_DENVERTON:
2670 return 1;
2671 }
2672 return 0;
2673}
Len Brownade0eba2017-02-10 01:56:47 -05002674int is_bdx(unsigned int family, unsigned int model)
2675{
2676
2677 if (!genuine_intel)
2678 return 0;
2679
2680 switch (model) {
2681 case INTEL_FAM6_BROADWELL_X:
2682 case INTEL_FAM6_BROADWELL_XEON_D:
2683 return 1;
2684 }
2685 return 0;
2686}
Len Brown34c761972017-01-27 02:36:41 -05002687int is_skx(unsigned int family, unsigned int model)
2688{
2689
2690 if (!genuine_intel)
2691 return 0;
2692
2693 switch (model) {
2694 case INTEL_FAM6_SKYLAKE_X:
2695 return 1;
2696 }
2697 return 0;
2698}
Len Brown0f7887c2017-01-12 23:49:18 -05002699
Len Brown31e07522017-01-31 23:07:49 -05002700int has_turbo_ratio_limit(unsigned int family, unsigned int model)
Len Brownd7899442015-01-23 00:12:33 -05002701{
Len Brown0f7887c2017-01-12 23:49:18 -05002702 if (has_slv_msrs(family, model))
2703 return 0;
2704
Len Brownd7899442015-01-23 00:12:33 -05002705 switch (model) {
2706 /* Nehalem compatible, but do not include turbo-ratio limit support */
Len Brown869ce692016-06-16 23:22:37 -04002707 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2708 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
2709 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
Len Brown005c82d2016-12-01 01:35:38 -05002710 case INTEL_FAM6_XEON_PHI_KNM:
Len Brownd7899442015-01-23 00:12:33 -05002711 return 0;
2712 default:
2713 return 1;
2714 }
2715}
Len Brown0f7887c2017-01-12 23:49:18 -05002716int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
2717{
2718 if (has_slv_msrs(family, model))
2719 return 1;
2720
2721 return 0;
2722}
Len Brown6574a5d2012-09-21 00:01:31 -04002723int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
2724{
2725 if (!genuine_intel)
2726 return 0;
2727
2728 if (family != 6)
2729 return 0;
2730
2731 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002732 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2733 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brown6574a5d2012-09-21 00:01:31 -04002734 return 1;
2735 default:
2736 return 0;
2737 }
2738}
Len Brownfcd17212015-03-23 20:29:09 -04002739int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
2740{
2741 if (!genuine_intel)
2742 return 0;
2743
2744 if (family != 6)
2745 return 0;
2746
2747 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002748 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brownfcd17212015-03-23 20:29:09 -04002749 return 1;
2750 default:
2751 return 0;
2752 }
2753}
2754
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002755int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
2756{
2757 if (!genuine_intel)
2758 return 0;
2759
2760 if (family != 6)
2761 return 0;
2762
2763 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002764 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown005c82d2016-12-01 01:35:38 -05002765 case INTEL_FAM6_XEON_PHI_KNM:
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002766 return 1;
2767 default:
2768 return 0;
2769 }
2770}
Len Brown31e07522017-01-31 23:07:49 -05002771int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
2772{
2773 if (!genuine_intel)
2774 return 0;
2775
2776 if (family != 6)
2777 return 0;
2778
2779 switch (model) {
2780 case INTEL_FAM6_ATOM_GOLDMONT:
2781 case INTEL_FAM6_SKYLAKE_X:
2782 return 1;
2783 default:
2784 return 0;
2785 }
2786}
Len Brown6fb31432015-06-17 16:23:45 -04002787int has_config_tdp(unsigned int family, unsigned int model)
2788{
2789 if (!genuine_intel)
2790 return 0;
2791
2792 if (family != 6)
2793 return 0;
2794
2795 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002796 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2797 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2798 case INTEL_FAM6_HASWELL_X: /* HSX */
2799 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2800 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2801 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2802 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2803 case INTEL_FAM6_BROADWELL_X: /* BDX */
2804 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2805 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2806 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2807 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2808 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2809 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brown6fb31432015-06-17 16:23:45 -04002810
Len Brown869ce692016-06-16 23:22:37 -04002811 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown005c82d2016-12-01 01:35:38 -05002812 case INTEL_FAM6_XEON_PHI_KNM:
Len Brown6fb31432015-06-17 16:23:45 -04002813 return 1;
2814 default:
2815 return 0;
2816 }
2817}
2818
Len Brownfcd17212015-03-23 20:29:09 -04002819static void
Colin Ian King1b693172016-03-02 13:50:25 +00002820dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
Len Brownfcd17212015-03-23 20:29:09 -04002821{
2822 if (!do_nhm_platform_info)
2823 return;
2824
2825 dump_nhm_platform_info();
2826
2827 if (has_hsw_turbo_ratio_limit(family, model))
2828 dump_hsw_turbo_ratio_limits();
2829
2830 if (has_ivt_turbo_ratio_limit(family, model))
2831 dump_ivt_turbo_ratio_limits();
2832
Len Brown31e07522017-01-31 23:07:49 -05002833 if (has_turbo_ratio_limit(family, model))
2834 dump_turbo_ratio_limits(family, model);
Len Brownfcd17212015-03-23 20:29:09 -04002835
Len Brown0f7887c2017-01-12 23:49:18 -05002836 if (has_atom_turbo_ratio_limit(family, model))
2837 dump_atom_turbo_ratio_limits();
2838
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002839 if (has_knl_turbo_ratio_limit(family, model))
2840 dump_knl_turbo_ratio_limits();
2841
Len Brown6fb31432015-06-17 16:23:45 -04002842 if (has_config_tdp(family, model))
2843 dump_config_tdp();
2844
Len Brownfcd17212015-03-23 20:29:09 -04002845 dump_nhm_cst_cfg();
2846}
2847
Len Brown41618e62017-02-09 18:25:22 -05002848static void
2849dump_sysfs_cstate_config(void)
2850{
2851 char path[64];
2852 char name_buf[16];
2853 char desc[64];
2854 FILE *input;
2855 int state;
2856 char *sp;
2857
2858 if (!DO_BIC(BIC_sysfs))
2859 return;
2860
2861 for (state = 0; state < 10; ++state) {
2862
2863 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
2864 base_cpu, state);
2865 input = fopen(path, "r");
2866 if (input == NULL)
2867 continue;
2868 fgets(name_buf, sizeof(name_buf), input);
2869
2870 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
2871 sp = strchr(name_buf, '-');
2872 if (!sp)
2873 sp = strchrnul(name_buf, '\n');
2874 *sp = '\0';
2875
2876 fclose(input);
2877
2878 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
2879 base_cpu, state);
2880 input = fopen(path, "r");
2881 if (input == NULL)
2882 continue;
2883 fgets(desc, sizeof(desc), input);
2884
2885 fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
2886 fclose(input);
2887 }
2888}
2889
Len Brown6574a5d2012-09-21 00:01:31 -04002890
Len Brown889facb2012-11-08 00:48:57 -05002891/*
2892 * print_epb()
2893 * Decode the ENERGY_PERF_BIAS MSR
2894 */
2895int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2896{
2897 unsigned long long msr;
2898 char *epb_string;
2899 int cpu;
2900
2901 if (!has_epb)
2902 return 0;
2903
2904 cpu = t->cpu_id;
2905
2906 /* EPB is per-package */
2907 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2908 return 0;
2909
2910 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002911 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002912 return -1;
2913 }
2914
2915 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
2916 return 0;
2917
Len Browne9be7dd2015-05-26 12:19:37 -04002918 switch (msr & 0xF) {
Len Brown889facb2012-11-08 00:48:57 -05002919 case ENERGY_PERF_BIAS_PERFORMANCE:
2920 epb_string = "performance";
2921 break;
2922 case ENERGY_PERF_BIAS_NORMAL:
2923 epb_string = "balanced";
2924 break;
2925 case ENERGY_PERF_BIAS_POWERSAVE:
2926 epb_string = "powersave";
2927 break;
2928 default:
2929 epb_string = "custom";
2930 break;
2931 }
Len Brownb7d8c142016-02-13 23:36:17 -05002932 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
Len Brown889facb2012-11-08 00:48:57 -05002933
2934 return 0;
2935}
Len Brown7f5c2582015-12-01 01:36:39 -05002936/*
2937 * print_hwp()
2938 * Decode the MSR_HWP_CAPABILITIES
2939 */
2940int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2941{
2942 unsigned long long msr;
2943 int cpu;
2944
2945 if (!has_hwp)
2946 return 0;
2947
2948 cpu = t->cpu_id;
2949
2950 /* MSR_HWP_CAPABILITIES is per-package */
2951 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2952 return 0;
2953
2954 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002955 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown7f5c2582015-12-01 01:36:39 -05002956 return -1;
2957 }
2958
2959 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
2960 return 0;
2961
Len Brownb7d8c142016-02-13 23:36:17 -05002962 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
Len Brown7f5c2582015-12-01 01:36:39 -05002963 cpu, msr, (msr & (1 << 0)) ? "" : "No-");
2964
2965 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
2966 if ((msr & (1 << 0)) == 0)
2967 return 0;
2968
2969 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
2970 return 0;
2971
Len Brownb7d8c142016-02-13 23:36:17 -05002972 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002973 "(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
2974 cpu, msr,
2975 (unsigned int)HWP_HIGHEST_PERF(msr),
2976 (unsigned int)HWP_GUARANTEED_PERF(msr),
2977 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
2978 (unsigned int)HWP_LOWEST_PERF(msr));
2979
2980 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
2981 return 0;
2982
Len Brownb7d8c142016-02-13 23:36:17 -05002983 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002984 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
2985 cpu, msr,
2986 (unsigned int)(((msr) >> 0) & 0xff),
2987 (unsigned int)(((msr) >> 8) & 0xff),
2988 (unsigned int)(((msr) >> 16) & 0xff),
2989 (unsigned int)(((msr) >> 24) & 0xff),
2990 (unsigned int)(((msr) >> 32) & 0xff3),
2991 (unsigned int)(((msr) >> 42) & 0x1));
2992
2993 if (has_hwp_pkg) {
2994 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
2995 return 0;
2996
Len Brownb7d8c142016-02-13 23:36:17 -05002997 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002998 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
2999 cpu, msr,
3000 (unsigned int)(((msr) >> 0) & 0xff),
3001 (unsigned int)(((msr) >> 8) & 0xff),
3002 (unsigned int)(((msr) >> 16) & 0xff),
3003 (unsigned int)(((msr) >> 24) & 0xff),
3004 (unsigned int)(((msr) >> 32) & 0xff3));
3005 }
3006 if (has_hwp_notify) {
3007 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
3008 return 0;
3009
Len Brownb7d8c142016-02-13 23:36:17 -05003010 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05003011 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
3012 cpu, msr,
3013 ((msr) & 0x1) ? "EN" : "Dis",
3014 ((msr) & 0x2) ? "EN" : "Dis");
3015 }
3016 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
3017 return 0;
3018
Len Brownb7d8c142016-02-13 23:36:17 -05003019 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05003020 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
3021 cpu, msr,
3022 ((msr) & 0x1) ? "" : "No-",
3023 ((msr) & 0x2) ? "" : "No-");
Len Brown889facb2012-11-08 00:48:57 -05003024
3025 return 0;
3026}
3027
Len Brown3a9a9412014-08-15 02:39:52 -04003028/*
3029 * print_perf_limit()
3030 */
3031int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3032{
3033 unsigned long long msr;
3034 int cpu;
3035
3036 cpu = t->cpu_id;
3037
3038 /* per-package */
3039 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3040 return 0;
3041
3042 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003043 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown3a9a9412014-08-15 02:39:52 -04003044 return -1;
3045 }
3046
3047 if (do_core_perf_limit_reasons) {
3048 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05003049 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3050 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
Len Browne33cbe82015-03-13 16:30:57 -04003051 (msr & 1 << 15) ? "bit15, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04003052 (msr & 1 << 14) ? "bit14, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04003053 (msr & 1 << 13) ? "Transitions, " : "",
3054 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
3055 (msr & 1 << 11) ? "PkgPwrL2, " : "",
3056 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3057 (msr & 1 << 9) ? "CorePwr, " : "",
3058 (msr & 1 << 8) ? "Amps, " : "",
3059 (msr & 1 << 6) ? "VR-Therm, " : "",
3060 (msr & 1 << 5) ? "Auto-HWP, " : "",
3061 (msr & 1 << 4) ? "Graphics, " : "",
3062 (msr & 1 << 2) ? "bit2, " : "",
3063 (msr & 1 << 1) ? "ThermStatus, " : "",
3064 (msr & 1 << 0) ? "PROCHOT, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05003065 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 -04003066 (msr & 1 << 31) ? "bit31, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04003067 (msr & 1 << 30) ? "bit30, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04003068 (msr & 1 << 29) ? "Transitions, " : "",
3069 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
3070 (msr & 1 << 27) ? "PkgPwrL2, " : "",
3071 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3072 (msr & 1 << 25) ? "CorePwr, " : "",
3073 (msr & 1 << 24) ? "Amps, " : "",
3074 (msr & 1 << 22) ? "VR-Therm, " : "",
3075 (msr & 1 << 21) ? "Auto-HWP, " : "",
3076 (msr & 1 << 20) ? "Graphics, " : "",
3077 (msr & 1 << 18) ? "bit18, " : "",
3078 (msr & 1 << 17) ? "ThermStatus, " : "",
3079 (msr & 1 << 16) ? "PROCHOT, " : "");
Len Brown3a9a9412014-08-15 02:39:52 -04003080
3081 }
3082 if (do_gfx_perf_limit_reasons) {
3083 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05003084 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3085 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04003086 (msr & 1 << 0) ? "PROCHOT, " : "",
3087 (msr & 1 << 1) ? "ThermStatus, " : "",
3088 (msr & 1 << 4) ? "Graphics, " : "",
3089 (msr & 1 << 6) ? "VR-Therm, " : "",
3090 (msr & 1 << 8) ? "Amps, " : "",
3091 (msr & 1 << 9) ? "GFXPwr, " : "",
3092 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3093 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05003094 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04003095 (msr & 1 << 16) ? "PROCHOT, " : "",
3096 (msr & 1 << 17) ? "ThermStatus, " : "",
3097 (msr & 1 << 20) ? "Graphics, " : "",
3098 (msr & 1 << 22) ? "VR-Therm, " : "",
3099 (msr & 1 << 24) ? "Amps, " : "",
3100 (msr & 1 << 25) ? "GFXPwr, " : "",
3101 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3102 (msr & 1 << 27) ? "PkgPwrL2, " : "");
3103 }
3104 if (do_ring_perf_limit_reasons) {
3105 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05003106 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3107 fprintf(outf, " (Active: %s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04003108 (msr & 1 << 0) ? "PROCHOT, " : "",
3109 (msr & 1 << 1) ? "ThermStatus, " : "",
3110 (msr & 1 << 6) ? "VR-Therm, " : "",
3111 (msr & 1 << 8) ? "Amps, " : "",
3112 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3113 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05003114 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04003115 (msr & 1 << 16) ? "PROCHOT, " : "",
3116 (msr & 1 << 17) ? "ThermStatus, " : "",
3117 (msr & 1 << 22) ? "VR-Therm, " : "",
3118 (msr & 1 << 24) ? "Amps, " : "",
3119 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3120 (msr & 1 << 27) ? "PkgPwrL2, " : "");
3121 }
3122 return 0;
3123}
3124
Len Brown889facb2012-11-08 00:48:57 -05003125#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
3126#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
3127
Colin Ian King1b693172016-03-02 13:50:25 +00003128double get_tdp(unsigned int model)
Len Brown144b44b2013-11-09 00:30:16 -05003129{
3130 unsigned long long msr;
3131
3132 if (do_rapl & RAPL_PKG_POWER_INFO)
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003133 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
Len Brown144b44b2013-11-09 00:30:16 -05003134 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
3135
3136 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003137 case INTEL_FAM6_ATOM_SILVERMONT1:
3138 case INTEL_FAM6_ATOM_SILVERMONT2:
Len Brown144b44b2013-11-09 00:30:16 -05003139 return 30.0;
3140 default:
3141 return 135.0;
3142 }
3143}
3144
Andrey Semin40ee8e32014-12-05 00:07:00 -05003145/*
3146 * rapl_dram_energy_units_probe()
3147 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
3148 */
3149static double
3150rapl_dram_energy_units_probe(int model, double rapl_energy_units)
3151{
3152 /* only called for genuine_intel, family 6 */
3153
3154 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003155 case INTEL_FAM6_HASWELL_X: /* HSX */
3156 case INTEL_FAM6_BROADWELL_X: /* BDX */
3157 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3158 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003159 case INTEL_FAM6_XEON_PHI_KNM:
Andrey Semin40ee8e32014-12-05 00:07:00 -05003160 return (rapl_dram_energy_units = 15.3 / 1000000);
3161 default:
3162 return (rapl_energy_units);
3163 }
3164}
3165
Len Brown144b44b2013-11-09 00:30:16 -05003166
Len Brown889facb2012-11-08 00:48:57 -05003167/*
3168 * rapl_probe()
3169 *
Len Brown144b44b2013-11-09 00:30:16 -05003170 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
Len Brown889facb2012-11-08 00:48:57 -05003171 */
3172void rapl_probe(unsigned int family, unsigned int model)
3173{
3174 unsigned long long msr;
Len Brown144b44b2013-11-09 00:30:16 -05003175 unsigned int time_unit;
Len Brown889facb2012-11-08 00:48:57 -05003176 double tdp;
3177
3178 if (!genuine_intel)
3179 return;
3180
3181 if (family != 6)
3182 return;
3183
3184 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003185 case INTEL_FAM6_SANDYBRIDGE:
3186 case INTEL_FAM6_IVYBRIDGE:
3187 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3188 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3189 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3190 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3191 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
Len Brown144b44b2013-11-09 00:30:16 -05003192 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003193 if (rapl_joules) {
3194 BIC_PRESENT(BIC_Pkg_J);
3195 BIC_PRESENT(BIC_Cor_J);
3196 BIC_PRESENT(BIC_GFX_J);
3197 } else {
3198 BIC_PRESENT(BIC_PkgWatt);
3199 BIC_PRESENT(BIC_CorWatt);
3200 BIC_PRESENT(BIC_GFXWatt);
3201 }
Len Brown889facb2012-11-08 00:48:57 -05003202 break;
Len Brown869ce692016-06-16 23:22:37 -04003203 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003204 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Len Browne4085d52016-04-06 17:15:56 -04003205 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003206 if (rapl_joules)
3207 BIC_PRESENT(BIC_Pkg_J);
3208 else
3209 BIC_PRESENT(BIC_PkgWatt);
Len Browne4085d52016-04-06 17:15:56 -04003210 break;
Len Brown869ce692016-06-16 23:22:37 -04003211 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3212 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3213 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3214 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04003215 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003216 BIC_PRESENT(BIC_PKG__);
3217 BIC_PRESENT(BIC_RAM__);
3218 if (rapl_joules) {
3219 BIC_PRESENT(BIC_Pkg_J);
3220 BIC_PRESENT(BIC_Cor_J);
3221 BIC_PRESENT(BIC_RAM_J);
3222 } else {
3223 BIC_PRESENT(BIC_PkgWatt);
3224 BIC_PRESENT(BIC_CorWatt);
3225 BIC_PRESENT(BIC_RAMWatt);
3226 }
Len Brown0b2bb692015-03-26 00:50:30 -04003227 break;
Len Brown869ce692016-06-16 23:22:37 -04003228 case INTEL_FAM6_HASWELL_X: /* HSX */
3229 case INTEL_FAM6_BROADWELL_X: /* BDX */
3230 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3231 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3232 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003233 case INTEL_FAM6_XEON_PHI_KNM:
Len Brown0b2bb692015-03-26 00:50:30 -04003234 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003235 BIC_PRESENT(BIC_PKG__);
3236 BIC_PRESENT(BIC_RAM__);
3237 if (rapl_joules) {
3238 BIC_PRESENT(BIC_Pkg_J);
3239 BIC_PRESENT(BIC_RAM_J);
3240 } else {
3241 BIC_PRESENT(BIC_PkgWatt);
3242 BIC_PRESENT(BIC_RAMWatt);
3243 }
Len Browne6f9bb32013-12-03 02:19:19 -05003244 break;
Len Brown869ce692016-06-16 23:22:37 -04003245 case INTEL_FAM6_SANDYBRIDGE_X:
3246 case INTEL_FAM6_IVYBRIDGE_X:
Len Brown0b2bb692015-03-26 00:50:30 -04003247 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 Brown812db3f2017-02-10 00:25:41 -05003248 BIC_PRESENT(BIC_PKG__);
3249 BIC_PRESENT(BIC_RAM__);
3250 if (rapl_joules) {
3251 BIC_PRESENT(BIC_Pkg_J);
3252 BIC_PRESENT(BIC_Cor_J);
3253 BIC_PRESENT(BIC_RAM_J);
3254 } else {
3255 BIC_PRESENT(BIC_PkgWatt);
3256 BIC_PRESENT(BIC_CorWatt);
3257 BIC_PRESENT(BIC_RAMWatt);
3258 }
Len Brown144b44b2013-11-09 00:30:16 -05003259 break;
Len Brown869ce692016-06-16 23:22:37 -04003260 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3261 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Jacob Pan91484942016-06-16 09:48:20 -07003262 do_rapl = RAPL_PKG | RAPL_CORES;
Len Brown812db3f2017-02-10 00:25:41 -05003263 if (rapl_joules) {
3264 BIC_PRESENT(BIC_Pkg_J);
3265 BIC_PRESENT(BIC_Cor_J);
3266 } else {
3267 BIC_PRESENT(BIC_PkgWatt);
3268 BIC_PRESENT(BIC_CorWatt);
3269 }
Len Brown889facb2012-11-08 00:48:57 -05003270 break;
Len Brown869ce692016-06-16 23:22:37 -04003271 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Jacob Pan0f644902016-06-16 09:48:22 -07003272 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;
Len Brown812db3f2017-02-10 00:25:41 -05003273 BIC_PRESENT(BIC_PKG__);
3274 BIC_PRESENT(BIC_RAM__);
3275 if (rapl_joules) {
3276 BIC_PRESENT(BIC_Pkg_J);
3277 BIC_PRESENT(BIC_Cor_J);
3278 BIC_PRESENT(BIC_RAM_J);
3279 } else {
3280 BIC_PRESENT(BIC_PkgWatt);
3281 BIC_PRESENT(BIC_CorWatt);
3282 BIC_PRESENT(BIC_RAMWatt);
3283 }
Jacob Pan0f644902016-06-16 09:48:22 -07003284 break;
Len Brown889facb2012-11-08 00:48:57 -05003285 default:
3286 return;
3287 }
3288
3289 /* units on package 0, verify later other packages match */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003290 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
Len Brown889facb2012-11-08 00:48:57 -05003291 return;
3292
3293 rapl_power_units = 1.0 / (1 << (msr & 0xF));
Len Brown869ce692016-06-16 23:22:37 -04003294 if (model == INTEL_FAM6_ATOM_SILVERMONT1)
Len Brown144b44b2013-11-09 00:30:16 -05003295 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
3296 else
3297 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
Len Brown889facb2012-11-08 00:48:57 -05003298
Andrey Semin40ee8e32014-12-05 00:07:00 -05003299 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
3300
Len Brown144b44b2013-11-09 00:30:16 -05003301 time_unit = msr >> 16 & 0xF;
3302 if (time_unit == 0)
3303 time_unit = 0xA;
Len Brown889facb2012-11-08 00:48:57 -05003304
Len Brown144b44b2013-11-09 00:30:16 -05003305 rapl_time_units = 1.0 / (1 << (time_unit));
3306
3307 tdp = get_tdp(model);
Len Brown889facb2012-11-08 00:48:57 -05003308
3309 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
Len Brown96e47152017-01-21 02:26:00 -05003310 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003311 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
Len Brown889facb2012-11-08 00:48:57 -05003312
3313 return;
3314}
3315
Colin Ian King1b693172016-03-02 13:50:25 +00003316void perf_limit_reasons_probe(unsigned int family, unsigned int model)
Len Brown3a9a9412014-08-15 02:39:52 -04003317{
3318 if (!genuine_intel)
3319 return;
3320
3321 if (family != 6)
3322 return;
3323
3324 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003325 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3326 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3327 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
Len Brown3a9a9412014-08-15 02:39:52 -04003328 do_gfx_perf_limit_reasons = 1;
Len Brown869ce692016-06-16 23:22:37 -04003329 case INTEL_FAM6_HASWELL_X: /* HSX */
Len Brown3a9a9412014-08-15 02:39:52 -04003330 do_core_perf_limit_reasons = 1;
3331 do_ring_perf_limit_reasons = 1;
3332 default:
3333 return;
3334 }
3335}
3336
Len Brown889facb2012-11-08 00:48:57 -05003337int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3338{
3339 unsigned long long msr;
3340 unsigned int dts;
3341 int cpu;
3342
3343 if (!(do_dts || do_ptm))
3344 return 0;
3345
3346 cpu = t->cpu_id;
3347
3348 /* DTS is per-core, no need to print for each thread */
Len Brown388e9c82016-12-22 23:57:55 -05003349 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
Len Brown889facb2012-11-08 00:48:57 -05003350 return 0;
3351
3352 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003353 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003354 return -1;
3355 }
3356
3357 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
3358 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
3359 return 0;
3360
3361 dts = (msr >> 16) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05003362 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003363 cpu, msr, tcc_activation_temp - dts);
3364
3365#ifdef THERM_DEBUG
3366 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
3367 return 0;
3368
3369 dts = (msr >> 16) & 0x7F;
3370 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05003371 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003372 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
3373#endif
3374 }
3375
3376
3377 if (do_dts) {
3378 unsigned int resolution;
3379
3380 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
3381 return 0;
3382
3383 dts = (msr >> 16) & 0x7F;
3384 resolution = (msr >> 27) & 0xF;
Len Brownb7d8c142016-02-13 23:36:17 -05003385 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
Len Brown889facb2012-11-08 00:48:57 -05003386 cpu, msr, tcc_activation_temp - dts, resolution);
3387
3388#ifdef THERM_DEBUG
3389 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
3390 return 0;
3391
3392 dts = (msr >> 16) & 0x7F;
3393 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05003394 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003395 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
3396#endif
3397 }
3398
3399 return 0;
3400}
Len Brown36229892016-02-26 20:51:02 -05003401
Len Brown889facb2012-11-08 00:48:57 -05003402void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
3403{
Len Brownb7d8c142016-02-13 23:36:17 -05003404 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05003405 cpu, label,
3406 ((msr >> 15) & 1) ? "EN" : "DIS",
3407 ((msr >> 0) & 0x7FFF) * rapl_power_units,
3408 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
3409 (((msr >> 16) & 1) ? "EN" : "DIS"));
3410
3411 return;
3412}
3413
3414int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3415{
3416 unsigned long long msr;
3417 int cpu;
Len Brown889facb2012-11-08 00:48:57 -05003418
3419 if (!do_rapl)
3420 return 0;
3421
3422 /* RAPL counters are per package, so print only for 1st thread/package */
3423 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3424 return 0;
3425
3426 cpu = t->cpu_id;
3427 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003428 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003429 return -1;
3430 }
3431
3432 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
3433 return -1;
3434
Len Brown96e47152017-01-21 02:26:00 -05003435 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr,
3436 rapl_power_units, rapl_energy_units, rapl_time_units);
3437
Len Brown144b44b2013-11-09 00:30:16 -05003438 if (do_rapl & RAPL_PKG_POWER_INFO) {
3439
Len Brown889facb2012-11-08 00:48:57 -05003440 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
3441 return -5;
3442
3443
Len Brownb7d8c142016-02-13 23:36:17 -05003444 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 -05003445 cpu, msr,
3446 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3447 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3448 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3449 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
3450
Len Brown144b44b2013-11-09 00:30:16 -05003451 }
3452 if (do_rapl & RAPL_PKG) {
3453
Len Brown889facb2012-11-08 00:48:57 -05003454 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
3455 return -9;
3456
Len Brownb7d8c142016-02-13 23:36:17 -05003457 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown96e47152017-01-21 02:26:00 -05003458 cpu, msr, (msr >> 63) & 1 ? "" : "UN");
Len Brown889facb2012-11-08 00:48:57 -05003459
3460 print_power_limit_msr(cpu, msr, "PKG Limit #1");
Len Brownb7d8c142016-02-13 23:36:17 -05003461 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05003462 cpu,
3463 ((msr >> 47) & 1) ? "EN" : "DIS",
3464 ((msr >> 32) & 0x7FFF) * rapl_power_units,
3465 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
3466 ((msr >> 48) & 1) ? "EN" : "DIS");
3467 }
3468
Len Brown0b2bb692015-03-26 00:50:30 -04003469 if (do_rapl & RAPL_DRAM_POWER_INFO) {
Len Brown889facb2012-11-08 00:48:57 -05003470 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
3471 return -6;
3472
Len Brownb7d8c142016-02-13 23:36:17 -05003473 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 -05003474 cpu, msr,
3475 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3476 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3477 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3478 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
Len Brown0b2bb692015-03-26 00:50:30 -04003479 }
3480 if (do_rapl & RAPL_DRAM) {
Len Brown889facb2012-11-08 00:48:57 -05003481 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
3482 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05003483 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown96e47152017-01-21 02:26:00 -05003484 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
Len Brown889facb2012-11-08 00:48:57 -05003485
3486 print_power_limit_msr(cpu, msr, "DRAM Limit");
3487 }
Len Brown144b44b2013-11-09 00:30:16 -05003488 if (do_rapl & RAPL_CORE_POLICY) {
Len Brown96e47152017-01-21 02:26:00 -05003489 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
3490 return -7;
Len Brown889facb2012-11-08 00:48:57 -05003491
Len Brown96e47152017-01-21 02:26:00 -05003492 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown144b44b2013-11-09 00:30:16 -05003493 }
Jacob Pan91484942016-06-16 09:48:20 -07003494 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
Len Brown96e47152017-01-21 02:26:00 -05003495 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
3496 return -9;
3497 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
3498 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3499 print_power_limit_msr(cpu, msr, "Cores Limit");
Len Brown889facb2012-11-08 00:48:57 -05003500 }
3501 if (do_rapl & RAPL_GFX) {
Len Brown96e47152017-01-21 02:26:00 -05003502 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
3503 return -8;
Len Brown889facb2012-11-08 00:48:57 -05003504
Len Brown96e47152017-01-21 02:26:00 -05003505 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown889facb2012-11-08 00:48:57 -05003506
Len Brown96e47152017-01-21 02:26:00 -05003507 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
3508 return -9;
3509 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
3510 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3511 print_power_limit_msr(cpu, msr, "GFX Limit");
Len Brown889facb2012-11-08 00:48:57 -05003512 }
3513 return 0;
3514}
3515
Len Brownd7899442015-01-23 00:12:33 -05003516/*
3517 * SNB adds support for additional MSRs:
3518 *
3519 * MSR_PKG_C7_RESIDENCY 0x000003fa
3520 * MSR_CORE_C7_RESIDENCY 0x000003fe
3521 * MSR_PKG_C2_RESIDENCY 0x0000060d
3522 */
Len Brown103a8fe2010-10-22 23:53:03 -04003523
Len Brownd7899442015-01-23 00:12:33 -05003524int has_snb_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04003525{
3526 if (!genuine_intel)
3527 return 0;
3528
3529 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003530 case INTEL_FAM6_SANDYBRIDGE:
3531 case INTEL_FAM6_SANDYBRIDGE_X:
3532 case INTEL_FAM6_IVYBRIDGE: /* IVB */
3533 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
3534 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3535 case INTEL_FAM6_HASWELL_X: /* HSW */
3536 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3537 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3538 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3539 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
3540 case INTEL_FAM6_BROADWELL_X: /* BDX */
3541 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3542 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3543 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3544 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3545 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
3546 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3547 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003548 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Xiaolong Wang5bbac262016-09-30 17:53:40 +08003549 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Brown103a8fe2010-10-22 23:53:03 -04003550 return 1;
3551 }
3552 return 0;
3553}
3554
Len Brownd7899442015-01-23 00:12:33 -05003555/*
3556 * HSW adds support for additional MSRs:
3557 *
Len Brown5a634262016-04-06 17:15:55 -04003558 * MSR_PKG_C8_RESIDENCY 0x00000630
3559 * MSR_PKG_C9_RESIDENCY 0x00000631
3560 * MSR_PKG_C10_RESIDENCY 0x00000632
3561 *
3562 * MSR_PKGC8_IRTL 0x00000633
3563 * MSR_PKGC9_IRTL 0x00000634
3564 * MSR_PKGC10_IRTL 0x00000635
3565 *
Len Brownd7899442015-01-23 00:12:33 -05003566 */
3567int has_hsw_msrs(unsigned int family, unsigned int model)
Kristen Carlson Accardica587102012-11-21 05:22:43 -08003568{
3569 if (!genuine_intel)
3570 return 0;
3571
3572 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003573 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3574 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3575 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3576 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3577 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3578 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
3579 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003580 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Kristen Carlson Accardica587102012-11-21 05:22:43 -08003581 return 1;
3582 }
3583 return 0;
3584}
3585
Len Brown0b2bb692015-03-26 00:50:30 -04003586/*
3587 * SKL adds support for additional MSRS:
3588 *
3589 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
3590 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
3591 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
3592 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
3593 */
3594int has_skl_msrs(unsigned int family, unsigned int model)
3595{
3596 if (!genuine_intel)
3597 return 0;
3598
3599 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003600 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3601 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3602 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3603 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04003604 return 1;
3605 }
3606 return 0;
3607}
3608
Len Brown144b44b2013-11-09 00:30:16 -05003609int is_slm(unsigned int family, unsigned int model)
3610{
3611 if (!genuine_intel)
3612 return 0;
3613 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003614 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3615 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brown144b44b2013-11-09 00:30:16 -05003616 return 1;
3617 }
3618 return 0;
3619}
3620
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003621int is_knl(unsigned int family, unsigned int model)
3622{
3623 if (!genuine_intel)
3624 return 0;
3625 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003626 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003627 case INTEL_FAM6_XEON_PHI_KNM:
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003628 return 1;
3629 }
3630 return 0;
3631}
3632
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02003633unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
3634{
3635 if (is_knl(family, model))
3636 return 1024;
3637 return 1;
3638}
3639
Len Brown144b44b2013-11-09 00:30:16 -05003640#define SLM_BCLK_FREQS 5
3641double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
3642
3643double slm_bclk(void)
3644{
3645 unsigned long long msr = 3;
3646 unsigned int i;
3647 double freq;
3648
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003649 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003650 fprintf(outf, "SLM BCLK: unknown\n");
Len Brown144b44b2013-11-09 00:30:16 -05003651
3652 i = msr & 0xf;
3653 if (i >= SLM_BCLK_FREQS) {
Len Brownb7d8c142016-02-13 23:36:17 -05003654 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
Colin Ian King0a91e552016-04-25 13:03:15 +01003655 i = 3;
Len Brown144b44b2013-11-09 00:30:16 -05003656 }
3657 freq = slm_freq_table[i];
3658
Len Brown96e47152017-01-21 02:26:00 -05003659 if (!quiet)
Len Brown8f6196c2017-01-07 22:40:23 -05003660 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
Len Brown144b44b2013-11-09 00:30:16 -05003661
3662 return freq;
3663}
3664
Len Brown103a8fe2010-10-22 23:53:03 -04003665double discover_bclk(unsigned int family, unsigned int model)
3666{
Chrzaniuk, Hubert121b48b2016-02-10 16:35:17 +01003667 if (has_snb_msrs(family, model) || is_knl(family, model))
Len Brown103a8fe2010-10-22 23:53:03 -04003668 return 100.00;
Len Brown144b44b2013-11-09 00:30:16 -05003669 else if (is_slm(family, model))
3670 return slm_bclk();
Len Brown103a8fe2010-10-22 23:53:03 -04003671 else
3672 return 133.33;
3673}
3674
Len Brown889facb2012-11-08 00:48:57 -05003675/*
3676 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
3677 * the Thermal Control Circuit (TCC) activates.
3678 * This is usually equal to tjMax.
3679 *
3680 * Older processors do not have this MSR, so there we guess,
3681 * but also allow cmdline over-ride with -T.
3682 *
3683 * Several MSR temperature values are in units of degrees-C
3684 * below this value, including the Digital Thermal Sensor (DTS),
3685 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
3686 */
3687int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3688{
3689 unsigned long long msr;
3690 unsigned int target_c_local;
3691 int cpu;
3692
3693 /* tcc_activation_temp is used only for dts or ptm */
3694 if (!(do_dts || do_ptm))
3695 return 0;
3696
3697 /* this is a per-package concept */
3698 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3699 return 0;
3700
3701 cpu = t->cpu_id;
3702 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003703 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003704 return -1;
3705 }
3706
3707 if (tcc_activation_temp_override != 0) {
3708 tcc_activation_temp = tcc_activation_temp_override;
Len Brownb7d8c142016-02-13 23:36:17 -05003709 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003710 cpu, tcc_activation_temp);
3711 return 0;
3712 }
3713
3714 /* Temperature Target MSR is Nehalem and newer only */
Len Brownd7899442015-01-23 00:12:33 -05003715 if (!do_nhm_platform_info)
Len Brown889facb2012-11-08 00:48:57 -05003716 goto guess;
3717
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003718 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
Len Brown889facb2012-11-08 00:48:57 -05003719 goto guess;
3720
Jean Delvare34821242014-05-01 11:40:19 +02003721 target_c_local = (msr >> 16) & 0xFF;
Len Brown889facb2012-11-08 00:48:57 -05003722
Len Brown96e47152017-01-21 02:26:00 -05003723 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003724 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003725 cpu, msr, target_c_local);
3726
Jean Delvare34821242014-05-01 11:40:19 +02003727 if (!target_c_local)
Len Brown889facb2012-11-08 00:48:57 -05003728 goto guess;
3729
3730 tcc_activation_temp = target_c_local;
3731
3732 return 0;
3733
3734guess:
3735 tcc_activation_temp = TJMAX_DEFAULT;
Len Brownb7d8c142016-02-13 23:36:17 -05003736 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
Len Brown889facb2012-11-08 00:48:57 -05003737 cpu, tcc_activation_temp);
3738
3739 return 0;
3740}
Len Brown69807a62015-11-21 12:22:47 -05003741
Len Brownaa8d8cc2016-03-11 13:26:03 -05003742void decode_feature_control_msr(void)
3743{
3744 unsigned long long msr;
3745
3746 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
3747 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
3748 base_cpu, msr,
3749 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
3750 msr & (1 << 18) ? "SGX" : "");
3751}
3752
Len Brown69807a62015-11-21 12:22:47 -05003753void decode_misc_enable_msr(void)
3754{
3755 unsigned long long msr;
3756
3757 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
Len Browne6512622017-01-11 23:17:24 -05003758 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
Len Brown69807a62015-11-21 12:22:47 -05003759 base_cpu, msr,
Len Browne6512622017-01-11 23:17:24 -05003760 msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
3761 msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
3762 msr & MSR_IA32_MISC_ENABLE_MWAIT ? "No-" : "",
3763 msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "",
3764 msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
Len Brown69807a62015-11-21 12:22:47 -05003765}
3766
Len Brown33148d62017-01-21 01:26:16 -05003767void decode_misc_feature_control(void)
3768{
3769 unsigned long long msr;
3770
3771 if (!has_misc_feature_control)
3772 return;
3773
3774 if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
3775 fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
3776 base_cpu, msr,
3777 msr & (0 << 0) ? "No-" : "",
3778 msr & (1 << 0) ? "No-" : "",
3779 msr & (2 << 0) ? "No-" : "",
3780 msr & (3 << 0) ? "No-" : "");
3781}
Len Brownf0057312015-12-03 01:35:36 -05003782/*
3783 * Decode MSR_MISC_PWR_MGMT
3784 *
3785 * Decode the bits according to the Nehalem documentation
3786 * bit[0] seems to continue to have same meaning going forward
3787 * bit[1] less so...
3788 */
3789void decode_misc_pwr_mgmt_msr(void)
3790{
3791 unsigned long long msr;
3792
3793 if (!do_nhm_platform_info)
3794 return;
3795
Len Browncf4cbe52017-01-01 13:08:33 -05003796 if (no_MSR_MISC_PWR_MGMT)
3797 return;
3798
Len Brownf0057312015-12-03 01:35:36 -05003799 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
Srinivas Pandruvadaddadb8a2016-11-11 14:29:48 -08003800 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
Len Brownf0057312015-12-03 01:35:36 -05003801 base_cpu, msr,
3802 msr & (1 << 0) ? "DIS" : "EN",
Srinivas Pandruvadaddadb8a2016-11-11 14:29:48 -08003803 msr & (1 << 1) ? "EN" : "DIS",
3804 msr & (1 << 8) ? "EN" : "DIS");
Len Brownf0057312015-12-03 01:35:36 -05003805}
Len Brown71616c82017-01-07 22:37:48 -05003806/*
3807 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
3808 *
3809 * This MSRs are present on Silvermont processors,
3810 * Intel Atom processor E3000 series (Baytrail), and friends.
3811 */
3812void decode_c6_demotion_policy_msr(void)
3813{
3814 unsigned long long msr;
3815
3816 if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
3817 fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
3818 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
3819
3820 if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
3821 fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
3822 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
3823}
Len Brown7f5c2582015-12-01 01:36:39 -05003824
Len Brownfcd17212015-03-23 20:29:09 -04003825void process_cpuid()
Len Brown103a8fe2010-10-22 23:53:03 -04003826{
Len Brown61a87ba2015-11-23 02:30:51 -05003827 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
Len Brown103a8fe2010-10-22 23:53:03 -04003828 unsigned int fms, family, model, stepping;
Len Brownb3a34e92017-01-21 00:50:08 -05003829 unsigned int has_turbo;
Len Brown103a8fe2010-10-22 23:53:03 -04003830
3831 eax = ebx = ecx = edx = 0;
3832
Len Brown5aea2f72016-03-13 03:14:35 -04003833 __cpuid(0, max_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003834
3835 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
3836 genuine_intel = 1;
3837
Len Brown96e47152017-01-21 02:26:00 -05003838 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003839 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
Len Brown103a8fe2010-10-22 23:53:03 -04003840 (char *)&ebx, (char *)&edx, (char *)&ecx);
3841
Len Brown5aea2f72016-03-13 03:14:35 -04003842 __cpuid(1, fms, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003843 family = (fms >> 8) & 0xf;
3844 model = (fms >> 4) & 0xf;
3845 stepping = fms & 0xf;
3846 if (family == 6 || family == 0xf)
3847 model += ((fms >> 16) & 0xf) << 4;
3848
Len Brown96e47152017-01-21 02:26:00 -05003849 if (!quiet) {
Len Brownb7d8c142016-02-13 23:36:17 -05003850 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
Len Brown103a8fe2010-10-22 23:53:03 -04003851 max_level, family, model, stepping, family, model, stepping);
Len Brownaa8d8cc2016-03-11 13:26:03 -05003852 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
Len Brown69807a62015-11-21 12:22:47 -05003853 ecx & (1 << 0) ? "SSE3" : "-",
3854 ecx & (1 << 3) ? "MONITOR" : "-",
Len Brownaa8d8cc2016-03-11 13:26:03 -05003855 ecx & (1 << 6) ? "SMX" : "-",
Len Brown69807a62015-11-21 12:22:47 -05003856 ecx & (1 << 7) ? "EIST" : "-",
3857 ecx & (1 << 8) ? "TM2" : "-",
3858 edx & (1 << 4) ? "TSC" : "-",
3859 edx & (1 << 5) ? "MSR" : "-",
3860 edx & (1 << 22) ? "ACPI-TM" : "-",
3861 edx & (1 << 29) ? "TM" : "-");
3862 }
Len Brown103a8fe2010-10-22 23:53:03 -04003863
Josh Triplettb2c95d92013-08-20 17:20:18 -07003864 if (!(edx & (1 << 5)))
3865 errx(1, "CPUID: no MSR");
Len Brown103a8fe2010-10-22 23:53:03 -04003866
3867 /*
3868 * check max extended function levels of CPUID.
3869 * This is needed to check for invariant TSC.
3870 * This check is valid for both Intel and AMD.
3871 */
3872 ebx = ecx = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003873 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003874
Len Brown61a87ba2015-11-23 02:30:51 -05003875 if (max_extended_level >= 0x80000007) {
Len Brown103a8fe2010-10-22 23:53:03 -04003876
Len Brownd7899442015-01-23 00:12:33 -05003877 /*
3878 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
3879 * this check is valid for both Intel and AMD
3880 */
Len Brown5aea2f72016-03-13 03:14:35 -04003881 __cpuid(0x80000007, eax, ebx, ecx, edx);
Len Brownd7899442015-01-23 00:12:33 -05003882 has_invariant_tsc = edx & (1 << 8);
3883 }
Len Brown103a8fe2010-10-22 23:53:03 -04003884
3885 /*
3886 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
3887 * this check is valid for both Intel and AMD
3888 */
3889
Len Brown5aea2f72016-03-13 03:14:35 -04003890 __cpuid(0x6, eax, ebx, ecx, edx);
Thomas Renninger8209e052011-01-21 15:11:19 +01003891 has_aperf = ecx & (1 << 0);
Len Brown812db3f2017-02-10 00:25:41 -05003892 if (has_aperf) {
3893 BIC_PRESENT(BIC_Avg_MHz);
3894 BIC_PRESENT(BIC_Busy);
3895 BIC_PRESENT(BIC_Bzy_MHz);
3896 }
Len Brown889facb2012-11-08 00:48:57 -05003897 do_dts = eax & (1 << 0);
Len Brown812db3f2017-02-10 00:25:41 -05003898 if (do_dts)
3899 BIC_PRESENT(BIC_CoreTmp);
Len Brownb3a34e92017-01-21 00:50:08 -05003900 has_turbo = eax & (1 << 1);
Len Brown889facb2012-11-08 00:48:57 -05003901 do_ptm = eax & (1 << 6);
Len Brown812db3f2017-02-10 00:25:41 -05003902 if (do_ptm)
3903 BIC_PRESENT(BIC_PkgTmp);
Len Brown7f5c2582015-12-01 01:36:39 -05003904 has_hwp = eax & (1 << 7);
3905 has_hwp_notify = eax & (1 << 8);
3906 has_hwp_activity_window = eax & (1 << 9);
3907 has_hwp_epp = eax & (1 << 10);
3908 has_hwp_pkg = eax & (1 << 11);
Len Brown889facb2012-11-08 00:48:57 -05003909 has_epb = ecx & (1 << 3);
3910
Len Brown96e47152017-01-21 02:26:00 -05003911 if (!quiet)
Len Brownb3a34e92017-01-21 00:50:08 -05003912 fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
Len Brown7f5c2582015-12-01 01:36:39 -05003913 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
3914 has_aperf ? "" : "No-",
Len Brownb3a34e92017-01-21 00:50:08 -05003915 has_turbo ? "" : "No-",
Len Brown7f5c2582015-12-01 01:36:39 -05003916 do_dts ? "" : "No-",
3917 do_ptm ? "" : "No-",
3918 has_hwp ? "" : "No-",
3919 has_hwp_notify ? "" : "No-",
3920 has_hwp_activity_window ? "" : "No-",
3921 has_hwp_epp ? "" : "No-",
3922 has_hwp_pkg ? "" : "No-",
3923 has_epb ? "" : "No-");
Len Brown103a8fe2010-10-22 23:53:03 -04003924
Len Brown96e47152017-01-21 02:26:00 -05003925 if (!quiet)
Len Brown69807a62015-11-21 12:22:47 -05003926 decode_misc_enable_msr();
3927
Len Brown33148d62017-01-21 01:26:16 -05003928
Len Brown96e47152017-01-21 02:26:00 -05003929 if (max_level >= 0x7 && !quiet) {
Len Brownaa8d8cc2016-03-11 13:26:03 -05003930 int has_sgx;
3931
3932 ecx = 0;
3933
3934 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
3935
3936 has_sgx = ebx & (1 << 2);
3937 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
3938
3939 if (has_sgx)
3940 decode_feature_control_msr();
3941 }
3942
Len Brown61a87ba2015-11-23 02:30:51 -05003943 if (max_level >= 0x15) {
Len Brown8a5bdf42015-04-01 21:02:57 -04003944 unsigned int eax_crystal;
3945 unsigned int ebx_tsc;
3946
3947 /*
3948 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
3949 */
3950 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003951 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
Len Brown8a5bdf42015-04-01 21:02:57 -04003952
3953 if (ebx_tsc != 0) {
3954
Len Brown96e47152017-01-21 02:26:00 -05003955 if (!quiet && (ebx != 0))
Len Brownb7d8c142016-02-13 23:36:17 -05003956 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003957 eax_crystal, ebx_tsc, crystal_hz);
3958
3959 if (crystal_hz == 0)
3960 switch(model) {
Len Brown869ce692016-06-16 23:22:37 -04003961 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3962 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3963 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3964 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Browne8efbc82016-04-06 17:15:57 -04003965 crystal_hz = 24000000; /* 24.0 MHz */
3966 break;
Len Brown869ce692016-06-16 23:22:37 -04003967 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brown7268d402016-12-01 23:10:39 -05003968 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Brownec53e592016-04-06 17:15:58 -04003969 crystal_hz = 25000000; /* 25.0 MHz */
3970 break;
Len Brown869ce692016-06-16 23:22:37 -04003971 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003972 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Len Browne8efbc82016-04-06 17:15:57 -04003973 crystal_hz = 19200000; /* 19.2 MHz */
Len Brown8a5bdf42015-04-01 21:02:57 -04003974 break;
3975 default:
3976 crystal_hz = 0;
3977 }
3978
3979 if (crystal_hz) {
3980 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
Len Brown96e47152017-01-21 02:26:00 -05003981 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003982 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003983 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
3984 }
3985 }
3986 }
Len Brown61a87ba2015-11-23 02:30:51 -05003987 if (max_level >= 0x16) {
3988 unsigned int base_mhz, max_mhz, bus_mhz, edx;
3989
3990 /*
3991 * CPUID 16H Base MHz, Max MHz, Bus MHz
3992 */
3993 base_mhz = max_mhz = bus_mhz = edx = 0;
3994
Len Brown5aea2f72016-03-13 03:14:35 -04003995 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
Len Brown96e47152017-01-21 02:26:00 -05003996 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003997 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
Len Brown61a87ba2015-11-23 02:30:51 -05003998 base_mhz, max_mhz, bus_mhz);
3999 }
Len Brown8a5bdf42015-04-01 21:02:57 -04004000
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02004001 if (has_aperf)
4002 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
4003
Len Brown812db3f2017-02-10 00:25:41 -05004004 BIC_PRESENT(BIC_IRQ);
4005 BIC_PRESENT(BIC_TSC_MHz);
4006
4007 if (probe_nhm_msrs(family, model)) {
4008 do_nhm_platform_info = 1;
4009 BIC_PRESENT(BIC_CPU_c1);
4010 BIC_PRESENT(BIC_CPU_c3);
4011 BIC_PRESENT(BIC_CPU_c6);
4012 BIC_PRESENT(BIC_SMI);
4013 }
Len Brownd7899442015-01-23 00:12:33 -05004014 do_snb_cstates = has_snb_msrs(family, model);
Len Brown812db3f2017-02-10 00:25:41 -05004015
4016 if (do_snb_cstates)
4017 BIC_PRESENT(BIC_CPU_c7);
4018
Len Brown5a634262016-04-06 17:15:55 -04004019 do_irtl_snb = has_snb_msrs(family, model);
Len Brown0f47c082017-01-27 00:50:45 -05004020 if (do_snb_cstates && (pkg_cstate_limit >= PCL__2))
4021 BIC_PRESENT(BIC_Pkgpc2);
4022 if (pkg_cstate_limit >= PCL__3)
4023 BIC_PRESENT(BIC_Pkgpc3);
4024 if (pkg_cstate_limit >= PCL__6)
4025 BIC_PRESENT(BIC_Pkgpc6);
4026 if (do_snb_cstates && (pkg_cstate_limit >= PCL__7))
4027 BIC_PRESENT(BIC_Pkgpc7);
Len Brown0539ba12017-02-10 00:27:20 -05004028 if (has_slv_msrs(family, model)) {
Len Brown0f47c082017-01-27 00:50:45 -05004029 BIC_NOT_PRESENT(BIC_Pkgpc2);
4030 BIC_NOT_PRESENT(BIC_Pkgpc3);
4031 BIC_PRESENT(BIC_Pkgpc6);
4032 BIC_NOT_PRESENT(BIC_Pkgpc7);
Len Brown0539ba12017-02-10 00:27:20 -05004033 BIC_PRESENT(BIC_Mod_c6);
4034 use_c1_residency_msr = 1;
4035 }
Len Brown7170a372017-01-27 02:13:27 -05004036 if (is_dnv(family, model)) {
4037 BIC_PRESENT(BIC_CPU_c1);
4038 BIC_NOT_PRESENT(BIC_CPU_c3);
4039 BIC_NOT_PRESENT(BIC_Pkgpc3);
4040 BIC_NOT_PRESENT(BIC_CPU_c7);
4041 BIC_NOT_PRESENT(BIC_Pkgpc7);
4042 use_c1_residency_msr = 1;
4043 }
Len Brown34c761972017-01-27 02:36:41 -05004044 if (is_skx(family, model)) {
4045 BIC_NOT_PRESENT(BIC_CPU_c3);
4046 BIC_NOT_PRESENT(BIC_Pkgpc3);
4047 BIC_NOT_PRESENT(BIC_CPU_c7);
4048 BIC_NOT_PRESENT(BIC_Pkgpc7);
4049 }
Len Brownade0eba2017-02-10 01:56:47 -05004050 if (is_bdx(family, model)) {
4051 BIC_NOT_PRESENT(BIC_CPU_c7);
4052 BIC_NOT_PRESENT(BIC_Pkgpc7);
4053 }
Len Brown0f47c082017-01-27 00:50:45 -05004054 if (has_hsw_msrs(family, model)) {
4055 BIC_PRESENT(BIC_Pkgpc8);
4056 BIC_PRESENT(BIC_Pkgpc9);
4057 BIC_PRESENT(BIC_Pkgpc10);
4058 }
Len Brown5a634262016-04-06 17:15:55 -04004059 do_irtl_hsw = has_hsw_msrs(family, model);
Len Brown0b2bb692015-03-26 00:50:30 -04004060 do_skl_residency = has_skl_msrs(family, model);
Len Brown144b44b2013-11-09 00:30:16 -05004061 do_slm_cstates = is_slm(family, model);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07004062 do_knl_cstates = is_knl(family, model);
Len Brown103a8fe2010-10-22 23:53:03 -04004063
Len Brown96e47152017-01-21 02:26:00 -05004064 if (!quiet)
Len Brownf0057312015-12-03 01:35:36 -05004065 decode_misc_pwr_mgmt_msr();
4066
Len Brown96e47152017-01-21 02:26:00 -05004067 if (!quiet && has_slv_msrs(family, model))
Len Brown71616c82017-01-07 22:37:48 -05004068 decode_c6_demotion_policy_msr();
4069
Len Brown889facb2012-11-08 00:48:57 -05004070 rapl_probe(family, model);
Len Brown3a9a9412014-08-15 02:39:52 -04004071 perf_limit_reasons_probe(family, model);
Len Brown889facb2012-11-08 00:48:57 -05004072
Len Brown96e47152017-01-21 02:26:00 -05004073 if (!quiet)
Colin Ian King1b693172016-03-02 13:50:25 +00004074 dump_cstate_pstate_config_info(family, model);
Len Brownfcd17212015-03-23 20:29:09 -04004075
Len Brown41618e62017-02-09 18:25:22 -05004076 if (!quiet)
4077 dump_sysfs_cstate_config();
4078
Len Browna2b7b742015-09-26 00:12:38 -04004079 if (has_skl_msrs(family, model))
4080 calculate_tsc_tweak();
4081
Len Brown812db3f2017-02-10 00:25:41 -05004082 if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
4083 BIC_PRESENT(BIC_GFX_rc6);
Len Brownfdf676e2016-02-27 01:28:12 -05004084
Len Brown812db3f2017-02-10 00:25:41 -05004085 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
4086 BIC_PRESENT(BIC_GFXMHz);
Len Brown27d47352016-02-27 00:37:54 -05004087
Len Brown96e47152017-01-21 02:26:00 -05004088 if (!quiet)
Len Brown33148d62017-01-21 01:26:16 -05004089 decode_misc_feature_control();
4090
Len Brown889facb2012-11-08 00:48:57 -05004091 return;
Len Brown103a8fe2010-10-22 23:53:03 -04004092}
4093
Len Brownd8af6f52015-02-10 01:56:38 -05004094void help()
Len Brown103a8fe2010-10-22 23:53:03 -04004095{
Len Brownb7d8c142016-02-13 23:36:17 -05004096 fprintf(outf,
Len Brownd8af6f52015-02-10 01:56:38 -05004097 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
4098 "\n"
4099 "Turbostat forks the specified COMMAND and prints statistics\n"
4100 "when COMMAND completes.\n"
4101 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
4102 "to print statistics, until interrupted.\n"
Len Brown388e9c82016-12-22 23:57:55 -05004103 "--add add a counter\n"
4104 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
Len Brown1ef7d212017-02-10 23:54:15 -05004105 "--cpu cpu-set limit output to summary plus cpu-set cpu-set\n"
Len Brown96e47152017-01-21 02:26:00 -05004106 "--quiet skip decoding system configuration header\n"
Len Brownd8af6f52015-02-10 01:56:38 -05004107 "--interval sec Override default 5-second measurement interval\n"
4108 "--help print this help message\n"
Len Brownb7d8c142016-02-13 23:36:17 -05004109 "--out file create or truncate \"file\" for all output\n"
Len Brownd8af6f52015-02-10 01:56:38 -05004110 "--version print version information\n"
4111 "\n"
4112 "For more help, run \"man turbostat\"\n");
Len Brown103a8fe2010-10-22 23:53:03 -04004113}
4114
4115
4116/*
4117 * in /dev/cpu/ return success for names that are numbers
4118 * ie. filter out ".", "..", "microcode".
4119 */
4120int dir_filter(const struct dirent *dirp)
4121{
4122 if (isdigit(dirp->d_name[0]))
4123 return 1;
4124 else
4125 return 0;
4126}
4127
4128int open_dev_cpu_msr(int dummy1)
4129{
4130 return 0;
4131}
4132
Len Brownc98d5d92012-06-04 00:56:40 -04004133void topology_probe()
4134{
4135 int i;
4136 int max_core_id = 0;
4137 int max_package_id = 0;
4138 int max_siblings = 0;
4139 struct cpu_topology {
4140 int core_id;
4141 int physical_package_id;
4142 } *cpus;
4143
4144 /* Initialize num_cpus, max_cpu_num */
4145 topo.num_cpus = 0;
4146 topo.max_cpu_num = 0;
4147 for_all_proc_cpus(count_cpus);
4148 if (!summary_only && topo.num_cpus > 1)
Len Brown812db3f2017-02-10 00:25:41 -05004149 BIC_PRESENT(BIC_CPU);
Len Brownc98d5d92012-06-04 00:56:40 -04004150
Len Brownd8af6f52015-02-10 01:56:38 -05004151 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004152 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
Len Brownc98d5d92012-06-04 00:56:40 -04004153
4154 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
Josh Triplettb2c95d92013-08-20 17:20:18 -07004155 if (cpus == NULL)
4156 err(1, "calloc cpus");
Len Brownc98d5d92012-06-04 00:56:40 -04004157
4158 /*
4159 * Allocate and initialize cpu_present_set
4160 */
4161 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07004162 if (cpu_present_set == NULL)
4163 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04004164 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
4165 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
4166 for_all_proc_cpus(mark_cpu_present);
4167
4168 /*
Len Brown1ef7d212017-02-10 23:54:15 -05004169 * Validate that all cpus in cpu_subset are also in cpu_present_set
4170 */
4171 for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
4172 if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
4173 if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
4174 err(1, "cpu%d not present", i);
4175 }
4176
4177 /*
Len Brownc98d5d92012-06-04 00:56:40 -04004178 * Allocate and initialize cpu_affinity_set
4179 */
4180 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07004181 if (cpu_affinity_set == NULL)
4182 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04004183 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
4184 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
4185
4186
4187 /*
4188 * For online cpus
4189 * find max_core_id, max_package_id
4190 */
4191 for (i = 0; i <= topo.max_cpu_num; ++i) {
4192 int siblings;
4193
4194 if (cpu_is_not_present(i)) {
Len Brownd8af6f52015-02-10 01:56:38 -05004195 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004196 fprintf(outf, "cpu%d NOT PRESENT\n", i);
Len Brownc98d5d92012-06-04 00:56:40 -04004197 continue;
4198 }
4199 cpus[i].core_id = get_core_id(i);
4200 if (cpus[i].core_id > max_core_id)
4201 max_core_id = cpus[i].core_id;
4202
4203 cpus[i].physical_package_id = get_physical_package_id(i);
4204 if (cpus[i].physical_package_id > max_package_id)
4205 max_package_id = cpus[i].physical_package_id;
4206
4207 siblings = get_num_ht_siblings(i);
4208 if (siblings > max_siblings)
4209 max_siblings = siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05004210 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004211 fprintf(outf, "cpu %d pkg %d core %d\n",
Len Brownc98d5d92012-06-04 00:56:40 -04004212 i, cpus[i].physical_package_id, cpus[i].core_id);
4213 }
4214 topo.num_cores_per_pkg = max_core_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05004215 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004216 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
Len Brownc98d5d92012-06-04 00:56:40 -04004217 max_core_id, topo.num_cores_per_pkg);
Len Brown0f47c082017-01-27 00:50:45 -05004218 if (!summary_only && topo.num_cores_per_pkg > 1)
Len Brown812db3f2017-02-10 00:25:41 -05004219 BIC_PRESENT(BIC_Core);
Len Brownc98d5d92012-06-04 00:56:40 -04004220
4221 topo.num_packages = max_package_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05004222 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004223 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
Len Brownc98d5d92012-06-04 00:56:40 -04004224 max_package_id, topo.num_packages);
Len Brown1cc21f72015-02-23 00:34:57 -05004225 if (debug && !summary_only && topo.num_packages > 1)
Len Brown812db3f2017-02-10 00:25:41 -05004226 BIC_PRESENT(BIC_Package);
Len Brownc98d5d92012-06-04 00:56:40 -04004227
4228 topo.num_threads_per_core = max_siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05004229 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004230 fprintf(outf, "max_siblings %d\n", max_siblings);
Len Brownc98d5d92012-06-04 00:56:40 -04004231
4232 free(cpus);
4233}
4234
4235void
4236allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
4237{
4238 int i;
4239
4240 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
Len Brown678a3bd2017-02-09 22:22:13 -05004241 topo.num_packages, sizeof(struct thread_data));
Len Brownc98d5d92012-06-04 00:56:40 -04004242 if (*t == NULL)
4243 goto error;
4244
4245 for (i = 0; i < topo.num_threads_per_core *
4246 topo.num_cores_per_pkg * topo.num_packages; i++)
4247 (*t)[i].cpu_id = -1;
4248
4249 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
Len Brown678a3bd2017-02-09 22:22:13 -05004250 sizeof(struct core_data));
Len Brownc98d5d92012-06-04 00:56:40 -04004251 if (*c == NULL)
4252 goto error;
4253
4254 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
4255 (*c)[i].core_id = -1;
4256
Len Brown678a3bd2017-02-09 22:22:13 -05004257 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
Len Brownc98d5d92012-06-04 00:56:40 -04004258 if (*p == NULL)
4259 goto error;
4260
4261 for (i = 0; i < topo.num_packages; i++)
4262 (*p)[i].package_id = i;
4263
4264 return;
4265error:
Josh Triplettb2c95d92013-08-20 17:20:18 -07004266 err(1, "calloc counters");
Len Brownc98d5d92012-06-04 00:56:40 -04004267}
4268/*
4269 * init_counter()
4270 *
4271 * set cpu_id, core_num, pkg_num
4272 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
4273 *
4274 * increment topo.num_cores when 1st core in pkg seen
4275 */
4276void init_counter(struct thread_data *thread_base, struct core_data *core_base,
4277 struct pkg_data *pkg_base, int thread_num, int core_num,
4278 int pkg_num, int cpu_id)
4279{
4280 struct thread_data *t;
4281 struct core_data *c;
4282 struct pkg_data *p;
4283
4284 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num);
4285 c = GET_CORE(core_base, core_num, pkg_num);
4286 p = GET_PKG(pkg_base, pkg_num);
4287
4288 t->cpu_id = cpu_id;
4289 if (thread_num == 0) {
4290 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
4291 if (cpu_is_first_core_in_package(cpu_id))
4292 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
4293 }
4294
4295 c->core_id = core_num;
4296 p->package_id = pkg_num;
4297}
4298
4299
4300int initialize_counters(int cpu_id)
4301{
4302 int my_thread_id, my_core_id, my_package_id;
4303
4304 my_package_id = get_physical_package_id(cpu_id);
4305 my_core_id = get_core_id(cpu_id);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07004306 my_thread_id = get_cpu_position_in_core(cpu_id);
4307 if (!my_thread_id)
Len Brownc98d5d92012-06-04 00:56:40 -04004308 topo.num_cores++;
Len Brownc98d5d92012-06-04 00:56:40 -04004309
4310 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
4311 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
4312 return 0;
4313}
4314
4315void allocate_output_buffer()
4316{
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004317 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
Len Brownc98d5d92012-06-04 00:56:40 -04004318 outp = output_buffer;
Josh Triplettb2c95d92013-08-20 17:20:18 -07004319 if (outp == NULL)
4320 err(-1, "calloc output buffer");
Len Brownc98d5d92012-06-04 00:56:40 -04004321}
Len Brown36229892016-02-26 20:51:02 -05004322void allocate_fd_percpu(void)
4323{
Mika Westerberg01a67ad2016-04-22 11:13:23 +03004324 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown36229892016-02-26 20:51:02 -05004325 if (fd_percpu == NULL)
4326 err(-1, "calloc fd_percpu");
4327}
Len Brown562a2d32016-02-26 23:48:05 -05004328void allocate_irq_buffers(void)
4329{
4330 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
4331 if (irq_column_2_cpu == NULL)
4332 err(-1, "calloc %d", topo.num_cpus);
Len Brownc98d5d92012-06-04 00:56:40 -04004333
Mika Westerberg01a67ad2016-04-22 11:13:23 +03004334 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown562a2d32016-02-26 23:48:05 -05004335 if (irqs_per_cpu == NULL)
Mika Westerberg01a67ad2016-04-22 11:13:23 +03004336 err(-1, "calloc %d", topo.max_cpu_num + 1);
Len Brown562a2d32016-02-26 23:48:05 -05004337}
Len Brownc98d5d92012-06-04 00:56:40 -04004338void setup_all_buffers(void)
4339{
4340 topology_probe();
Len Brown562a2d32016-02-26 23:48:05 -05004341 allocate_irq_buffers();
Len Brown36229892016-02-26 20:51:02 -05004342 allocate_fd_percpu();
Len Brownc98d5d92012-06-04 00:56:40 -04004343 allocate_counters(&thread_even, &core_even, &package_even);
4344 allocate_counters(&thread_odd, &core_odd, &package_odd);
4345 allocate_output_buffer();
4346 for_all_proc_cpus(initialize_counters);
4347}
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004348
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04004349void set_base_cpu(void)
4350{
4351 base_cpu = sched_getcpu();
4352 if (base_cpu < 0)
4353 err(-ENODEV, "No valid cpus found");
4354
4355 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004356 fprintf(outf, "base_cpu = %d\n", base_cpu);
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04004357}
4358
Len Brown103a8fe2010-10-22 23:53:03 -04004359void turbostat_init()
4360{
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04004361 setup_all_buffers();
4362 set_base_cpu();
Len Brown103a8fe2010-10-22 23:53:03 -04004363 check_dev_msr();
Len Brown98481e72014-08-15 00:36:50 -04004364 check_permissions();
Len Brownfcd17212015-03-23 20:29:09 -04004365 process_cpuid();
Len Brown103a8fe2010-10-22 23:53:03 -04004366
Len Brown103a8fe2010-10-22 23:53:03 -04004367
Len Brown96e47152017-01-21 02:26:00 -05004368 if (!quiet)
Len Brown7f5c2582015-12-01 01:36:39 -05004369 for_all_cpus(print_hwp, ODD_COUNTERS);
4370
Len Brown96e47152017-01-21 02:26:00 -05004371 if (!quiet)
Len Brown889facb2012-11-08 00:48:57 -05004372 for_all_cpus(print_epb, ODD_COUNTERS);
4373
Len Brown96e47152017-01-21 02:26:00 -05004374 if (!quiet)
Len Brown3a9a9412014-08-15 02:39:52 -04004375 for_all_cpus(print_perf_limit, ODD_COUNTERS);
4376
Len Brown96e47152017-01-21 02:26:00 -05004377 if (!quiet)
Len Brown889facb2012-11-08 00:48:57 -05004378 for_all_cpus(print_rapl, ODD_COUNTERS);
4379
4380 for_all_cpus(set_temperature_target, ODD_COUNTERS);
4381
Len Brown96e47152017-01-21 02:26:00 -05004382 if (!quiet)
Len Brown889facb2012-11-08 00:48:57 -05004383 for_all_cpus(print_thermal, ODD_COUNTERS);
Len Brown5a634262016-04-06 17:15:55 -04004384
Len Brown96e47152017-01-21 02:26:00 -05004385 if (!quiet && do_irtl_snb)
Len Brown5a634262016-04-06 17:15:55 -04004386 print_irtl();
Len Brown103a8fe2010-10-22 23:53:03 -04004387}
4388
4389int fork_it(char **argv)
4390{
Len Brown103a8fe2010-10-22 23:53:03 -04004391 pid_t child_pid;
Len Brownd91bb172012-11-01 00:08:19 -04004392 int status;
Len Brownd15cf7c2012-06-03 23:24:00 -04004393
Len Brownd91bb172012-11-01 00:08:19 -04004394 status = for_all_cpus(get_counters, EVEN_COUNTERS);
4395 if (status)
4396 exit(status);
Len Brownc98d5d92012-06-04 00:56:40 -04004397 /* clear affinity side-effect of get_counters() */
4398 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
Len Brown103a8fe2010-10-22 23:53:03 -04004399 gettimeofday(&tv_even, (struct timezone *)NULL);
4400
4401 child_pid = fork();
4402 if (!child_pid) {
4403 /* child */
4404 execvp(argv[0], argv);
4405 } else {
Len Brown103a8fe2010-10-22 23:53:03 -04004406
4407 /* parent */
Josh Triplettb2c95d92013-08-20 17:20:18 -07004408 if (child_pid == -1)
4409 err(1, "fork");
Len Brown103a8fe2010-10-22 23:53:03 -04004410
4411 signal(SIGINT, SIG_IGN);
4412 signal(SIGQUIT, SIG_IGN);
Josh Triplettb2c95d92013-08-20 17:20:18 -07004413 if (waitpid(child_pid, &status, 0) == -1)
4414 err(status, "waitpid");
Len Brown103a8fe2010-10-22 23:53:03 -04004415 }
Len Brownc98d5d92012-06-04 00:56:40 -04004416 /*
4417 * n.b. fork_it() does not check for errors from for_all_cpus()
4418 * because re-starting is problematic when forking
4419 */
4420 for_all_cpus(get_counters, ODD_COUNTERS);
Len Brown103a8fe2010-10-22 23:53:03 -04004421 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04004422 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04004423 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
4424 fprintf(outf, "%s: Counter reset detected\n", progname);
4425 else {
4426 compute_average(EVEN_COUNTERS);
4427 format_all_counters(EVEN_COUNTERS);
4428 }
Len Brown103a8fe2010-10-22 23:53:03 -04004429
Len Brownb7d8c142016-02-13 23:36:17 -05004430 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
4431
4432 flush_output_stderr();
Len Brown103a8fe2010-10-22 23:53:03 -04004433
Len Brownd91bb172012-11-01 00:08:19 -04004434 return status;
Len Brown103a8fe2010-10-22 23:53:03 -04004435}
4436
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004437int get_and_dump_counters(void)
4438{
4439 int status;
4440
4441 status = for_all_cpus(get_counters, ODD_COUNTERS);
4442 if (status)
4443 return status;
4444
4445 status = for_all_cpus(dump_counters, ODD_COUNTERS);
4446 if (status)
4447 return status;
4448
Len Brownb7d8c142016-02-13 23:36:17 -05004449 flush_output_stdout();
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004450
4451 return status;
4452}
4453
Len Brownd8af6f52015-02-10 01:56:38 -05004454void print_version() {
Len Brown0539ba12017-02-10 00:27:20 -05004455 fprintf(outf, "turbostat version 4.17 10 Jan 2017"
Len Brownd8af6f52015-02-10 01:56:38 -05004456 " - Len Brown <lenb@kernel.org>\n");
4457}
4458
Len Brown495c76542017-02-08 02:41:51 -05004459int add_counter(unsigned int msr_num, char *path, char *name,
4460 unsigned int width, enum counter_scope scope,
Len Brown41618e62017-02-09 18:25:22 -05004461 enum counter_type type, enum counter_format format, int flags)
Len Brown388e9c82016-12-22 23:57:55 -05004462{
4463 struct msr_counter *msrp;
4464
4465 msrp = calloc(1, sizeof(struct msr_counter));
4466 if (msrp == NULL) {
4467 perror("calloc");
4468 exit(1);
4469 }
4470
4471 msrp->msr_num = msr_num;
4472 strncpy(msrp->name, name, NAME_BYTES);
Len Brown495c76542017-02-08 02:41:51 -05004473 if (path)
4474 strncpy(msrp->path, path, PATH_BYTES);
Len Brown388e9c82016-12-22 23:57:55 -05004475 msrp->width = width;
4476 msrp->type = type;
4477 msrp->format = format;
Len Brown41618e62017-02-09 18:25:22 -05004478 msrp->flags = flags;
Len Brown388e9c82016-12-22 23:57:55 -05004479
4480 switch (scope) {
4481
4482 case SCOPE_CPU:
Len Brown388e9c82016-12-22 23:57:55 -05004483 msrp->next = sys.tp;
4484 sys.tp = msrp;
Len Brown678a3bd2017-02-09 22:22:13 -05004485 sys.added_thread_counters++;
4486 if (sys.added_thread_counters > MAX_ADDED_COUNTERS) {
4487 fprintf(stderr, "exceeded max %d added thread counters\n",
4488 MAX_ADDED_COUNTERS);
4489 exit(-1);
4490 }
Len Brown388e9c82016-12-22 23:57:55 -05004491 break;
4492
4493 case SCOPE_CORE:
Len Brown388e9c82016-12-22 23:57:55 -05004494 msrp->next = sys.cp;
4495 sys.cp = msrp;
Len Brown678a3bd2017-02-09 22:22:13 -05004496 sys.added_core_counters++;
4497 if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
4498 fprintf(stderr, "exceeded max %d added core counters\n",
4499 MAX_ADDED_COUNTERS);
4500 exit(-1);
4501 }
Len Brown388e9c82016-12-22 23:57:55 -05004502 break;
4503
4504 case SCOPE_PACKAGE:
Len Brown388e9c82016-12-22 23:57:55 -05004505 msrp->next = sys.pp;
4506 sys.pp = msrp;
Len Brown678a3bd2017-02-09 22:22:13 -05004507 sys.added_package_counters++;
4508 if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
4509 fprintf(stderr, "exceeded max %d added package counters\n",
4510 MAX_ADDED_COUNTERS);
4511 exit(-1);
4512 }
Len Brown388e9c82016-12-22 23:57:55 -05004513 break;
4514 }
4515
4516 return 0;
4517}
4518
4519void parse_add_command(char *add_command)
4520{
4521 int msr_num = 0;
Len Brown495c76542017-02-08 02:41:51 -05004522 char *path = NULL;
Len Brown0f47c082017-01-27 00:50:45 -05004523 char name_buffer[NAME_BYTES] = "";
Len Brown388e9c82016-12-22 23:57:55 -05004524 int width = 64;
4525 int fail = 0;
4526 enum counter_scope scope = SCOPE_CPU;
4527 enum counter_type type = COUNTER_CYCLES;
4528 enum counter_format format = FORMAT_DELTA;
4529
4530 while (add_command) {
4531
4532 if (sscanf(add_command, "msr0x%x", &msr_num) == 1)
4533 goto next;
4534
4535 if (sscanf(add_command, "msr%d", &msr_num) == 1)
4536 goto next;
4537
Len Brown495c76542017-02-08 02:41:51 -05004538 if (*add_command == '/') {
4539 path = add_command;
4540 goto next;
4541 }
4542
Len Brown388e9c82016-12-22 23:57:55 -05004543 if (sscanf(add_command, "u%d", &width) == 1) {
4544 if ((width == 32) || (width == 64))
4545 goto next;
4546 width = 64;
4547 }
4548 if (!strncmp(add_command, "cpu", strlen("cpu"))) {
4549 scope = SCOPE_CPU;
4550 goto next;
4551 }
4552 if (!strncmp(add_command, "core", strlen("core"))) {
4553 scope = SCOPE_CORE;
4554 goto next;
4555 }
4556 if (!strncmp(add_command, "package", strlen("package"))) {
4557 scope = SCOPE_PACKAGE;
4558 goto next;
4559 }
4560 if (!strncmp(add_command, "cycles", strlen("cycles"))) {
4561 type = COUNTER_CYCLES;
4562 goto next;
4563 }
4564 if (!strncmp(add_command, "seconds", strlen("seconds"))) {
4565 type = COUNTER_SECONDS;
4566 goto next;
4567 }
Len Brown41618e62017-02-09 18:25:22 -05004568 if (!strncmp(add_command, "usec", strlen("usec"))) {
4569 type = COUNTER_USEC;
4570 goto next;
4571 }
Len Brown388e9c82016-12-22 23:57:55 -05004572 if (!strncmp(add_command, "raw", strlen("raw"))) {
4573 format = FORMAT_RAW;
4574 goto next;
4575 }
4576 if (!strncmp(add_command, "delta", strlen("delta"))) {
4577 format = FORMAT_DELTA;
4578 goto next;
4579 }
4580 if (!strncmp(add_command, "percent", strlen("percent"))) {
4581 format = FORMAT_PERCENT;
4582 goto next;
4583 }
4584
4585 if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) { /* 18 < NAME_BYTES */
4586 char *eos;
4587
4588 eos = strchr(name_buffer, ',');
4589 if (eos)
4590 *eos = '\0';
4591 goto next;
4592 }
4593
4594next:
4595 add_command = strchr(add_command, ',');
Len Brown495c76542017-02-08 02:41:51 -05004596 if (add_command) {
4597 *add_command = '\0';
Len Brown388e9c82016-12-22 23:57:55 -05004598 add_command++;
Len Brown495c76542017-02-08 02:41:51 -05004599 }
Len Brown388e9c82016-12-22 23:57:55 -05004600
4601 }
Len Brown495c76542017-02-08 02:41:51 -05004602 if ((msr_num == 0) && (path == NULL)) {
4603 fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
Len Brown388e9c82016-12-22 23:57:55 -05004604 fail++;
4605 }
4606
4607 /* generate default column header */
4608 if (*name_buffer == '\0') {
4609 if (format == FORMAT_RAW) {
4610 if (width == 32)
4611 sprintf(name_buffer, "msr%d", msr_num);
4612 else
4613 sprintf(name_buffer, "MSR%d", msr_num);
4614 } else if (format == FORMAT_DELTA) {
4615 if (width == 32)
4616 sprintf(name_buffer, "cnt%d", msr_num);
4617 else
4618 sprintf(name_buffer, "CNT%d", msr_num);
4619 } else if (format == FORMAT_PERCENT) {
4620 if (width == 32)
4621 sprintf(name_buffer, "msr%d%%", msr_num);
4622 else
4623 sprintf(name_buffer, "MSR%d%%", msr_num);
4624 }
4625 }
4626
Len Brown41618e62017-02-09 18:25:22 -05004627 if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0))
Len Brown388e9c82016-12-22 23:57:55 -05004628 fail++;
4629
4630 if (fail) {
4631 help();
4632 exit(1);
4633 }
4634}
Len Brown41618e62017-02-09 18:25:22 -05004635
4636void probe_sysfs(void)
4637{
4638 char path[64];
4639 char name_buf[16];
4640 FILE *input;
4641 int state;
4642 char *sp;
4643
4644 if (!DO_BIC(BIC_sysfs))
4645 return;
4646
4647 for (state = 10; state > 0; --state) {
4648
4649 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
4650 base_cpu, state);
4651 input = fopen(path, "r");
4652 if (input == NULL)
4653 continue;
4654 fgets(name_buf, sizeof(name_buf), input);
4655
4656 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
4657 sp = strchr(name_buf, '-');
4658 if (!sp)
4659 sp = strchrnul(name_buf, '\n');
4660 *sp = '%';
4661 *(sp + 1) = '\0';
4662
4663 fclose(input);
4664
4665 sprintf(path, "cpuidle/state%d/time", state);
4666
4667 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC,
4668 FORMAT_PERCENT, SYSFS_PERCPU);
4669 }
4670
4671 for (state = 10; state > 0; --state) {
4672
4673 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
4674 base_cpu, state);
4675 input = fopen(path, "r");
4676 if (input == NULL)
4677 continue;
4678 fgets(name_buf, sizeof(name_buf), input);
4679 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
4680 sp = strchr(name_buf, '-');
4681 if (!sp)
4682 sp = strchrnul(name_buf, '\n');
4683 *sp = '\0';
4684 fclose(input);
4685
4686 sprintf(path, "cpuidle/state%d/usage", state);
4687
4688 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS,
4689 FORMAT_DELTA, SYSFS_PERCPU);
4690 }
4691
4692}
4693
Len Brown1ef7d212017-02-10 23:54:15 -05004694
4695/*
4696 * parse cpuset with following syntax
4697 * 1,2,4..6,8-10 and set bits in cpu_subset
4698 */
4699void parse_cpu_command(char *optarg)
4700{
4701 unsigned int start, end;
4702 char *next;
4703
4704 cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
4705 if (cpu_subset == NULL)
4706 err(3, "CPU_ALLOC");
4707 cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
4708
4709 CPU_ZERO_S(cpu_subset_size, cpu_subset);
4710
4711 next = optarg;
4712
4713 while (next && *next) {
4714
4715 if (*next == '-') /* no negative cpu numbers */
4716 goto error;
4717
4718 start = strtoul(next, &next, 10);
4719
4720 if (start >= CPU_SUBSET_MAXCPUS)
4721 goto error;
4722 CPU_SET_S(start, cpu_subset_size, cpu_subset);
4723
4724 if (*next == '\0')
4725 break;
4726
4727 if (*next == ',') {
4728 next += 1;
4729 continue;
4730 }
4731
4732 if (*next == '-') {
4733 next += 1; /* start range */
4734 } else if (*next == '.') {
4735 next += 1;
4736 if (*next == '.')
4737 next += 1; /* start range */
4738 else
4739 goto error;
4740 }
4741
4742 end = strtoul(next, &next, 10);
4743 if (end <= start)
4744 goto error;
4745
4746 while (++start <= end) {
4747 if (start >= CPU_SUBSET_MAXCPUS)
4748 goto error;
4749 CPU_SET_S(start, cpu_subset_size, cpu_subset);
4750 }
4751
4752 if (*next == ',')
4753 next += 1;
4754 else if (*next != '\0')
4755 goto error;
4756 }
4757
4758 return;
4759
4760error:
4761 fprintf(stderr, "'--cpu %s' malformed\n", optarg);
4762 exit(-1);
4763}
4764
Len Brown812db3f2017-02-10 00:25:41 -05004765/*
4766 * HIDE_LIST - hide this list of counters, show the rest [default]
4767 * SHOW_LIST - show this list of counters, hide the rest
4768 */
4769enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
4770
4771int shown;
4772/*
4773 * parse_show_hide() - process cmdline to set default counter action
4774 */
4775void parse_show_hide(char *optarg, enum show_hide_mode new_mode)
4776{
4777 /*
4778 * --show: show only those specified
4779 * The 1st invocation will clear and replace the enabled mask
4780 * subsequent invocations can add to it.
4781 */
4782 if (new_mode == SHOW_LIST) {
4783 if (shown == 0)
4784 bic_enabled = bic_lookup(optarg);
4785 else
4786 bic_enabled |= bic_lookup(optarg);
4787 shown = 1;
4788
4789 return;
4790 }
4791
4792 /*
4793 * --hide: do not show those specified
4794 * multiple invocations simply clear more bits in enabled mask
4795 */
4796 bic_enabled &= ~bic_lookup(optarg);
Len Brown41618e62017-02-09 18:25:22 -05004797
Len Brown812db3f2017-02-10 00:25:41 -05004798}
4799
Len Brown103a8fe2010-10-22 23:53:03 -04004800void cmdline(int argc, char **argv)
4801{
4802 int opt;
Len Brownd8af6f52015-02-10 01:56:38 -05004803 int option_index = 0;
4804 static struct option long_options[] = {
Len Brown388e9c82016-12-22 23:57:55 -05004805 {"add", required_argument, 0, 'a'},
Len Brown1ef7d212017-02-10 23:54:15 -05004806 {"cpu", required_argument, 0, 'c'},
Len Brownd8af6f52015-02-10 01:56:38 -05004807 {"Dump", no_argument, 0, 'D'},
Len Brown96e47152017-01-21 02:26:00 -05004808 {"debug", no_argument, 0, 'd'}, /* internal, not documented */
Len Brownd8af6f52015-02-10 01:56:38 -05004809 {"interval", required_argument, 0, 'i'},
4810 {"help", no_argument, 0, 'h'},
Len Brown812db3f2017-02-10 00:25:41 -05004811 {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help
Len Brownd8af6f52015-02-10 01:56:38 -05004812 {"Joules", no_argument, 0, 'J'},
Len Brownb7d8c142016-02-13 23:36:17 -05004813 {"out", required_argument, 0, 'o'},
Len Brownd8af6f52015-02-10 01:56:38 -05004814 {"Package", no_argument, 0, 'p'},
4815 {"processor", no_argument, 0, 'p'},
Len Brown96e47152017-01-21 02:26:00 -05004816 {"quiet", no_argument, 0, 'q'},
Len Brown812db3f2017-02-10 00:25:41 -05004817 {"show", required_argument, 0, 's'},
Len Brownd8af6f52015-02-10 01:56:38 -05004818 {"Summary", no_argument, 0, 'S'},
4819 {"TCC", required_argument, 0, 'T'},
4820 {"version", no_argument, 0, 'v' },
4821 {0, 0, 0, 0 }
4822 };
Len Brown103a8fe2010-10-22 23:53:03 -04004823
4824 progname = argv[0];
4825
Len Brown96e47152017-01-21 02:26:00 -05004826 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpqST:v",
Len Brownd8af6f52015-02-10 01:56:38 -05004827 long_options, &option_index)) != -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04004828 switch (opt) {
Len Brown388e9c82016-12-22 23:57:55 -05004829 case 'a':
4830 parse_add_command(optarg);
4831 break;
Len Brown1ef7d212017-02-10 23:54:15 -05004832 case 'c':
4833 parse_cpu_command(optarg);
4834 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004835 case 'D':
4836 dump_only++;
Len Brown8e180f32012-09-22 01:25:08 -04004837 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004838 case 'd':
4839 debug++;
Len Brown2f32edf2012-09-21 23:45:46 -04004840 break;
Len Brown812db3f2017-02-10 00:25:41 -05004841 case 'H':
4842 parse_show_hide(optarg, HIDE_LIST);
4843 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004844 case 'h':
4845 default:
4846 help();
4847 exit(1);
4848 case 'i':
Len Brown2a0609c2016-02-12 22:44:48 -05004849 {
4850 double interval = strtod(optarg, NULL);
4851
4852 if (interval < 0.001) {
Len Brownb7d8c142016-02-13 23:36:17 -05004853 fprintf(outf, "interval %f seconds is too small\n",
Len Brown2a0609c2016-02-12 22:44:48 -05004854 interval);
4855 exit(2);
4856 }
4857
4858 interval_ts.tv_sec = interval;
4859 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
4860 }
Len Brown889facb2012-11-08 00:48:57 -05004861 break;
Dirk Brandewie5c56be92013-12-16 10:23:41 -08004862 case 'J':
4863 rapl_joules++;
4864 break;
Len Brownb7d8c142016-02-13 23:36:17 -05004865 case 'o':
4866 outf = fopen_or_die(optarg, "w");
4867 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004868 case 'P':
4869 show_pkg_only++;
4870 break;
4871 case 'p':
4872 show_core_only++;
4873 break;
Len Brown96e47152017-01-21 02:26:00 -05004874 case 'q':
4875 quiet = 1;
4876 break;
Len Brown812db3f2017-02-10 00:25:41 -05004877 case 's':
4878 parse_show_hide(optarg, SHOW_LIST);
4879 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004880 case 'S':
4881 summary_only++;
4882 break;
4883 case 'T':
4884 tcc_activation_temp_override = atoi(optarg);
4885 break;
4886 case 'v':
4887 print_version();
4888 exit(0);
4889 break;
Len Brown103a8fe2010-10-22 23:53:03 -04004890 }
4891 }
4892}
4893
4894int main(int argc, char **argv)
4895{
Len Brownb7d8c142016-02-13 23:36:17 -05004896 outf = stderr;
4897
Len Brown103a8fe2010-10-22 23:53:03 -04004898 cmdline(argc, argv);
4899
Len Brown96e47152017-01-21 02:26:00 -05004900 if (!quiet)
Len Brownd8af6f52015-02-10 01:56:38 -05004901 print_version();
Len Brown103a8fe2010-10-22 23:53:03 -04004902
Len Brown41618e62017-02-09 18:25:22 -05004903 probe_sysfs();
4904
Len Brown103a8fe2010-10-22 23:53:03 -04004905 turbostat_init();
4906
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004907 /* dump counters and exit */
4908 if (dump_only)
4909 return get_and_dump_counters();
4910
Len Brown103a8fe2010-10-22 23:53:03 -04004911 /*
4912 * if any params left, it must be a command to fork
4913 */
4914 if (argc - optind)
4915 return fork_it(argv + optind);
4916 else
4917 turbostat_loop();
4918
4919 return 0;
4920}