aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-10-14 08:41:14 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-10-28 11:48:12 -0400
commit84c86ca12b2189df751eed7b2d67cb63bc8feda5 (patch)
tree428334c3c12ff87391c478220cdf6985bc1c5a77 /tools
parent69d262a93a25cf475012ea2e00aeb29f4932c028 (diff)
perf tools: Enable passing bpf object file to --event
By introducing new rules in tools/perf/util/parse-events.[ly], this patch enables 'perf record --event bpf_file.o' to select events by an eBPF object file. It calls parse_events_load_bpf() to load that file, which uses bpf__prepare_load() and finally calls bpf_object__open() for the object files. After applying this patch, commands like: # perf record --event foo.o sleep become possible. However, at this point it is unable to link any useful things onto the evsel list because the creating of probe points and BPF program attaching have not been implemented. Before real events are possible to be extracted, to avoid perf report error because of empty evsel list, this patch link a dummy evsel. The dummy event related code will be removed when probing and extracting code is ready. Commiter notes: Using it: $ ls -la foo.o ls: cannot access foo.o: No such file or directory $ perf record --event foo.o sleep libbpf: failed to open foo.o: No such file or directory event syntax error: 'foo.o' \___ BPF object file 'foo.o' is invalid (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events $ $ file /tmp/build/perf/perf.o /tmp/build/perf/perf.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped $ perf record --event /tmp/build/perf/perf.o sleep libbpf: /tmp/build/perf/perf.o is not an eBPF object file event syntax error: '/tmp/build/perf/perf.o' \___ BPF object file '/tmp/build/perf/perf.o' is invalid (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events $ $ file /tmp/foo.o /tmp/foo.o: ELF 64-bit LSB relocatable, no machine, version 1 (SYSV), not stripped $ perf record --event /tmp/foo.o sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.013 MB perf.data ] $ perf evlist /tmp/foo.o $ perf evlist -v /tmp/foo.o: type: 1, size: 112, config: 0x9, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1 $ So, type 1 is PERF_TYPE_SOFTWARE, config 0x9 is PERF_COUNT_SW_DUMMY, ok. $ perf report --stdio Error: The perf.data file has no samples! # To display the perf.data header info, please use --header/--header-only options. # $ Signed-off-by: Wang Nan <wangnan0@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@plumgrid.com> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: David Ahern <dsahern@gmail.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kaixu Xia <xiakaixu@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1444826502-49291-4-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/parse-events.c57
-rw-r--r--tools/perf/util/parse-events.h8
-rw-r--r--tools/perf/util/parse-events.l3
-rw-r--r--tools/perf/util/parse-events.y18
6 files changed, 88 insertions, 1 deletions
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 543713422d14..3d4c7c09adea 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -15,6 +15,7 @@
15#include "util/run-command.h" 15#include "util/run-command.h"
16#include "util/parse-events.h" 16#include "util/parse-events.h"
17#include "util/parse-options.h" 17#include "util/parse-options.h"
18#include "util/bpf-loader.h"
18#include "util/debug.h" 19#include "util/debug.h"
19#include <api/fs/tracing_path.h> 20#include <api/fs/tracing_path.h>
20#include <pthread.h> 21#include <pthread.h>
@@ -385,6 +386,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
385 status = p->fn(argc, argv, prefix); 386 status = p->fn(argc, argv, prefix);
386 exit_browser(status); 387 exit_browser(status);
387 perf_env__exit(&perf_env); 388 perf_env__exit(&perf_env);
389 bpf__clear();
388 390
389 if (status) 391 if (status)
390 return status & 0xff; 392 return status & 0xff;
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 9217119c4108..591b3fe3ed49 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -87,6 +87,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-bts.o
87libperf-y += parse-branch-options.o 87libperf-y += parse-branch-options.o
88libperf-y += parse-regs-options.o 88libperf-y += parse-regs-options.o
89 89
90libperf-$(CONFIG_LIBBPF) += bpf-loader.o
90libperf-$(CONFIG_LIBELF) += symbol-elf.o 91libperf-$(CONFIG_LIBELF) += symbol-elf.o
91libperf-$(CONFIG_LIBELF) += probe-file.o 92libperf-$(CONFIG_LIBELF) += probe-file.o
92libperf-$(CONFIG_LIBELF) += probe-event.o 93libperf-$(CONFIG_LIBELF) += probe-event.o
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 72abcf254ccb..a9e1d79d17d7 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -11,6 +11,7 @@
11#include "symbol.h" 11#include "symbol.h"
12#include "cache.h" 12#include "cache.h"
13#include "header.h" 13#include "header.h"
14#include "bpf-loader.h"
14#include "debug.h" 15#include "debug.h"
15#include <api/fs/tracing_path.h> 16#include <api/fs/tracing_path.h>
16#include "parse-events-bison.h" 17#include "parse-events-bison.h"
@@ -529,6 +530,62 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
529 return ret; 530 return ret;
530} 531}
531 532
533int parse_events_load_bpf_obj(struct parse_events_evlist *data,
534 struct list_head *list,
535 struct bpf_object *obj)
536{
537 int err;
538 char errbuf[BUFSIZ];
539
540 if (IS_ERR(obj) || !obj) {
541 snprintf(errbuf, sizeof(errbuf),
542 "Internal error: load bpf obj with NULL");
543 err = -EINVAL;
544 goto errout;
545 }
546
547 /*
548 * Temporary add a dummy event here so we can check whether
549 * basic bpf loader works. Following patches will replace
550 * dummy event by useful evsels.
551 */
552 return parse_events_add_numeric(data, list, PERF_TYPE_SOFTWARE,
553 PERF_COUNT_SW_DUMMY, NULL);
554errout:
555 data->error->help = strdup("(add -v to see detail)");
556 data->error->str = strdup(errbuf);
557 return err;
558}
559
560int parse_events_load_bpf(struct parse_events_evlist *data,
561 struct list_head *list,
562 char *bpf_file_name)
563{
564 struct bpf_object *obj;
565
566 obj = bpf__prepare_load(bpf_file_name);
567 if (IS_ERR(obj) || !obj) {
568 char errbuf[BUFSIZ];
569 int err;
570
571 err = obj ? PTR_ERR(obj) : -EINVAL;
572
573 if (err == -ENOTSUP)
574 snprintf(errbuf, sizeof(errbuf),
575 "BPF support is not compiled");
576 else
577 snprintf(errbuf, sizeof(errbuf),
578 "BPF object file '%s' is invalid",
579 bpf_file_name);
580
581 data->error->help = strdup("(add -v to see detail)");
582 data->error->str = strdup(errbuf);
583 return err;
584 }
585
586 return parse_events_load_bpf_obj(data, list, obj);
587}
588
532static int 589static int
533parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 590parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
534{ 591{
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 13c9063513eb..765018a17448 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -123,6 +123,14 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx,
123 char *sys, char *event, 123 char *sys, char *event,
124 struct parse_events_error *error, 124 struct parse_events_error *error,
125 struct list_head *head_config); 125 struct list_head *head_config);
126int parse_events_load_bpf(struct parse_events_evlist *data,
127 struct list_head *list,
128 char *bpf_file_name);
129/* Provide this function for perf test */
130struct bpf_object;
131int parse_events_load_bpf_obj(struct parse_events_evlist *data,
132 struct list_head *list,
133 struct bpf_object *obj);
126int parse_events_add_numeric(struct parse_events_evlist *data, 134int parse_events_add_numeric(struct parse_events_evlist *data,
127 struct list_head *list, 135 struct list_head *list,
128 u32 type, u64 config, 136 u32 type, u64 config,
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 8d0de5b2991d..cf330ebf812c 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -115,6 +115,7 @@ do { \
115group [^,{}/]*[{][^}]*[}][^,{}/]* 115group [^,{}/]*[{][^}]*[}][^,{}/]*
116event_pmu [^,{}/]+[/][^/]*[/][^,{}/]* 116event_pmu [^,{}/]+[/][^/]*[/][^,{}/]*
117event [^,{}/]+ 117event [^,{}/]+
118bpf_object .*\.(o|bpf)
118 119
119num_dec [0-9]+ 120num_dec [0-9]+
120num_hex 0x[a-fA-F0-9]+ 121num_hex 0x[a-fA-F0-9]+
@@ -159,6 +160,7 @@ modifier_bp [rwx]{1,3}
159 } 160 }
160 161
161{event_pmu} | 162{event_pmu} |
163{bpf_object} |
162{event} { 164{event} {
163 BEGIN(INITIAL); 165 BEGIN(INITIAL);
164 REWIND(1); 166 REWIND(1);
@@ -266,6 +268,7 @@ r{num_raw_hex} { return raw(yyscanner); }
266{num_hex} { return value(yyscanner, 16); } 268{num_hex} { return value(yyscanner, 16); }
267 269
268{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } 270{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
271{bpf_object} { return str(yyscanner, PE_BPF_OBJECT); }
269{name} { return pmu_str_check(yyscanner); } 272{name} { return pmu_str_check(yyscanner); }
270"/" { BEGIN(config); return '/'; } 273"/" { BEGIN(config); return '/'; }
271- { return '-'; } 274- { return '-'; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index ae6af269f9c9..497f19b20f0b 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -42,6 +42,7 @@ static inc_group_count(struct list_head *list,
42%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM 42%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
43%token PE_EVENT_NAME 43%token PE_EVENT_NAME
44%token PE_NAME 44%token PE_NAME
45%token PE_BPF_OBJECT
45%token PE_MODIFIER_EVENT PE_MODIFIER_BP 46%token PE_MODIFIER_EVENT PE_MODIFIER_BP
46%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 47%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
47%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 48%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
@@ -53,6 +54,7 @@ static inc_group_count(struct list_head *list,
53%type <num> PE_RAW 54%type <num> PE_RAW
54%type <num> PE_TERM 55%type <num> PE_TERM
55%type <str> PE_NAME 56%type <str> PE_NAME
57%type <str> PE_BPF_OBJECT
56%type <str> PE_NAME_CACHE_TYPE 58%type <str> PE_NAME_CACHE_TYPE
57%type <str> PE_NAME_CACHE_OP_RESULT 59%type <str> PE_NAME_CACHE_OP_RESULT
58%type <str> PE_MODIFIER_EVENT 60%type <str> PE_MODIFIER_EVENT
@@ -70,6 +72,7 @@ static inc_group_count(struct list_head *list,
70%type <tracepoint_name> tracepoint_name 72%type <tracepoint_name> tracepoint_name
71%type <head> event_legacy_numeric 73%type <head> event_legacy_numeric
72%type <head> event_legacy_raw 74%type <head> event_legacy_raw
75%type <head> event_bpf_file
73%type <head> event_def 76%type <head> event_def
74%type <head> event_mod 77%type <head> event_mod
75%type <head> event_name 78%type <head> event_name
@@ -203,7 +206,8 @@ event_def: event_pmu |
203 event_legacy_mem | 206 event_legacy_mem |
204 event_legacy_tracepoint sep_dc | 207 event_legacy_tracepoint sep_dc |
205 event_legacy_numeric sep_dc | 208 event_legacy_numeric sep_dc |
206 event_legacy_raw sep_dc 209 event_legacy_raw sep_dc |
210 event_bpf_file
207 211
208event_pmu: 212event_pmu:
209PE_NAME '/' event_config '/' 213PE_NAME '/' event_config '/'
@@ -449,6 +453,18 @@ PE_RAW
449 $$ = list; 453 $$ = list;
450} 454}
451 455
456event_bpf_file:
457PE_BPF_OBJECT
458{
459 struct parse_events_evlist *data = _data;
460 struct parse_events_error *error = data->error;
461 struct list_head *list;
462
463 ALLOC_LIST(list);
464 ABORT_ON(parse_events_load_bpf(data, list, $1));
465 $$ = list;
466}
467
452start_terms: event_config 468start_terms: event_config
453{ 469{
454 struct parse_events_terms *data = _data; 470 struct parse_events_terms *data = _data;