aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-09-16 03:12:07 -0400
committerIngo Molnar <mingo@kernel.org>2015-09-16 03:12:07 -0400
commita4d71093e759b7cfe0babbc6ae89c8130532f6ad (patch)
tree760399c41577b0e70ca4ecd32a807b19a625d432 /tools/perf/util/parse-events.c
parent9059b284caecb628fac826c2c5cc8ee85708eec1 (diff)
parentbbbe6bf6037d77816c4a19aaf35f4cecf662b49a (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Enhance the error reporting of tracepoint event parsing, e.g.: $ oldperf record -e sched:sched_switc usleep 1 event syntax error: 'sched:sched_switc' \___ unknown tracepoint Run 'perf list' for a list of valid events Now we get the much nicer: $ perf record -e sched:sched_switc ls event syntax error: 'sched:sched_switc' \___ can't access trace events Error: No permissions to read /sys/kernel/debug/tracing/events/sched/sched_switc Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug' And after we have those mount point permissions fixed: $ perf record -e sched:sched_switc ls event syntax error: 'sched:sched_switc' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sched/sched_switc not found. Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. Now its just a matter of using what git uses to suggest alternatives when we make a typo, i.e. that it is just an 'h' missing :-) I.e. basically now the event parsing routing uses the strerror_open() routines introduced by and used in 'perf trace' work. (Jiri Olsa) Infrastructure changes: - Export init/exit_probe_symbol_maps() from 'perf probe' for use in eBPF. (Namhyung Kim) - Free perf_probe_event in cleanup_perf_probe_events(). (Namhyung Kim) - regs_query_register_offset() infrastructure + implementation for x86. First user will be the perf/eBPF code. (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 3840176642f8..d3fb90be6216 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,4 +1,5 @@
1#include <linux/hw_breakpoint.h> 1#include <linux/hw_breakpoint.h>
2#include <linux/err.h>
2#include "util.h" 3#include "util.h"
3#include "../perf.h" 4#include "../perf.h"
4#include "evlist.h" 5#include "evlist.h"
@@ -386,22 +387,52 @@ int parse_events_add_cache(struct list_head *list, int *idx,
386 return add_event(list, idx, &attr, name, NULL); 387 return add_event(list, idx, &attr, name, NULL);
387} 388}
388 389
390static void tracepoint_error(struct parse_events_error *error, int err,
391 char *sys, char *name)
392{
393 char help[BUFSIZ];
394
395 /*
396 * We get error directly from syscall errno ( > 0),
397 * or from encoded pointer's error ( < 0).
398 */
399 err = abs(err);
400
401 switch (err) {
402 case EACCES:
403 error->str = strdup("can't access trace events");
404 break;
405 case ENOENT:
406 error->str = strdup("unknown tracepoint");
407 break;
408 default:
409 error->str = strdup("failed to add tracepoint");
410 break;
411 }
412
413 tracing_path__strerror_open_tp(err, help, sizeof(help), sys, name);
414 error->help = strdup(help);
415}
416
389static int add_tracepoint(struct list_head *list, int *idx, 417static int add_tracepoint(struct list_head *list, int *idx,
390 char *sys_name, char *evt_name) 418 char *sys_name, char *evt_name,
419 struct parse_events_error *error __maybe_unused)
391{ 420{
392 struct perf_evsel *evsel; 421 struct perf_evsel *evsel;
393 422
394 evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); 423 evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
395 if (!evsel) 424 if (IS_ERR(evsel)) {
396 return -ENOMEM; 425 tracepoint_error(error, PTR_ERR(evsel), sys_name, evt_name);
426 return PTR_ERR(evsel);
427 }
397 428
398 list_add_tail(&evsel->node, list); 429 list_add_tail(&evsel->node, list);
399
400 return 0; 430 return 0;
401} 431}
402 432
403static int add_tracepoint_multi_event(struct list_head *list, int *idx, 433static int add_tracepoint_multi_event(struct list_head *list, int *idx,
404 char *sys_name, char *evt_name) 434 char *sys_name, char *evt_name,
435 struct parse_events_error *error)
405{ 436{
406 char evt_path[MAXPATHLEN]; 437 char evt_path[MAXPATHLEN];
407 struct dirent *evt_ent; 438 struct dirent *evt_ent;
@@ -411,7 +442,7 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
411 snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 442 snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name);
412 evt_dir = opendir(evt_path); 443 evt_dir = opendir(evt_path);
413 if (!evt_dir) { 444 if (!evt_dir) {
414 perror("Can't open event dir"); 445 tracepoint_error(error, errno, sys_name, evt_name);
415 return -1; 446 return -1;
416 } 447 }
417 448
@@ -425,7 +456,7 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
425 if (!strglobmatch(evt_ent->d_name, evt_name)) 456 if (!strglobmatch(evt_ent->d_name, evt_name))
426 continue; 457 continue;
427 458
428 ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 459 ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name, error);
429 } 460 }
430 461
431 closedir(evt_dir); 462 closedir(evt_dir);
@@ -433,15 +464,17 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
433} 464}
434 465
435static int add_tracepoint_event(struct list_head *list, int *idx, 466static int add_tracepoint_event(struct list_head *list, int *idx,
436 char *sys_name, char *evt_name) 467 char *sys_name, char *evt_name,
468 struct parse_events_error *error)
437{ 469{
438 return strpbrk(evt_name, "*?") ? 470 return strpbrk(evt_name, "*?") ?
439 add_tracepoint_multi_event(list, idx, sys_name, evt_name) : 471 add_tracepoint_multi_event(list, idx, sys_name, evt_name, error) :
440 add_tracepoint(list, idx, sys_name, evt_name); 472 add_tracepoint(list, idx, sys_name, evt_name, error);
441} 473}
442 474
443static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 475static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
444 char *sys_name, char *evt_name) 476 char *sys_name, char *evt_name,
477 struct parse_events_error *error)
445{ 478{
446 struct dirent *events_ent; 479 struct dirent *events_ent;
447 DIR *events_dir; 480 DIR *events_dir;
@@ -449,7 +482,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
449 482
450 events_dir = opendir(tracing_events_path); 483 events_dir = opendir(tracing_events_path);
451 if (!events_dir) { 484 if (!events_dir) {
452 perror("Can't open event dir"); 485 tracepoint_error(error, errno, sys_name, evt_name);
453 return -1; 486 return -1;
454 } 487 }
455 488
@@ -465,7 +498,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
465 continue; 498 continue;
466 499
467 ret = add_tracepoint_event(list, idx, events_ent->d_name, 500 ret = add_tracepoint_event(list, idx, events_ent->d_name,
468 evt_name); 501 evt_name, error);
469 } 502 }
470 503
471 closedir(events_dir); 504 closedir(events_dir);
@@ -473,12 +506,13 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
473} 506}
474 507
475int parse_events_add_tracepoint(struct list_head *list, int *idx, 508int parse_events_add_tracepoint(struct list_head *list, int *idx,
476 char *sys, char *event) 509 char *sys, char *event,
510 struct parse_events_error *error)
477{ 511{
478 if (strpbrk(sys, "*?")) 512 if (strpbrk(sys, "*?"))
479 return add_tracepoint_multi_sys(list, idx, sys, event); 513 return add_tracepoint_multi_sys(list, idx, sys, event, error);
480 else 514 else
481 return add_tracepoint_event(list, idx, sys, event); 515 return add_tracepoint_event(list, idx, sys, event, error);
482} 516}
483 517
484static int 518static int