diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-06-07 11:39:02 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-06-07 11:39:02 -0400 |
| commit | 3da297a60f7e8840f79f7d0b343af078890939ea (patch) | |
| tree | c3b5b39be914caa30f1eb820afbdc228d531e25e /tools | |
| parent | 716c69fecacd42f2a304a97158e04af2786a3f65 (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')
| -rw-r--r-- | tools/perf/builtin-record.c | 25 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 14 |
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; | |||
| 37 | static int inherit = 1; | 37 | static int inherit = 1; |
| 38 | static int force = 0; | 38 | static int force = 0; |
| 39 | static int append_file = 0; | 39 | static int append_file = 0; |
| 40 | static int verbose = 0; | ||
| 40 | 41 | ||
| 41 | static long samples; | 42 | static long samples; |
| 42 | static struct timeval last_read; | 43 | static 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 | ||
| 353 | try_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; | |||
| 65 | static unsigned int page_size; | 65 | static unsigned int page_size; |
| 66 | static unsigned int mmap_pages = 16; | 66 | static unsigned int mmap_pages = 16; |
| 67 | static int freq = 0; | 67 | static int freq = 0; |
| 68 | static int verbose = 0; | ||
| 68 | 69 | ||
| 69 | static char *sym_filter; | 70 | static char *sym_filter; |
| 70 | static unsigned long filter_start; | 71 | static 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 | ||
