aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-07 11:39:02 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-07 11:39:02 -0400
commit3da297a60f7e8840f79f7d0b343af078890939ea (patch)
treec3b5b39be914caa30f1eb820afbdc228d531e25e /tools/perf/builtin-record.c
parent716c69fecacd42f2a304a97158e04af2786a3f65 (diff)
perf record: Fall back to cpu-clock-ticks if no PMU
On architectures/CPUs without PMU support but with perfcounters enabled 'perf record' currently fails because it cannot create a cycle based hw-perfcounter. Fall back to the cpu-clock-tick sw-perfcounter in this case, which is hrtimer based and will always work (as long as perfcounters are enabled). 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/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index aeab9c4b15e..87866294a0e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -37,6 +37,7 @@ static pid_t target_pid = -1;
37static int inherit = 1; 37static int inherit = 1;
38static int force = 0; 38static int force = 0;
39static int append_file = 0; 39static int append_file = 0;
40static int verbose = 0;
40 41
41static long samples; 42static long samples;
42static struct timeval last_read; 43static struct timeval last_read;
@@ -349,17 +350,35 @@ static void create_counter(int counter, int cpu, pid_t pid)
349 350
350 track = 0; /* only the first counter needs these */ 351 track = 0; /* only the first counter needs these */
351 352
353try_again:
352 fd[nr_cpu][counter] = sys_perf_counter_open(attr, pid, cpu, group_fd, 0); 354 fd[nr_cpu][counter] = sys_perf_counter_open(attr, pid, cpu, group_fd, 0);
353 355
354 if (fd[nr_cpu][counter] < 0) { 356 if (fd[nr_cpu][counter] < 0) {
355 int err = errno; 357 int err = errno;
356 358
357 error("syscall returned with %d (%s)\n", 359 if (verbose)
360 error("sys_perf_counter_open() syscall returned with %d (%s)\n",
358 fd[nr_cpu][counter], strerror(err)); 361 fd[nr_cpu][counter], strerror(err));
359 if (err == EPERM) 362 if (err == EPERM)
360 printf("Are you root?\n"); 363 die("Permission error - are you root?\n");
364
365 /*
366 * If it's cycles then fall back to hrtimer
367 * based cpu-clock-tick sw counter, which
368 * is always available even if no PMU support:
369 */
370 if (attr->type == PERF_TYPE_HARDWARE
371 && attr->config == PERF_COUNT_CPU_CYCLES) {
372
373 if (verbose)
374 warning(" ... trying to fall back to cpu-clock-ticks\n");
375 attr->type = PERF_TYPE_SOFTWARE;
376 attr->config = PERF_COUNT_CPU_CLOCK;
377 goto try_again;
378 }
361 exit(-1); 379 exit(-1);
362 } 380 }
381
363 assert(fd[nr_cpu][counter] >= 0); 382 assert(fd[nr_cpu][counter] >= 0);
364 fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK); 383 fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK);
365 384
@@ -519,6 +538,8 @@ static const struct option options[] = {
519 "profile at this frequency"), 538 "profile at this frequency"),
520 OPT_INTEGER('m', "mmap-pages", &mmap_pages, 539 OPT_INTEGER('m', "mmap-pages", &mmap_pages,
521 "number of mmap data pages"), 540 "number of mmap data pages"),
541 OPT_BOOLEAN('v', "verbose", &verbose,
542 "be more verbose (show counter open errors, etc)"),
522 OPT_END() 543 OPT_END()
523}; 544};
524 545