From 3da297a60f7e8840f79f7d0b343af078890939ea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 7 Jun 2009 17:39:02 +0200 Subject: 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 Cc: Mike Galbraith Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: Signed-off-by: Ingo Molnar --- tools/perf/builtin-record.c | 25 +++++++++++++++++++++++-- tools/perf/builtin-top.c | 14 ++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) (limited to 'tools') 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; static int inherit = 1; static int force = 0; static int append_file = 0; +static int verbose = 0; static long samples; static struct timeval last_read; @@ -349,17 +350,35 @@ static void create_counter(int counter, int cpu, pid_t pid) track = 0; /* only the first counter needs these */ +try_again: fd[nr_cpu][counter] = sys_perf_counter_open(attr, pid, cpu, group_fd, 0); if (fd[nr_cpu][counter] < 0) { int err = errno; - error("syscall returned with %d (%s)\n", + if (verbose) + error("sys_perf_counter_open() syscall returned with %d (%s)\n", fd[nr_cpu][counter], strerror(err)); if (err == EPERM) - printf("Are you root?\n"); + die("Permission error - are you root?\n"); + + /* + * If it's cycles then fall back to hrtimer + * based cpu-clock-tick sw counter, which + * is always available even if no PMU support: + */ + if (attr->type == PERF_TYPE_HARDWARE + && attr->config == PERF_COUNT_CPU_CYCLES) { + + if (verbose) + warning(" ... trying to fall back to cpu-clock-ticks\n"); + attr->type = PERF_TYPE_SOFTWARE; + attr->config = PERF_COUNT_CPU_CLOCK; + goto try_again; + } exit(-1); } + assert(fd[nr_cpu][counter] >= 0); fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK); @@ -519,6 +538,8 @@ static const struct option options[] = { "profile at this frequency"), OPT_INTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"), + OPT_BOOLEAN('v', "verbose", &verbose, + "be more verbose (show counter open errors, etc)"), OPT_END() }; 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; static unsigned int page_size; static unsigned int mmap_pages = 16; static int freq = 0; +static int verbose = 0; static char *sym_filter; static unsigned long filter_start; @@ -550,11 +551,12 @@ try_again: if (fd[i][counter] < 0) { int err = errno; - error("sys_perf_counter_open() syscall returned with %d (%s)\n", - fd[i][counter], strerror(err)); + if (verbose) + error("sys_perf_counter_open() syscall returned with %d (%s)\n", + fd[i][counter], strerror(err)); if (err == EPERM) - die(" No permission - are you root?\n"); + die("No permission - are you root?\n"); /* * If it's cycles then fall back to hrtimer * based cpu-clock-tick sw counter, which @@ -563,7 +565,9 @@ try_again: if (attr->type == PERF_TYPE_HARDWARE && attr->config == PERF_COUNT_CPU_CYCLES) { - warning(" ... trying to fall back to cpu-clock-ticks\n"); + if (verbose) + warning(" ... trying to fall back to cpu-clock-ticks\n"); + attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_CPU_CLOCK; goto try_again; @@ -673,6 +677,8 @@ static const struct option options[] = { "profile at this frequency"), OPT_INTEGER('E', "entries", &print_entries, "display this many functions"), + OPT_BOOLEAN('v', "verbose", &verbose, + "be more verbose (show counter open errors, etc)"), OPT_END() }; -- cgit v1.2.3