From patchwork Sun Oct 7 02:43:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Len Brown X-Patchwork-Id: 1560481 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 1C543E00DD for ; Sun, 7 Oct 2012 02:45:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752473Ab2JGCoI (ORCPT ); Sat, 6 Oct 2012 22:44:08 -0400 Received: from mail-qc0-f174.google.com ([209.85.216.174]:47373 "EHLO mail-qc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751886Ab2JGCoC (ORCPT ); Sat, 6 Oct 2012 22:44:02 -0400 Received: by mail-qc0-f174.google.com with SMTP id d3so2032903qch.19 for ; Sat, 06 Oct 2012 19:44:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:in-reply-to:references:reply-to:organization; bh=HbK+bU8R8wlJ4weX009yceanx6+KCfzUYOJkObnwro8=; b=JW+uo0L3JLhXtXYQ9BFa0Hrzj4akBstkkxjw7iI6SEx1+N3QRrjcOetS1K/dTsrg15 sj1VdmpcSZj6ht90J6NHysmaZxM0vu1G5DTV4a9QsSeA3gYBAKEceSQjTkfojn0jt64H nL4E8kxFYO43HvUPV7w8U9E7hVq3XStlexz/VDGrbjpaTfH/D/XlLT6oVOuWfhb68zKM 1QdbauT2KTOz7nQxqga4Dw100QP3Dxk9CgE5fy0HoBT/KVA/LdC4EUOSh/Oj4LZ3d+5J kERTmbUuEedSRmBGjzpIJQurepzyNUSzupqKGxXBHCbsZOb8fGy7DyJR1Dxs7TLnn5Op Gitw== Received: by 10.229.172.35 with SMTP id j35mr5454489qcz.64.1349577842163; Sat, 06 Oct 2012 19:44:02 -0700 (PDT) Received: from x980.localdomain6 (pool-74-104-146-186.bstnma.fios.verizon.net. [74.104.146.186]) by mx.google.com with ESMTPS id g18sm14309050qan.1.2012.10.06.19.43.46 (version=SSLv3 cipher=OTHER); Sat, 06 Oct 2012 19:43:54 -0700 (PDT) From: Len Brown To: linux-acpi@vger.kernel.org, linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Len Brown Subject: [PATCH 44/49] tools/power turbostat: add [-m MSR#] option Date: Sat, 6 Oct 2012 22:43:14 -0400 Message-Id: <2f32edf12c1eafc8e5b1b0337360993fde1b3565.1349554106.git.len.brown@intel.com> X-Mailer: git-send-email 1.8.0.rc0.18.gf84667d In-Reply-To: <1349577799-566-1-git-send-email-lenb@kernel.org> References: <1349577799-566-1-git-send-email-lenb@kernel.org> In-Reply-To: References: Reply-To: Len Brown Organization: Intel Open Source Technology Center Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org From: Len Brown -m MSR# prints the specified MSR in 32-bit format -M MSR# prints the specified MSR in 64-bit format Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.8 | 14 +++++++- tools/power/x86/turbostat/turbostat.c | 68 +++++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 74e4450..8e7b29af 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -6,12 +6,14 @@ turbostat \- Report processor frequency and idle statistics .B turbostat .RB [ "\-s" ] .RB [ "\-v" ] +.RB [ "\-m MSR#" ] .RB [ "\-M MSR#" ] .RB command .br .B turbostat .RB [ "\-s" ] .RB [ "\-v" ] +.RB [ "\-m MSR#" ] .RB [ "\-M MSR#" ] .RB [ "\-i interval_sec" ] .SH DESCRIPTION @@ -35,7 +37,10 @@ The \fB-p\fP option limits output to the 1st thread in each package. .PP The \fB-v\fP option increases verbosity. .PP -The \fB-M MSR#\fP option dumps the specified MSR, +The \fB-m MSR#\fP option dumps the specified 32-bit MSR, +in addition to the usual frequency and idle statistics. +.PP +The \fB-M MSR#\fP option dumps the specified 64-bit MSR, in addition to the usual frequency and idle statistics. .PP The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. @@ -165,6 +170,13 @@ may work poorly on Linux-2.6.20 through 2.6.29, as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF in those kernels. +If the TSC column does not make sense, then +the other numbers will also make no sense. +Turbostat is lightweight, and its data collection is not atomic. +These issues are usually caused by an extremely short measurement +interval (much less than 1 second), or system activity that prevents +turbostat from being able to run on all CPUS to quickly collect data. + The APERF, MPERF MSRs are defined to count non-halted cycles. Although it is not guaranteed by the architecture, turbostat assumes that they count at TSC rate, which is true on all processors tested to date. diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 5ce88dd..946e9ab 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -63,7 +63,8 @@ unsigned int has_invariant_tsc; unsigned int do_nehalem_platform_info; unsigned int do_nehalem_turbo_ratio_limit; unsigned int do_ivt_turbo_ratio_limit; -unsigned int extra_msr_offset; +unsigned int extra_msr_offset32; +unsigned int extra_msr_offset64; double bclk; unsigned int show_pkg; unsigned int show_core; @@ -84,7 +85,8 @@ struct thread_data { unsigned long long aperf; unsigned long long mperf; unsigned long long c1; /* derived */ - unsigned long long extra_msr; + unsigned long long extra_msr64; + unsigned int extra_msr32; unsigned int cpu_id; unsigned int flags; #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 @@ -206,6 +208,24 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) return 0; } +/* + * Truncate the 8 bytes we read from /dev/cpu/.../msr + * to the 4 bytes requested + */ + +int get_msr32(int cpu, off_t offset, unsigned int *msr) +{ + int retval; + + unsigned long long msr64; + + retval = get_msr(cpu, offset, &msr64); + *msr = (unsigned int) msr64; + + return retval; +} + + void print_header(void) { if (show_pkg) @@ -223,8 +243,10 @@ void print_header(void) if (has_aperf) outp += sprintf(outp, " GHz"); outp += sprintf(outp, " TSC"); - if (extra_msr_offset) - outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset); + if (extra_msr_offset32) + outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset32); + if (extra_msr_offset64) + outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset64); if (do_nhm_cstates) outp += sprintf(outp, " %%c1"); if (do_nhm_cstates) @@ -256,8 +278,10 @@ int dump_counters(struct thread_data *t, struct core_data *c, fprintf(stderr, "aperf: %016llX\n", t->aperf); fprintf(stderr, "mperf: %016llX\n", t->mperf); fprintf(stderr, "c1: %016llX\n", t->c1); + fprintf(stderr, "msr0x%x: %08X\n", + extra_msr_offset32, t->extra_msr32); fprintf(stderr, "msr0x%x: %016llX\n", - extra_msr_offset, t->extra_msr); + extra_msr_offset64, t->extra_msr64); } if (c) { @@ -361,9 +385,13 @@ int format_counters(struct thread_data *t, struct core_data *c, /* TSC */ outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); + /* msr */ + if (extra_msr_offset32) + outp += sprintf(outp, " 0x%08x", t->extra_msr32); + /* MSR */ - if (extra_msr_offset) - outp += sprintf(outp, " 0x%016llx", t->extra_msr); + if (extra_msr_offset64) + outp += sprintf(outp, " 0x%016llx", t->extra_msr64); if (do_nhm_cstates) { if (!skip_c1) @@ -506,9 +534,10 @@ delta_thread(struct thread_data *new, struct thread_data *old, } /* - * for "extra msr", just copy the latest w/o subtracting + * Extra MSR is a snapshot, simply copy latest w/o subtracting */ - old->extra_msr = new->extra_msr; + old->extra_msr32 = new->extra_msr32; + old->extra_msr64 = new->extra_msr64; } int delta_cpu(struct thread_data *t, struct core_data *c, @@ -632,8 +661,12 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) return -4; } - if (extra_msr_offset) - if (get_msr(cpu, extra_msr_offset, &t->extra_msr)) + if (extra_msr_offset32) + if (get_msr32(cpu, extra_msr_offset32, &t->extra_msr32)) + return -5; + + if (extra_msr_offset64) + if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) return -5; /* collect core counters only for 1st thread in core */ @@ -1242,7 +1275,7 @@ void check_cpuid() void usage() { - fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n", + fprintf(stderr, "%s: [-v] [-m msr#] [-M MSR#] [-i interval_sec | command ...]\n", progname); exit(1); } @@ -1532,7 +1565,7 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) { + while ((opt = getopt(argc, argv, "+cpsvi:m:M:")) != -1) { switch (opt) { case 'c': show_core_only++; @@ -1549,10 +1582,15 @@ void cmdline(int argc, char **argv) case 'i': interval_sec = atoi(optarg); break; + case 'm': + sscanf(optarg, "%x", &extra_msr_offset32); + if (verbose > 1) + fprintf(stderr, "msr 0x%X\n", extra_msr_offset32); + break; case 'M': - sscanf(optarg, "%x", &extra_msr_offset); + sscanf(optarg, "%x", &extra_msr_offset64); if (verbose > 1) - fprintf(stderr, "MSR 0x%X\n", extra_msr_offset); + fprintf(stderr, "MSR 0x%X\n", extra_msr_offset64); break; default: usage();