perf tools: Fixup exit path when not able to open events

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 1dfd7b49
...@@ -275,11 +275,10 @@ static void open_counters(struct perf_evlist *evlist) ...@@ -275,11 +275,10 @@ static void open_counters(struct perf_evlist *evlist)
!no_inherit) < 0) { !no_inherit) < 0) {
int err = errno; int err = errno;
if (err == EPERM || err == EACCES) if (err == EPERM || err == EACCES) {
die("Permission error - are you root?\n" ui__warning_paranoid();
"\t Consider tweaking" exit(EXIT_FAILURE);
" /proc/sys/kernel/perf_event_paranoid.\n"); } else if (err == ENODEV && cpu_list) {
else if (err == ENODEV && cpu_list) {
die("No such device - did you specify" die("No such device - did you specify"
" an out-of-range profile CPU?\n"); " an out-of-range profile CPU?\n");
} else if (err == EINVAL && sample_id_all_avail) { } else if (err == EINVAL && sample_id_all_avail) {
......
...@@ -850,10 +850,10 @@ static void start_counters(struct perf_evlist *evlist) ...@@ -850,10 +850,10 @@ static void start_counters(struct perf_evlist *evlist)
top.evlist->threads, group, inherit) < 0) { top.evlist->threads, group, inherit) < 0) {
int err = errno; int err = errno;
if (err == EPERM || err == EACCES) if (err == EPERM || err == EACCES) {
die("Permission error - are you root?\n" ui__warning_paranoid();
"\t Consider tweaking" goto out_err;
" /proc/sys/kernel/perf_event_paranoid.\n"); }
/* /*
* If it's cycles then fall back to hrtimer * If it's cycles then fall back to hrtimer
* based cpu-clock-tick sw counter, which * based cpu-clock-tick sw counter, which
...@@ -861,25 +861,35 @@ static void start_counters(struct perf_evlist *evlist) ...@@ -861,25 +861,35 @@ static void start_counters(struct perf_evlist *evlist)
*/ */
if (attr->type == PERF_TYPE_HARDWARE && if (attr->type == PERF_TYPE_HARDWARE &&
attr->config == PERF_COUNT_HW_CPU_CYCLES) { attr->config == PERF_COUNT_HW_CPU_CYCLES) {
if (verbose) 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->type = PERF_TYPE_SOFTWARE;
attr->config = PERF_COUNT_SW_CPU_CLOCK; attr->config = PERF_COUNT_SW_CPU_CLOCK;
goto try_again; goto try_again;
} }
printf("\n");
error("sys_perf_event_open() syscall returned with %d " ui__warning("The sys_perf_event_open() syscall "
"(%s). /bin/dmesg may provide additional information.\n", "returned with %d (%s). /bin/dmesg "
err, strerror(err)); "may provide additional information.\n"
die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); "No CONFIG_PERF_EVENTS=y kernel support "
exit(-1); "configured?\n", err, strerror(err));
goto out_err;
} }
} }
if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) {
die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 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) static int __cmd_top(void)
......
...@@ -57,6 +57,16 @@ void ui__warning(const char *format, ...) ...@@ -57,6 +57,16 @@ void ui__warning(const char *format, ...)
} }
#endif #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) void trace_event(union perf_event *event)
{ {
unsigned char *raw_event = (void *)event; unsigned char *raw_event = (void *)event;
......
...@@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap); ...@@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap);
#endif #endif
void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
void ui__warning_paranoid(void);
#endif /* __PERF_DEBUG_H */ #endif /* __PERF_DEBUG_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment