diff options
author | Paul Mackerras <paulus@samba.org> | 2010-03-10 04:36:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-03-11 07:36:53 -0500 |
commit | a12b51c478899fe0b7e874a559b05ba35f1128ee (patch) | |
tree | 25b9911c1932c13fd8b468aa18eb17982ba31b59 /tools/perf/builtin-top.c | |
parent | 220b140b52ab6cc133f674a7ffec8fa792054f25 (diff) |
perf tools: Fix sparse CPU numbering related bugs
At present, the perf subcommands that do system-wide monitoring
(perf stat, perf record and perf top) don't work properly unless
the online cpus are numbered 0, 1, ..., N-1. These tools ask
for the number of online cpus with sysconf(_SC_NPROCESSORS_ONLN)
and then try to create events for cpus 0, 1, ..., N-1.
This creates problems for systems where the online cpus are
numbered sparsely. For example, a POWER6 system in
single-threaded mode (i.e. only running 1 hardware thread per
core) will have only even-numbered cpus online.
This fixes the problem by reading the /sys/devices/system/cpu/online
file to find out which cpus are online. The code that does that is in
tools/perf/util/cpumap.[ch], and consists of a read_cpu_map()
function that sets up a cpumap[] array and returns the number of
online cpus. If /sys/devices/system/cpu/online can't be read or
can't be parsed successfully, it falls back to using sysconf to
ask how many cpus are online and sets up an identity map in cpumap[].
The perf record, perf stat and perf top code then calls
read_cpu_map() in the system-wide monitoring case (instead of
sysconf) and uses cpumap[] to get the cpu numbers to pass to
perf_event_open.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
LKML-Reference: <20100310093609.GA3959@brick.ozlabs.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 31f2e597800c..0b719e3dde05 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/rbtree.h> | 28 | #include <linux/rbtree.h> |
29 | #include "util/parse-options.h" | 29 | #include "util/parse-options.h" |
30 | #include "util/parse-events.h" | 30 | #include "util/parse-events.h" |
31 | #include "util/cpumap.h" | ||
31 | 32 | ||
32 | #include "util/debug.h" | 33 | #include "util/debug.h" |
33 | 34 | ||
@@ -1123,7 +1124,7 @@ static void start_counter(int i, int counter) | |||
1123 | 1124 | ||
1124 | cpu = profile_cpu; | 1125 | cpu = profile_cpu; |
1125 | if (target_pid == -1 && profile_cpu == -1) | 1126 | if (target_pid == -1 && profile_cpu == -1) |
1126 | cpu = i; | 1127 | cpu = cpumap[i]; |
1127 | 1128 | ||
1128 | attr = attrs + counter; | 1129 | attr = attrs + counter; |
1129 | 1130 | ||
@@ -1347,12 +1348,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1347 | attrs[counter].sample_period = default_interval; | 1348 | attrs[counter].sample_period = default_interval; |
1348 | } | 1349 | } |
1349 | 1350 | ||
1350 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); | ||
1351 | assert(nr_cpus <= MAX_NR_CPUS); | ||
1352 | assert(nr_cpus >= 0); | ||
1353 | |||
1354 | if (target_pid != -1 || profile_cpu != -1) | 1351 | if (target_pid != -1 || profile_cpu != -1) |
1355 | nr_cpus = 1; | 1352 | nr_cpus = 1; |
1353 | else | ||
1354 | nr_cpus = read_cpu_map(); | ||
1356 | 1355 | ||
1357 | get_term_dimensions(&winsize); | 1356 | get_term_dimensions(&winsize); |
1358 | if (print_entries == 0) { | 1357 | if (print_entries == 0) { |