diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-06-07 11:06:46 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-07 11:08:59 -0400 |
commit | 743ee1f80434138495bbb95ffb897acf46b51d54 (patch) | |
tree | 90e86af77e39609922d88746aa50c4075f724be7 /tools/perf | |
parent | 2f01190aa62fe9dd0a98205927b9f09fd191c017 (diff) |
perf stat: Continue even on counter creation error
Before:
$ perf stat ~/hackbench 5
error: syscall returned with -1 (No such device)
After:
$ perf stat ~/hackbench 5
Time: 1.640
Performance counter stats for '/home/mingo/hackbench 5':
6524.570382 task-clock-ticks # 3.838 CPU utilization factor
35704 context-switches # 0.005 M/sec
191 CPU-migrations # 0.000 M/sec
8958 page-faults # 0.001 M/sec
<not counted> cycles
<not counted> instructions
<not counted> cache-references
<not counted> cache-misses
Wall-clock time elapsed: 1699.999995 msecs
Also add -v (--verbose) option to allow the printing of failed
counter opens.
Plus dont print 'inf' if wall-time is zero (due to jiffies granularity),
instead skip the printing of the CPU utilization factor.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-stat.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2cbf5a189589..184ff95ef4f5 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -59,6 +59,7 @@ static struct perf_counter_attr default_attrs[MAX_COUNTERS] = { | |||
59 | 59 | ||
60 | static int system_wide = 0; | 60 | static int system_wide = 0; |
61 | static int inherit = 1; | 61 | static int inherit = 1; |
62 | static int verbose = 0; | ||
62 | 63 | ||
63 | static int fd[MAX_NR_CPUS][MAX_COUNTERS]; | 64 | static int fd[MAX_NR_CPUS][MAX_COUNTERS]; |
64 | 65 | ||
@@ -83,7 +84,7 @@ static __u64 event_scaled[MAX_COUNTERS]; | |||
83 | static __u64 runtime_nsecs; | 84 | static __u64 runtime_nsecs; |
84 | static __u64 walltime_nsecs; | 85 | static __u64 walltime_nsecs; |
85 | 86 | ||
86 | static void create_perfstat_counter(int counter) | 87 | static void create_perf_stat_counter(int counter) |
87 | { | 88 | { |
88 | struct perf_counter_attr *attr = attrs + counter; | 89 | struct perf_counter_attr *attr = attrs + counter; |
89 | 90 | ||
@@ -95,10 +96,8 @@ static void create_perfstat_counter(int counter) | |||
95 | int cpu; | 96 | int cpu; |
96 | for (cpu = 0; cpu < nr_cpus; cpu ++) { | 97 | for (cpu = 0; cpu < nr_cpus; cpu ++) { |
97 | fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0); | 98 | fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0); |
98 | if (fd[cpu][counter] < 0) { | 99 | if (fd[cpu][counter] < 0 && verbose) { |
99 | printf("perfstat error: syscall returned with %d (%s)\n", | 100 | printf("Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n", counter, fd[cpu][counter], strerror(errno)); |
100 | fd[cpu][counter], strerror(errno)); | ||
101 | exit(-1); | ||
102 | } | 101 | } |
103 | } | 102 | } |
104 | } else { | 103 | } else { |
@@ -106,10 +105,8 @@ static void create_perfstat_counter(int counter) | |||
106 | attr->disabled = 1; | 105 | attr->disabled = 1; |
107 | 106 | ||
108 | fd[0][counter] = sys_perf_counter_open(attr, 0, -1, -1, 0); | 107 | fd[0][counter] = sys_perf_counter_open(attr, 0, -1, -1, 0); |
109 | if (fd[0][counter] < 0) { | 108 | if (fd[0][counter] < 0 && verbose) { |
110 | printf("perfstat error: syscall returned with %d (%s)\n", | 109 | printf("Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n", counter, fd[0][counter], strerror(errno)); |
111 | fd[0][counter], strerror(errno)); | ||
112 | exit(-1); | ||
113 | } | 110 | } |
114 | } | 111 | } |
115 | } | 112 | } |
@@ -147,6 +144,9 @@ static void read_counter(int counter) | |||
147 | 144 | ||
148 | nv = scale ? 3 : 1; | 145 | nv = scale ? 3 : 1; |
149 | for (cpu = 0; cpu < nr_cpus; cpu ++) { | 146 | for (cpu = 0; cpu < nr_cpus; cpu ++) { |
147 | if (fd[cpu][counter] < 0) | ||
148 | continue; | ||
149 | |||
150 | res = read(fd[cpu][counter], single_count, nv * sizeof(__u64)); | 150 | res = read(fd[cpu][counter], single_count, nv * sizeof(__u64)); |
151 | assert(res == nv * sizeof(__u64)); | 151 | assert(res == nv * sizeof(__u64)); |
152 | 152 | ||
@@ -204,8 +204,9 @@ static void print_counter(int counter) | |||
204 | if (attrs[counter].type == PERF_TYPE_SOFTWARE && | 204 | if (attrs[counter].type == PERF_TYPE_SOFTWARE && |
205 | attrs[counter].config == PERF_COUNT_TASK_CLOCK) { | 205 | attrs[counter].config == PERF_COUNT_TASK_CLOCK) { |
206 | 206 | ||
207 | fprintf(stderr, " # %11.3f CPU utilization factor", | 207 | if (walltime_nsecs) |
208 | (double)count[0] / (double)walltime_nsecs); | 208 | fprintf(stderr, " # %11.3f CPU utilization factor", |
209 | (double)count[0] / (double)walltime_nsecs); | ||
209 | } | 210 | } |
210 | } else { | 211 | } else { |
211 | fprintf(stderr, " %14Ld %-20s", | 212 | fprintf(stderr, " %14Ld %-20s", |
@@ -220,7 +221,7 @@ static void print_counter(int counter) | |||
220 | fprintf(stderr, "\n"); | 221 | fprintf(stderr, "\n"); |
221 | } | 222 | } |
222 | 223 | ||
223 | static int do_perfstat(int argc, const char **argv) | 224 | static int do_perf_stat(int argc, const char **argv) |
224 | { | 225 | { |
225 | unsigned long long t0, t1; | 226 | unsigned long long t0, t1; |
226 | int counter; | 227 | int counter; |
@@ -232,7 +233,7 @@ static int do_perfstat(int argc, const char **argv) | |||
232 | nr_cpus = 1; | 233 | nr_cpus = 1; |
233 | 234 | ||
234 | for (counter = 0; counter < nr_counters; counter++) | 235 | for (counter = 0; counter < nr_counters; counter++) |
235 | create_perfstat_counter(counter); | 236 | create_perf_stat_counter(counter); |
236 | 237 | ||
237 | /* | 238 | /* |
238 | * Enable counters and exec the command: | 239 | * Enable counters and exec the command: |
@@ -305,6 +306,8 @@ static const struct option options[] = { | |||
305 | "system-wide collection from all CPUs"), | 306 | "system-wide collection from all CPUs"), |
306 | OPT_BOOLEAN('S', "scale", &scale, | 307 | OPT_BOOLEAN('S', "scale", &scale, |
307 | "scale/normalize counters"), | 308 | "scale/normalize counters"), |
309 | OPT_BOOLEAN('v', "verbose", &verbose, | ||
310 | "be more verbose (show counter open errors, etc)"), | ||
308 | OPT_END() | 311 | OPT_END() |
309 | }; | 312 | }; |
310 | 313 | ||
@@ -335,5 +338,5 @@ int cmd_stat(int argc, const char **argv, const char *prefix) | |||
335 | signal(SIGALRM, skip_signal); | 338 | signal(SIGALRM, skip_signal); |
336 | signal(SIGABRT, skip_signal); | 339 | signal(SIGABRT, skip_signal); |
337 | 340 | ||
338 | return do_perfstat(argc, argv); | 341 | return do_perf_stat(argc, argv); |
339 | } | 342 | } |