diff options
author | Len Brown <len.brown@intel.com> | 2015-01-23 01:33:58 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2015-02-09 18:28:18 -0500 |
commit | a729617c58529be0be8faa22c5d45748bb0f12e5 (patch) | |
tree | f50255767f07a7bc8ccbc0abcd3e097b7ea7cef8 /tools | |
parent | d7899447535929b3672442b7b42a09ae4e48fa91 (diff) |
tools/power turbostat: relax dependency on APERF_MSR
While turbostat is significantly less useful on systems
with no APERF_MSR, it seems more friendly
to run on such systems and report what we can,
rather than refusing to run.
Update man page to reflect recent changes.
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.8 | 66 | ||||
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 47 |
2 files changed, 68 insertions, 45 deletions
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 56bfb523c5bb..9b950699e63d 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 | |||
@@ -12,16 +12,16 @@ turbostat \- Report processor frequency and idle statistics | |||
12 | .RB [ "\-i interval_sec" ] | 12 | .RB [ "\-i interval_sec" ] |
13 | .SH DESCRIPTION | 13 | .SH DESCRIPTION |
14 | \fBturbostat \fP reports processor topology, frequency, | 14 | \fBturbostat \fP reports processor topology, frequency, |
15 | idle power-state statistics, temperature and power on modern X86 processors. | 15 | idle power-state statistics, temperature and power on X86 processors. |
16 | Either \fBcommand\fP is forked and statistics are printed | 16 | There are two ways to invoke turbostat. |
17 | upon its completion, or statistics are printed periodically. | 17 | The first method is to supply a |
18 | 18 | \fBcommand\fP, which is forked and statistics are printed | |
19 | \fBturbostat \fP | 19 | upon its completion. |
20 | must be run on root, and | 20 | The second method is to omit the command, |
21 | minimally requires that the processor | 21 | and turbodstat will print statistics every 5 seconds. |
22 | supports an "invariant" TSC, plus the APERF and MPERF MSRs. | 22 | The 5-second interval can changed using the -i option. |
23 | Additional information is reported depending on hardware counter support. | 23 | |
24 | 24 | Some information is not availalbe on older processors. | |
25 | .SS Options | 25 | .SS Options |
26 | The \fB-p\fP option limits output to the 1st thread in 1st core of each package. | 26 | The \fB-p\fP option limits output to the 1st thread in 1st core of each package. |
27 | .PP | 27 | .PP |
@@ -130,12 +130,13 @@ cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1) | |||
130 | ... | 130 | ... |
131 | .fi | 131 | .fi |
132 | The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency | 132 | The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency |
133 | available at the minimum package voltage. The \fBTSC frequency\fP is the nominal | 133 | available at the minimum package voltage. The \fBTSC frequency\fP is the base |
134 | maximum frequency of the processor if turbo-mode were not available. This frequency | 134 | frequency of the processor -- this should match the brand string |
135 | in /proc/cpuinfo. This base frequency | ||
135 | should be sustainable on all CPUs indefinitely, given nominal power and cooling. | 136 | should be sustainable on all CPUs indefinitely, given nominal power and cooling. |
136 | The remaining rows show what maximum turbo frequency is possible | 137 | The remaining rows show what maximum turbo frequency is possible |
137 | depending on the number of idle cores. Note that this information is | 138 | depending on the number of idle cores. Note that not all information is |
138 | not available on all processors. | 139 | available on all processors. |
139 | .SH FORK EXAMPLE | 140 | .SH FORK EXAMPLE |
140 | If turbostat is invoked with a command, it will fork that command | 141 | If turbostat is invoked with a command, it will fork that command |
141 | and output the statistics gathered when the command exits. | 142 | and output the statistics gathered when the command exits. |
@@ -176,6 +177,11 @@ not including any non-busy idle time. | |||
176 | 177 | ||
177 | .B "turbostat " | 178 | .B "turbostat " |
178 | must be run as root. | 179 | must be run as root. |
180 | Alternatively, non-root users can be enabled to run turbostat this way: | ||
181 | |||
182 | # setcap cap_sys_rawio=ep ./turbostat | ||
183 | |||
184 | # chmod +r /dev/cpu/*/msr | ||
179 | 185 | ||
180 | .B "turbostat " | 186 | .B "turbostat " |
181 | reads hardware counters, but doesn't write them. | 187 | reads hardware counters, but doesn't write them. |
@@ -184,15 +190,33 @@ multiple invocations of itself. | |||
184 | 190 | ||
185 | \fBturbostat \fP | 191 | \fBturbostat \fP |
186 | may work poorly on Linux-2.6.20 through 2.6.29, | 192 | may work poorly on Linux-2.6.20 through 2.6.29, |
187 | as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF | 193 | as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF MSRs |
188 | in those kernels. | 194 | in those kernels. |
189 | 195 | ||
190 | If the TSC column does not make sense, then | 196 | AVG_MHz = APERF_delta/measurement_interval. This is the actual |
191 | the other numbers will also make no sense. | 197 | number of elapsed cycles divided by the entire sample interval -- |
192 | Turbostat is lightweight, and its data collection is not atomic. | 198 | including idle time. Note that this calculation is resiliant |
193 | These issues are usually caused by an extremely short measurement | 199 | to systems lacking a non-stop TSC. |
194 | interval (much less than 1 second), or system activity that prevents | 200 | |
195 | turbostat from being able to run on all CPUS to quickly collect data. | 201 | TSC_MHz = TSC_delta/measurement_interval. |
202 | On a system with an invariant TSC, this value will be constant | ||
203 | and will closely match the base frequency value shown | ||
204 | in the brand string in /proc/cpuinfo. On a system where | ||
205 | the TSC stops in idle, TSC_MHz will drop | ||
206 | below the processor's base frequency. | ||
207 | |||
208 | %Busy = MPERF_delta/TSC_delta | ||
209 | |||
210 | Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval | ||
211 | |||
212 | Note that these calculations depend on TSC_delta, so they | ||
213 | are not reliable during intervals when TSC_MHz is not running at the base frequency. | ||
214 | |||
215 | Turbostat data collection is not atomic. | ||
216 | Extremely short measurement intervals (much less than 1 second), | ||
217 | or system activity that prevents turbostat from being able | ||
218 | to run on all CPUS to quickly collect data, will result in | ||
219 | inconsistent results. | ||
196 | 220 | ||
197 | The APERF, MPERF MSRs are defined to count non-halted cycles. | 221 | The APERF, MPERF MSRs are defined to count non-halted cycles. |
198 | Although it is not guaranteed by the architecture, turbostat assumes | 222 | Although it is not guaranteed by the architecture, turbostat assumes |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index b654b641d4c3..a02c02f25e88 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -673,24 +673,26 @@ delta_thread(struct thread_data *new, struct thread_data *old, | |||
673 | 673 | ||
674 | old->c1 = new->c1 - old->c1; | 674 | old->c1 = new->c1 - old->c1; |
675 | 675 | ||
676 | if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { | 676 | if (has_aperf) { |
677 | old->aperf = new->aperf - old->aperf; | 677 | if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { |
678 | old->mperf = new->mperf - old->mperf; | 678 | old->aperf = new->aperf - old->aperf; |
679 | } else { | 679 | old->mperf = new->mperf - old->mperf; |
680 | } else { | ||
680 | 681 | ||
681 | if (!aperf_mperf_unstable) { | 682 | if (!aperf_mperf_unstable) { |
682 | fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname); | 683 | fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname); |
683 | fprintf(stderr, "* Frequency results do not cover entire interval *\n"); | 684 | fprintf(stderr, "* Frequency results do not cover entire interval *\n"); |
684 | fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n"); | 685 | fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n"); |
685 | 686 | ||
686 | aperf_mperf_unstable = 1; | 687 | aperf_mperf_unstable = 1; |
688 | } | ||
689 | /* | ||
690 | * mperf delta is likely a huge "positive" number | ||
691 | * can not use it for calculating c0 time | ||
692 | */ | ||
693 | skip_c0 = 1; | ||
694 | skip_c1 = 1; | ||
687 | } | 695 | } |
688 | /* | ||
689 | * mperf delta is likely a huge "positive" number | ||
690 | * can not use it for calculating c0 time | ||
691 | */ | ||
692 | skip_c0 = 1; | ||
693 | skip_c1 = 1; | ||
694 | } | 696 | } |
695 | 697 | ||
696 | 698 | ||
@@ -2244,14 +2246,11 @@ void check_cpuid() | |||
2244 | has_epb = ecx & (1 << 3); | 2246 | has_epb = ecx & (1 << 3); |
2245 | 2247 | ||
2246 | if (verbose) | 2248 | if (verbose) |
2247 | fprintf(stderr, "CPUID(6): %s%s%s%s\n", | 2249 | fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n", |
2248 | has_aperf ? "APERF" : "No APERF!", | 2250 | has_aperf ? "" : "No ", |
2249 | do_dts ? ", DTS" : "", | 2251 | do_dts ? "" : "No ", |
2250 | do_ptm ? ", PTM": "", | 2252 | do_ptm ? "" : "No ", |
2251 | has_epb ? ", EPB": ""); | 2253 | has_epb ? "" : "No "); |
2252 | |||
2253 | if (!has_aperf) | ||
2254 | errx(-1, "No APERF"); | ||
2255 | 2254 | ||
2256 | do_nhm_platform_info = do_nhm_cstates = do_smi = has_nhm_msrs(family, model); | 2255 | do_nhm_platform_info = do_nhm_cstates = do_smi = has_nhm_msrs(family, model); |
2257 | do_snb_cstates = has_snb_msrs(family, model); | 2256 | do_snb_cstates = has_snb_msrs(family, model); |
@@ -2632,7 +2631,7 @@ int main(int argc, char **argv) | |||
2632 | cmdline(argc, argv); | 2631 | cmdline(argc, argv); |
2633 | 2632 | ||
2634 | if (verbose) | 2633 | if (verbose) |
2635 | fprintf(stderr, "turbostat v3.8 14-Aug 2014" | 2634 | fprintf(stderr, "turbostat v3.9 23-Jan, 2015" |
2636 | " - Len Brown <lenb@kernel.org>\n"); | 2635 | " - Len Brown <lenb@kernel.org>\n"); |
2637 | 2636 | ||
2638 | turbostat_init(); | 2637 | turbostat_init(); |