summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-07 17:39:02 +0200
committerIngo Molnar <mingo@elte.hu>2009-06-07 17:39:02 +0200
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;
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()
};