perf tools: Fixup exit path when not able to open events
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 28 Mar 2011 12:50:11 +0000 (09:50 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 29 Mar 2011 16:40:27 +0000 (13:40 -0300)
We have to deal with the TUI mode in perf top, so that we don't end up
with a garbled screen when, say, a non root user on a machine with a
paranoid setting (the default) tries to use 'perf top'.

Introduce a ui__warning_paranoid() routine shared by top and record that
tells the user the valid values for /proc/sys/kernel/perf_event_paranoid.

Cc: David Ahern <daahern@cisco.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-record.c
tools/perf/builtin-top.c
tools/perf/util/debug.c
tools/perf/util/debug.h

index 6febcc1..623695e 100644 (file)
@@ -275,11 +275,10 @@ try_again:
                                     !no_inherit) < 0) {
                        int err = errno;
 
-                       if (err == EPERM || err == EACCES)
-                               die("Permission error - are you root?\n"
-                                       "\t Consider tweaking"
-                                       " /proc/sys/kernel/perf_event_paranoid.\n");
-                       else if (err ==  ENODEV && cpu_list) {
+                       if (err == EPERM || err == EACCES) {
+                               ui__warning_paranoid();
+                               exit(EXIT_FAILURE);
+                       } else if (err ==  ENODEV && cpu_list) {
                                die("No such device - did you specify"
                                        " an out-of-range profile CPU?\n");
                        } else if (err == EINVAL && sample_id_all_avail) {
index 676b4fb..935fc4f 100644 (file)
@@ -850,10 +850,10 @@ try_again:
                                     top.evlist->threads, group, inherit) < 0) {
                        int err = errno;
 
-                       if (err == EPERM || err == EACCES)
-                               die("Permission error - are you root?\n"
-                                       "\t Consider tweaking"
-                                       " /proc/sys/kernel/perf_event_paranoid.\n");
+                       if (err == EPERM || err == EACCES) {
+                               ui__warning_paranoid();
+                               goto out_err;
+                       }
                        /*
                         * If it's cycles then fall back to hrtimer
                         * based cpu-clock-tick sw counter, which
@@ -861,25 +861,35 @@ try_again:
                         */
                        if (attr->type == PERF_TYPE_HARDWARE &&
                            attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
                                if (verbose)
-                                       warning(" ... trying to fall back to cpu-clock-ticks\n");
+                                       ui__warning("Cycles event not supported,\n"
+                                                   "trying to fall back to cpu-clock-ticks\n");
 
                                attr->type = PERF_TYPE_SOFTWARE;
                                attr->config = PERF_COUNT_SW_CPU_CLOCK;
                                goto try_again;
                        }
-                       printf("\n");
-                       error("sys_perf_event_open() syscall returned with %d "
-                             "(%s).  /bin/dmesg may provide additional information.\n",
-                             err, strerror(err));
-                       die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
-                       exit(-1);
+
+                       ui__warning("The sys_perf_event_open() syscall "
+                                   "returned with %d (%s).  /bin/dmesg "
+                                   "may provide additional information.\n"
+                                   "No CONFIG_PERF_EVENTS=y kernel support "
+                                   "configured?\n", err, strerror(err));
+                       goto out_err;
                }
        }
 
-       if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
-               die("failed to mmap with %d (%s)\n", errno, strerror(errno));
+       if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) {
+               ui__warning("Failed to mmap with %d (%s)\n",
+                           errno, strerror(errno));
+               goto out_err;
+       }
+
+       return;
+
+out_err:
+       exit_browser(0);
+       exit(0);
 }
 
 static int __cmd_top(void)
index d4536a9..155749d 100644 (file)
@@ -57,6 +57,16 @@ void ui__warning(const char *format, ...)
 }
 #endif
 
+void ui__warning_paranoid(void)
+{
+       ui__warning("Permission error - are you root?\n"
+                   "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
+                   " -1 - Not paranoid at all\n"
+                   "  0 - Disallow raw tracepoint access for unpriv\n"
+                   "  1 - Disallow cpu events for unpriv\n"
+                   "  2 - Disallow kernel profiling for unpriv\n");
+}
+
 void trace_event(union perf_event *event)
 {
        unsigned char *raw_event = (void *)event;
index 93516cf..fd53db4 100644 (file)
@@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap);
 #endif
 
 void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
+void ui__warning_paranoid(void);
 
 #endif /* __PERF_DEBUG_H */