aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-12-13 13:10:58 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-01-24 14:40:09 -0500
commit56e52e85366717481cde16b3480f015c7eb32ba3 (patch)
tree5e68bd51510915b6da7db8e0fdcc5fc766dd6b6a /tools/perf
parentc0a54341c0e89333ef201fc3f3001176962f6121 (diff)
perf evsel: Introduce perf_evsel__open_strerror method
That consolidates the error messages in 'record', 'stat' and 'top', that now get a consistent set of messages and allow other tools to use the new method to report problems using whatever UI toolkit. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-1cudb7wl996kz7ilz83ctvhr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-record.c54
-rw-r--r--tools/perf/builtin-stat.c16
-rw-r--r--tools/perf/builtin-top.c34
-rw-r--r--tools/perf/ui/util.c11
-rw-r--r--tools/perf/util/debug.h1
-rw-r--r--tools/perf/util/evsel.c49
-rw-r--r--tools/perf/util/evsel.h3
7 files changed, 68 insertions, 100 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b8d0a39b484e..de60dd4ee5d3 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -224,7 +224,7 @@ static bool perf_evlist__equal(struct perf_evlist *evlist,
224 224
225static int perf_record__open(struct perf_record *rec) 225static int perf_record__open(struct perf_record *rec)
226{ 226{
227 char msg[128]; 227 char msg[512];
228 struct perf_evsel *pos; 228 struct perf_evsel *pos;
229 struct perf_evlist *evlist = rec->evlist; 229 struct perf_evlist *evlist = rec->evlist;
230 struct perf_session *session = rec->session; 230 struct perf_session *session = rec->session;
@@ -234,60 +234,18 @@ static int perf_record__open(struct perf_record *rec)
234 perf_evlist__config(evlist, opts); 234 perf_evlist__config(evlist, opts);
235 235
236 list_for_each_entry(pos, &evlist->entries, node) { 236 list_for_each_entry(pos, &evlist->entries, node) {
237 struct perf_event_attr *attr = &pos->attr;
238try_again: 237try_again:
239 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) { 238 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
240 int err = errno; 239 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
241
242 if (err == EPERM || err == EACCES) {
243 ui__error_paranoid();
244 rc = -err;
245 goto out;
246 } else if (err == ENODEV && opts->target.cpu_list) {
247 pr_err("No such device - did you specify"
248 " an out-of-range profile CPU?\n");
249 rc = -err;
250 goto out;
251 }
252
253 if (perf_evsel__fallback(pos, err, msg, sizeof(msg))) {
254 if (verbose) 240 if (verbose)
255 ui__warning("%s\n", msg); 241 ui__warning("%s\n", msg);
256 goto try_again; 242 goto try_again;
257 } 243 }
258 244
259 if (err == ENOENT) { 245 rc = -errno;
260 ui__error("The %s event is not supported.\n", 246 perf_evsel__open_strerror(pos, &opts->target,
261 perf_evsel__name(pos)); 247 errno, msg, sizeof(msg));
262 rc = -err; 248 ui__error("%s\n", msg);
263 goto out;
264 } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
265 ui__error("\'precise\' request may not be supported. "
266 "Try removing 'p' modifier\n");
267 rc = -err;
268 goto out;
269 }
270
271 printf("\n");
272 error("sys_perf_event_open() syscall returned with %d "
273 "(%s) for event %s. /bin/dmesg may provide "
274 "additional information.\n",
275 err, strerror(err), perf_evsel__name(pos));
276
277#if defined(__i386__) || defined(__x86_64__)
278 if (attr->type == PERF_TYPE_HARDWARE &&
279 err == EOPNOTSUPP) {
280 pr_err("No hardware sampling interrupt available."
281 " No APIC? If so then you can boot the kernel"
282 " with the \"lapic\" boot parameter to"
283 " force-enable it.\n");
284 rc = -err;
285 goto out;
286 }
287#endif
288
289 pr_err("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
290 rc = -err;
291 goto out; 249 goto out;
292 } 250 }
293 } 251 }
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ef067c193f93..1c2ac148a7d5 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -247,6 +247,7 @@ static int read_counter(struct perf_evsel *counter)
247 247
248static int __run_perf_stat(int argc __maybe_unused, const char **argv) 248static int __run_perf_stat(int argc __maybe_unused, const char **argv)
249{ 249{
250 char msg[512];
250 unsigned long long t0, t1; 251 unsigned long long t0, t1;
251 struct perf_evsel *counter; 252 struct perf_evsel *counter;
252 int status = 0; 253 int status = 0;
@@ -324,20 +325,13 @@ static int __run_perf_stat(int argc __maybe_unused, const char **argv)
324 continue; 325 continue;
325 } 326 }
326 327
327 if (errno == EPERM || errno == EACCES) { 328 perf_evsel__open_strerror(counter, &target,
328 error("You may not have permission to collect %sstats.\n" 329 errno, msg, sizeof(msg));
329 "\t Consider tweaking" 330 ui__error("%s\n", msg);
330 " /proc/sys/kernel/perf_event_paranoid or running as root.", 331
331 target.system_wide ? "system-wide " : "");
332 } else {
333 error("open_counter returned with %d (%s). "
334 "/bin/dmesg may provide additional information.\n",
335 errno, strerror(errno));
336 }
337 if (child_pid != -1) 332 if (child_pid != -1)
338 kill(child_pid, SIGTERM); 333 kill(child_pid, SIGTERM);
339 334
340 pr_err("Not all events could be opened.\n");
341 return -1; 335 return -1;
342 } 336 }
343 counter->supported = true; 337 counter->supported = true;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 8d41d0b58956..f5fd260f7b20 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -892,7 +892,7 @@ static void perf_top__mmap_read(struct perf_top *top)
892 892
893static void perf_top__start_counters(struct perf_top *top) 893static void perf_top__start_counters(struct perf_top *top)
894{ 894{
895 char msg[128]; 895 char msg[512];
896 struct perf_evsel *counter; 896 struct perf_evsel *counter;
897 struct perf_evlist *evlist = top->evlist; 897 struct perf_evlist *evlist = top->evlist;
898 struct perf_record_opts *opts = &top->record_opts; 898 struct perf_record_opts *opts = &top->record_opts;
@@ -900,42 +900,18 @@ static void perf_top__start_counters(struct perf_top *top)
900 perf_evlist__config(evlist, opts); 900 perf_evlist__config(evlist, opts);
901 901
902 list_for_each_entry(counter, &evlist->entries, node) { 902 list_for_each_entry(counter, &evlist->entries, node) {
903 struct perf_event_attr *attr = &counter->attr;
904try_again: 903try_again:
905 if (perf_evsel__open(counter, top->evlist->cpus, 904 if (perf_evsel__open(counter, top->evlist->cpus,
906 top->evlist->threads) < 0) { 905 top->evlist->threads) < 0) {
907 int err = errno; 906 if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
908
909 if (err == EPERM || err == EACCES) {
910 ui__error_paranoid();
911 goto out_err;
912 }
913
914 if (perf_evsel__fallback(counter, err, msg, sizeof(msg))) {
915 if (verbose) 907 if (verbose)
916 ui__warning("%s\n", msg); 908 ui__warning("%s\n", msg);
917 goto try_again; 909 goto try_again;
918 } 910 }
919 911
920 if (err == ENOENT) { 912 perf_evsel__open_strerror(counter, &opts->target,
921 ui__error("The %s event is not supported.\n", 913 errno, msg, sizeof(msg));
922 perf_evsel__name(counter)); 914 ui__error("%s\n", msg);
923 goto out_err;
924 } else if (err == EMFILE) {
925 ui__error("Too many events are opened.\n"
926 "Try again after reducing the number of events\n");
927 goto out_err;
928 } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
929 ui__error("\'precise\' request may not be supported. "
930 "Try removing 'p' modifier\n");
931 goto out_err;
932 }
933
934 ui__error("The sys_perf_event_open() syscall "
935 "returned with %d (%s). /bin/dmesg "
936 "may provide additional information.\n"
937 "No CONFIG_PERF_EVENTS=y kernel support "
938 "configured?\n", err, strerror(err));
939 goto out_err; 915 goto out_err;
940 } 916 }
941 } 917 }
diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c
index 3014a7cd5271..e3e0a963d03a 100644
--- a/tools/perf/ui/util.c
+++ b/tools/perf/ui/util.c
@@ -52,17 +52,6 @@ int ui__warning(const char *format, ...)
52 return ret; 52 return ret;
53} 53}
54 54
55int ui__error_paranoid(void)
56{
57 return ui__error("Permission error - are you root?\n"
58 "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
59 " -1 - Not paranoid at all\n"
60 " 0 - Disallow raw tracepoint access for unpriv\n"
61 " 1 - Disallow cpu events for unpriv\n"
62 " 2 - Disallow kernel profiling for unpriv\n");
63}
64
65
66/** 55/**
67 * perf_error__register - Register error logging functions 56 * perf_error__register - Register error logging functions
68 * @eops: The pointer to error logging function struct 57 * @eops: The pointer to error logging function struct
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 6e2667fb8211..efbd98805ad0 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -16,6 +16,5 @@ void trace_event(union perf_event *event);
16 16
17int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); 17int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
18int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); 18int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
19int ui__error_paranoid(void);
20 19
21#endif /* __PERF_DEBUG_H */ 20#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0c88e5c12dab..e45332d08a58 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1406,3 +1406,52 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
1406 1406
1407 return false; 1407 return false;
1408} 1408}
1409
1410int perf_evsel__open_strerror(struct perf_evsel *evsel,
1411 struct perf_target *target,
1412 int err, char *msg, size_t size)
1413{
1414 switch (err) {
1415 case EPERM:
1416 case EACCES:
1417 return scnprintf(msg, size, "%s",
1418 "You may not have permission to collect %sstats.\n"
1419 "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
1420 " -1 - Not paranoid at all\n"
1421 " 0 - Disallow raw tracepoint access for unpriv\n"
1422 " 1 - Disallow cpu events for unpriv\n"
1423 " 2 - Disallow kernel profiling for unpriv",
1424 target->system_wide ? "system-wide " : "");
1425 case ENOENT:
1426 return scnprintf(msg, size, "The %s event is not supported.",
1427 perf_evsel__name(evsel));
1428 case EMFILE:
1429 return scnprintf(msg, size, "%s",
1430 "Too many events are opened.\n"
1431 "Try again after reducing the number of events.");
1432 case ENODEV:
1433 if (target->cpu_list)
1434 return scnprintf(msg, size, "%s",
1435 "No such device - did you specify an out-of-range profile CPU?\n");
1436 break;
1437 case EOPNOTSUPP:
1438 if (evsel->attr.precise_ip)
1439 return scnprintf(msg, size, "%s",
1440 "\'precise\' request may not be supported. Try removing 'p' modifier.");
1441#if defined(__i386__) || defined(__x86_64__)
1442 if (evsel->attr.type == PERF_TYPE_HARDWARE)
1443 return scnprintf(msg, size, "%s",
1444 "No hardware sampling interrupt available.\n"
1445 "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.");
1446#endif
1447 break;
1448 default:
1449 break;
1450 }
1451
1452 return scnprintf(msg, size,
1453 "The sys_perf_event_open() syscall returned with %d (%s) for event (%s). \n"
1454 "/bin/dmesg may provide additional information.\n"
1455 "No CONFIG_PERF_EVENTS=y kernel support configured?\n",
1456 err, strerror(err), perf_evsel__name(evsel));
1457}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 26d8cfd86e0a..c68d1b82e843 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -254,4 +254,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
254 254
255bool perf_evsel__fallback(struct perf_evsel *evsel, int err, 255bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
256 char *msg, size_t msgsize); 256 char *msg, size_t msgsize);
257int perf_evsel__open_strerror(struct perf_evsel *evsel,
258 struct perf_target *target,
259 int err, char *msg, size_t size);
257#endif /* __PERF_EVSEL_H */ 260#endif /* __PERF_EVSEL_H */