aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--tools/perf/builtin-record.c25
-rw-r--r--tools/perf/builtin-top.c14
2 files changed, 33 insertions, 6 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index aeab9c4b15e4..87866294a0e6 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
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 6da30a140e86..1f8c97d5c32e 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -65,6 +65,7 @@ static int group = 0;
65static unsigned int page_size; 65static unsigned int page_size;
66static unsigned int mmap_pages = 16; 66static unsigned int mmap_pages = 16;
67static int freq = 0; 67static int freq = 0;
68static int verbose = 0;
68 69
69static char *sym_filter; 70static char *sym_filter;
70static unsigned long filter_start; 71static unsigned long filter_start;
@@ -550,11 +551,12 @@ try_again:
550 if (fd[i][counter] < 0) { 551 if (fd[i][counter] < 0) {
551 int err = errno; 552 int err = errno;
552 553
553 error("sys_perf_counter_open() syscall returned with %d (%s)\n", 554 if (verbose)
554 fd[i][counter], strerror(err)); 555 error("sys_perf_counter_open() syscall returned with %d (%s)\n",
556 fd[i][counter], strerror(err));
555 557
556 if (err == EPERM) 558 if (err == EPERM)
557 die(" No permission - are you root?\n"); 559 die("No permission - are you root?\n");
558 /* 560 /*
559 * If it's cycles then fall back to hrtimer 561 * If it's cycles then fall back to hrtimer
560 * based cpu-clock-tick sw counter, which 562 * based cpu-clock-tick sw counter, which
@@ -563,7 +565,9 @@ try_again:
563 if (attr->type == PERF_TYPE_HARDWARE 565 if (attr->type == PERF_TYPE_HARDWARE
564 && attr->config == PERF_COUNT_CPU_CYCLES) { 566 && attr->config == PERF_COUNT_CPU_CYCLES) {
565 567
566 warning(" ... trying to fall back to cpu-clock-ticks\n"); 568 if (verbose)
569 warning(" ... trying to fall back to cpu-clock-ticks\n");
570
567 attr->type = PERF_TYPE_SOFTWARE; 571 attr->type = PERF_TYPE_SOFTWARE;
568 attr->config = PERF_COUNT_CPU_CLOCK; 572 attr->config = PERF_COUNT_CPU_CLOCK;
569 goto try_again; 573 goto try_again;
@@ -673,6 +677,8 @@ static const struct option options[] = {
673 "profile at this frequency"), 677 "profile at this frequency"),
674 OPT_INTEGER('E', "entries", &print_entries, 678 OPT_INTEGER('E', "entries", &print_entries,
675 "display this many functions"), 679 "display this many functions"),
680 OPT_BOOLEAN('v', "verbose", &verbose,
681 "be more verbose (show counter open errors, etc)"),
676 OPT_END() 682 OPT_END()
677}; 683};
678 684