tools/power turbostat: update parameters, documentation
authorLen Brown <len.brown@intel.com>
Tue, 10 Feb 2015 06:56:38 +0000 (01:56 -0500)
committerLen Brown <len.brown@intel.com>
Tue, 10 Feb 2015 06:56:38 +0000 (01:56 -0500)
Long format options added, though the short ones should still work.
eg. the new "--Counter 0x10" is the same as the old "-C 0x10"

Note this Incompatibility:
Old:
-v displayed verbose debug output

New:
-v and --version simpaly display version

Additional parameters:
-d and --debug display verbose debug output
-h and --help display a help message

Updated turbosat.8 man page accordingly.

Signed-off-by: Len Brown <len.brown@intel.com>
tools/power/x86/turbostat/turbostat.8
tools/power/x86/turbostat/turbostat.c

index 9b950699e63d9d5fcf057d9f499071afa3d4b9ba..feea7ad9500bbb78740bff54b08ab4b83d26e244 100644 (file)
@@ -9,7 +9,7 @@ turbostat \- Report processor frequency and idle statistics
 .br
 .B turbostat
 .RB [ Options ]
-.RB [ "\-i interval_sec" ]
+.RB [ "\--interval seconds" ]
 .SH DESCRIPTION
 \fBturbostat \fP reports processor topology, frequency,
 idle power-state statistics, temperature and power on X86 processors.
@@ -18,31 +18,41 @@ The first method is to supply a
 \fBcommand\fP, which is forked and statistics are printed
 upon its completion.
 The second method is to omit the command,
-and turbodstat will print statistics every 5 seconds.
-The 5-second interval can changed using the -i option.
+and turbostat displays statistics every 5 seconds.
+The 5-second interval can be changed using the --interval option.
 
-Some information is not availalbe on older processors.
+Some information is not available on older processors.
 .SS Options
-The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
+\fB--Counter MSR#\fP shows the delta of the specified 64-bit MSR counter.
 .PP
-The \fB-P\fP option limits output to the 1st thread in each Package.
+\fB--counter MSR#\fP shows the delta of the specified 32-bit MSR counter.
 .PP
-The \fB-S\fP option limits output to a 1-line System Summary for each interval.
+\fB--Dump\fP displays the raw counter values.
 .PP
-The \fB-v\fP option increases verbosity.
+\fB--debug\fP displays additional system configuration information.  Invoking this parameter
+more than once may also enable internal turbostat debug information.
 .PP
-The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
+\fB--interval seconds\fP overrides the default 5-second measurement interval.
 .PP
-The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
+\fB--help\fP displays usage for the most common parameters.
 .PP
-The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
+\fB--Joules\fP displays energy in Joules, rather than dividing Joules by time to print power in Watts.
 .PP
-The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
+\fB--MSR MSR#\fP shows the specified 64-bit MSR value.
 .PP
-The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
-The default is 5 seconds.
+\fB--msr MSR#\fP shows the specified 32-bit MSR value.
 .PP
-The \fBcommand\fP parameter forks \fBcommand\fP and upon its exit,
+\fB--Package\fP limits output to the system summary plus the 1st thread in each Package.
+.PP
+\fB--processor\fP limits output to the system summary plus the 1st thread in each processor of each package.  Ie. it skips hyper-threaded siblings.
+.PP
+\fB--Summary\fP limits output to a 1-line System Summary for each interval.
+.PP
+\fB--TCC temperature\fP sets the Thermal Control Circuit temperature for systems which do not export that value.  This is used for making sense of the Digital Thermal Sensor outputs, as they return degrees Celsius below the TCC activation temperature.
+.PP
+\fB--version\fP displays the version.
+.PP
+The \fBcommand\fP parameter forks \fBcommand\fP, and upon its exit,
 displays the statistics gathered since it was forked.
 .PP
 .SH FIELD DESCRIPTIONS
@@ -52,7 +62,7 @@ displays the statistics gathered since it was forked.
 \fBCPU\fP Linux CPU (logical processor) number.
 Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology.
 \fBAVG_MHz\fP number of cycles executed divided by time elapsed.
-\fB%Buzy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
+\fB%Busy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
 \fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state).
 \fBTSC_MHz\fP average MHz that the TSC ran during the entire interval.
 \fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states.
@@ -68,7 +78,7 @@ Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading T
 .fi
 .PP
 .SH EXAMPLE
-Without any parameters, turbostat prints out counters ever 5 seconds.
+Without any parameters, turbostat displays statistics ever 5 seconds.
 (override interval with "-i sec" option, or specify a command
 for turbostat to fork).
 
@@ -91,19 +101,19 @@ Subsequent rows show per-CPU statistics.
        3       3       3    0.20    1596    3492       0    0.44    0.00   99.37    0.00      23
        3       7       5    0.31    1596    3492       0    0.33
 .fi
-.SH VERBOSE EXAMPLE
-The "-v" option adds verbosity to the output:
+.SH DEBUG EXAMPLE
+The "--debug" option prints additional system information before measurements:
 
 .nf
-[root@ivy]# turbostat -v
-turbostat v3.0 November 23, 2012 - Len Brown <lenb@kernel.org>
+turbostat version 4.0 10-Feb, 2015 - Len Brown <lenb@kernel.org>
 CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3a:9 (6:58:9)
 CPUID(6): APERF, DTS, PTM, EPB
-RAPL: 851 sec. Joule Counter Range
+RAPL: 851 sec. Joule Counter Range, at 77 Watts
 cpu0: MSR_NHM_PLATFORM_INFO: 0x81010f0012300
 16 * 100 = 1600 MHz max efficiency
 35 * 100 = 3500 MHz TSC frequency
-cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6-noret)
+cpu0: MSR_IA32_POWER_CTL: 0x0014005d (C1E auto-promotion: DISabled)
+cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6n)
 cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
 37 * 100 = 3700 MHz max turbo 4 active cores
 38 * 100 = 3800 MHz max turbo 3 active cores
@@ -112,9 +122,9 @@ cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
 cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced)
 cpu0: MSR_RAPL_POWER_UNIT: 0x000a1003 (0.125000 Watts, 0.000015 Joules, 0.000977 sec.)
 cpu0: MSR_PKG_POWER_INFO: 0x01e00268 (77 W TDP, RAPL 60 - 0 W, 0.000000 sec.)
-cpu0: MSR_PKG_POWER_LIMIT: 0x830000148268 (UNlocked)
+cpu0: MSR_PKG_POWER_LIMIT: 0x30000148268 (UNlocked)
 cpu0: PKG Limit #1: ENabled (77.000000 Watts, 1.000000 sec, clamp DISabled)
-cpu0: PKG Limit #2: ENabled (96.000000 Watts, 0.000977* sec, clamp DISabled)
+cpu0: PKG Limit #2: DISabled (96.000000 Watts, 0.000977* sec, clamp DISabled)
 cpu0: MSR_PP0_POLICY: 0
 cpu0: MSR_PP0_POWER_LIMIT: 0x00000000 (UNlocked)
 cpu0: Cores Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
@@ -123,9 +133,9 @@ cpu0: MSR_PP1_POWER_LIMIT: 0x00000000 (UNlocked)
 cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
 cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00691400 (105 C)
 cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x884e0000 (27 C)
-cpu0: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1)
-cpu1: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1)
-cpu2: MSR_IA32_THERM_STATUS: 0x88540000 (21 C +/- 1)
+cpu0: MSR_IA32_THERM_STATUS: 0x88580000 (17 C +/- 1)
+cpu1: MSR_IA32_THERM_STATUS: 0x885a0000 (15 C +/- 1)
+cpu2: MSR_IA32_THERM_STATUS: 0x88570000 (18 C +/- 1)
 cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1)
  ...
 .fi
@@ -195,7 +205,7 @@ in those kernels.
 
 AVG_MHz = APERF_delta/measurement_interval.  This is the actual
 number of elapsed cycles divided by the entire sample interval --
-including idle time.  Note that this calculation is resiliant
+including idle time.  Note that this calculation is resilient
 to systems lacking a non-stop TSC.
 
 TSC_MHz = TSC_delta/measurement_interval.
index ba8846b309f7c74f5b4f500bfbdb9e0764492dcd..3f5a9af34f471bced94ecdbce0c13260fa0217db 100644 (file)
@@ -33,6 +33,7 @@
 #include <signal.h>
 #include <sys/time.h>
 #include <stdlib.h>
+#include <getopt.h>
 #include <dirent.h>
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
 
 char *proc_stat = "/proc/stat";
-unsigned int interval_sec = 5; /* set with -i interval_sec */
-unsigned int verbose;          /* set with -v */
-unsigned int rapl_verbose;     /* set with -R */
-unsigned int rapl_joules;      /* set with -J */
-unsigned int thermal_verbose;  /* set with -T */
-unsigned int summary_only;     /* set with -S */
-unsigned int dump_only;                /* set with -s */
+unsigned int interval_sec = 5;
+unsigned int debug;
+unsigned int rapl_joules;
+unsigned int summary_only;
+unsigned int dump_only;
 unsigned int skip_c0;
 unsigned int skip_c1;
 unsigned int do_nhm_cstates;
@@ -727,7 +726,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
        }
 
        if (old->mperf == 0) {
-               if (verbose > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
+               if (debug > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
                old->mperf = 1; /* divide by 0 protection */
        }
 
@@ -1847,7 +1846,7 @@ void rapl_probe(unsigned int family, unsigned int model)
        tdp = get_tdp(model);
 
        rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
-       if (verbose)
+       if (debug)
                fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
 
        return;
@@ -1972,7 +1971,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
        if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
                return -1;
 
-       if (verbose) {
+       if (debug) {
                fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
                        "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
                        rapl_power_units, rapl_energy_units, rapl_time_units);
@@ -2029,7 +2028,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
                print_power_limit_msr(cpu, msr, "DRAM Limit");
        }
        if (do_rapl & RAPL_CORE_POLICY) {
-               if (verbose) {
+               if (debug) {
                        if (get_msr(cpu, MSR_PP0_POLICY, &msr))
                                return -7;
 
@@ -2037,7 +2036,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
                }
        }
        if (do_rapl & RAPL_CORES) {
-               if (verbose) {
+               if (debug) {
 
                        if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
                                return -9;
@@ -2047,7 +2046,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
                }
        }
        if (do_rapl & RAPL_GFX) {
-               if (verbose) {
+               if (debug) {
                        if (get_msr(cpu, MSR_PP1_POLICY, &msr))
                                return -8;
 
@@ -2208,7 +2207,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
 
        target_c_local = (msr >> 16) & 0xFF;
 
-       if (verbose)
+       if (debug)
                fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
                        cpu, msr, target_c_local);
 
@@ -2238,7 +2237,7 @@ void check_cpuid()
        if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
                genuine_intel = 1;
 
-       if (verbose)
+       if (debug)
                fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
                        (char *)&ebx, (char *)&edx, (char *)&ecx);
 
@@ -2249,7 +2248,7 @@ void check_cpuid()
        if (family == 6 || family == 0xf)
                model += ((fms >> 16) & 0xf) << 4;
 
-       if (verbose)
+       if (debug)
                fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
                        max_level, family, model, stepping, family, model, stepping);
 
@@ -2285,7 +2284,7 @@ void check_cpuid()
        do_ptm = eax & (1 << 6);
        has_epb = ecx & (1 << 3);
 
-       if (verbose)
+       if (debug)
                fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n",
                        has_aperf ? "" : "No ",
                        do_dts ? "" : "No ",
@@ -2311,10 +2310,25 @@ void check_cpuid()
 }
 
 
-void usage()
+void help()
 {
-       errx(1, "%s: [-v][-R][-T][-p|-P|-S][-c MSR#][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
-            progname);
+       fprintf(stderr,
+       "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
+       "\n"
+       "Turbostat forks the specified COMMAND and prints statistics\n"
+       "when COMMAND completes.\n"
+       "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
+       "to print statistics, until interrupted.\n"
+       "--debug        run in \"debug\" mode\n"
+       "--interval sec Override default 5-second measurement interval\n"
+       "--help         print this help message\n"
+       "--counter msr  print 32-bit counter at address \"msr\"\n"
+       "--Counter msr  print 64-bit Counter at address \"msr\"\n"
+       "--msr msr      print 32-bit value at address \"msr\"\n"
+       "--MSR msr      print 64-bit Value at address \"msr\"\n"
+       "--version      print version information\n"
+       "\n"
+       "For more help, run \"man turbostat\"\n");
 }
 
 
@@ -2353,7 +2367,7 @@ void topology_probe()
        if (!summary_only && topo.num_cpus > 1)
                show_cpu = 1;
 
-       if (verbose > 1)
+       if (debug > 1)
                fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
 
        cpus = calloc(1, (topo.max_cpu_num  + 1) * sizeof(struct cpu_topology));
@@ -2388,7 +2402,7 @@ void topology_probe()
                int siblings;
 
                if (cpu_is_not_present(i)) {
-                       if (verbose > 1)
+                       if (debug > 1)
                                fprintf(stderr, "cpu%d NOT PRESENT\n", i);
                        continue;
                }
@@ -2403,26 +2417,26 @@ void topology_probe()
                siblings = get_num_ht_siblings(i);
                if (siblings > max_siblings)
                        max_siblings = siblings;
-               if (verbose > 1)
+               if (debug > 1)
                        fprintf(stderr, "cpu %d pkg %d core %d\n",
                                i, cpus[i].physical_package_id, cpus[i].core_id);
        }
        topo.num_cores_per_pkg = max_core_id + 1;
-       if (verbose > 1)
+       if (debug > 1)
                fprintf(stderr, "max_core_id %d, sizing for %d cores per package\n",
                        max_core_id, topo.num_cores_per_pkg);
        if (!summary_only && topo.num_cores_per_pkg > 1)
                show_core = 1;
 
        topo.num_packages = max_package_id + 1;
-       if (verbose > 1)
+       if (debug > 1)
                fprintf(stderr, "max_package_id %d, sizing for %d packages\n",
                        max_package_id, topo.num_packages);
        if (!summary_only && topo.num_packages > 1)
                show_pkg = 1;
 
        topo.num_threads_per_core = max_siblings;
-       if (verbose > 1)
+       if (debug > 1)
                fprintf(stderr, "max_siblings %d\n", max_siblings);
 
        free(cpus);
@@ -2537,21 +2551,21 @@ void turbostat_init()
 
        setup_all_buffers();
 
-       if (verbose)
+       if (debug)
                print_verbose_header();
 
-       if (verbose)
+       if (debug)
                for_all_cpus(print_epb, ODD_COUNTERS);
 
-       if (verbose)
+       if (debug)
                for_all_cpus(print_perf_limit, ODD_COUNTERS);
 
-       if (verbose)
+       if (debug)
                for_all_cpus(print_rapl, ODD_COUNTERS);
 
        for_all_cpus(set_temperature_target, ODD_COUNTERS);
 
-       if (verbose)
+       if (debug)
                for_all_cpus(print_thermal, ODD_COUNTERS);
 }
 
@@ -2616,56 +2630,82 @@ int get_and_dump_counters(void)
        return status;
 }
 
+void print_version() {
+       fprintf(stderr, "turbostat version 4.0 10-Feb, 2015"
+               " - Len Brown <lenb@kernel.org>\n");
+}
+
 void cmdline(int argc, char **argv)
 {
        int opt;
+       int option_index = 0;
+       static struct option long_options[] = {
+               {"Counter",     required_argument,      0, 'C'},
+               {"counter",     required_argument,      0, 'c'},
+               {"Dump",        no_argument,            0, 'D'},
+               {"debug",       no_argument,            0, 'd'},
+               {"interval",    required_argument,      0, 'i'},
+               {"help",        no_argument,            0, 'h'},
+               {"Joules",      no_argument,            0, 'J'},
+               {"MSR",         required_argument,      0, 'M'},
+               {"msr",         required_argument,      0, 'm'},
+               {"Package",     no_argument,            0, 'p'},
+               {"processor",   no_argument,            0, 'p'},
+               {"Summary",     no_argument,            0, 'S'},
+               {"TCC",         required_argument,      0, 'T'},
+               {"version",     no_argument,            0, 'v' },
+               {0,             0,                      0,  0 }
+       };
 
        progname = argv[0];
 
-       while ((opt = getopt(argc, argv, "+pPsSvi:c:C:m:M:RJT:")) != -1) {
+       while ((opt = getopt_long_only(argc, argv, "C:c:Ddhi:JM:m:PpST:v",
+                               long_options, &option_index)) != -1) {
                switch (opt) {
-               case 'p':
-                       show_core_only++;
+               case 'C':
+                       sscanf(optarg, "%x", &extra_delta_offset64);
                        break;
-               case 'P':
-                       show_pkg_only++;
+               case 'c':
+                       sscanf(optarg, "%x", &extra_delta_offset32);
                        break;
-               case 's':
+               case 'D':
                        dump_only++;
                        break;
-               case 'S':
-                       summary_only++;
-                       break;
-               case 'v':
-                       verbose++;
+               case 'd':
+                       debug++;
                        break;
+               case 'h':
+               default:
+                       help();
+                       exit(1);
                case 'i':
                        interval_sec = atoi(optarg);
                        break;
-               case 'c':
-                       sscanf(optarg, "%x", &extra_delta_offset32);
+               case 'J':
+                       rapl_joules++;
                        break;
-               case 'C':
-                       sscanf(optarg, "%x", &extra_delta_offset64);
+               case 'M':
+                       sscanf(optarg, "%x", &extra_msr_offset64);
                        break;
                case 'm':
                        sscanf(optarg, "%x", &extra_msr_offset32);
                        break;
-               case 'M':
-                       sscanf(optarg, "%x", &extra_msr_offset64);
+               case 'P':
+                       show_pkg_only++;
+                       break;
+               case 'p':
+                       show_core_only++;
                        break;
-               case 'R':
-                       rapl_verbose++;
+               case 'S':
+                       summary_only++;
                        break;
                case 'T':
                        tcc_activation_temp_override = atoi(optarg);
                        break;
-               case 'J':
-                       rapl_joules++;
+               case 'v':
+                       print_version();
+                       exit(0);
                        break;
-
-               default:
-                       usage();
                }
        }
 }
@@ -2674,9 +2714,8 @@ int main(int argc, char **argv)
 {
        cmdline(argc, argv);
 
-       if (verbose)
-               fprintf(stderr, "turbostat v3.10 9-Feb, 2015"
-                       " - Len Brown <lenb@kernel.org>\n");
+       if (debug)
+               print_version();
 
        turbostat_init();