aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2016-02-22 04:10:36 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-02-22 11:02:44 -0500
commit95088a591e197610bd03f4059f5fdbe9e376425b (patch)
treeb48f2529838b72d00d2caba00bb0cfbf0bddd790 /tools/perf/util/parse-events.c
parente571e029bdbf59f485fe67740b7a4ef421e1d55d (diff)
perf tools: Apply tracepoint event definition options to BPF script
Users can pass options to tracepoints defined in the BPF script. For example: # perf record -e ./test.c/no-inherit/ bash # dd if=/dev/zero of=/dev/null count=10000 # exit [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.022 MB perf.data (139 samples) ] (no-inherit works, only the sys_read issued by bash are captured, at least 10000 sys_read issued by dd are skipped.) test.c: #define SEC(NAME) __attribute__((section(NAME), used)) SEC("func=sys_read") int bpf_func__sys_read(void *ctx) { return 1; } char _license[] SEC("license") = "GPL"; int _version SEC("version") = LINUX_VERSION_CODE; no-inherit is applied to the kprobe event defined in test.c. Signed-off-by: Wang Nan <wangnan0@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Cody P Schafer <dev@codyps.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kirill Smelkov <kirr@nexedi.com> Cc: Li Zefan <lizefan@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1456132275-98875-10-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6e2f20334379..4c19d5e79d8c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -581,6 +581,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
581struct __add_bpf_event_param { 581struct __add_bpf_event_param {
582 struct parse_events_evlist *data; 582 struct parse_events_evlist *data;
583 struct list_head *list; 583 struct list_head *list;
584 struct list_head *head_config;
584}; 585};
585 586
586static int add_bpf_event(struct probe_trace_event *tev, int fd, 587static int add_bpf_event(struct probe_trace_event *tev, int fd,
@@ -597,7 +598,8 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
597 tev->group, tev->event, fd); 598 tev->group, tev->event, fd);
598 599
599 err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group, 600 err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group,
600 tev->event, evlist->error, NULL); 601 tev->event, evlist->error,
602 param->head_config);
601 if (err) { 603 if (err) {
602 struct perf_evsel *evsel, *tmp; 604 struct perf_evsel *evsel, *tmp;
603 605
@@ -622,11 +624,12 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
622 624
623int parse_events_load_bpf_obj(struct parse_events_evlist *data, 625int parse_events_load_bpf_obj(struct parse_events_evlist *data,
624 struct list_head *list, 626 struct list_head *list,
625 struct bpf_object *obj) 627 struct bpf_object *obj,
628 struct list_head *head_config)
626{ 629{
627 int err; 630 int err;
628 char errbuf[BUFSIZ]; 631 char errbuf[BUFSIZ];
629 struct __add_bpf_event_param param = {data, list}; 632 struct __add_bpf_event_param param = {data, list, head_config};
630 static bool registered_unprobe_atexit = false; 633 static bool registered_unprobe_atexit = false;
631 634
632 if (IS_ERR(obj) || !obj) { 635 if (IS_ERR(obj) || !obj) {
@@ -720,14 +723,47 @@ parse_events_config_bpf(struct parse_events_evlist *data,
720 return 0; 723 return 0;
721} 724}
722 725
726/*
727 * Split config terms:
728 * perf record -e bpf.c/call-graph=fp,map:array.value[0]=1/ ...
729 * 'call-graph=fp' is 'evt config', should be applied to each
730 * events in bpf.c.
731 * 'map:array.value[0]=1' is 'obj config', should be processed
732 * with parse_events_config_bpf.
733 *
734 * Move object config terms from the first list to obj_head_config.
735 */
736static void
737split_bpf_config_terms(struct list_head *evt_head_config,
738 struct list_head *obj_head_config)
739{
740 struct parse_events_term *term, *temp;
741
742 /*
743 * Currectly, all possible user config term
744 * belong to bpf object. parse_events__is_hardcoded_term()
745 * happends to be a good flag.
746 *
747 * See parse_events_config_bpf() and
748 * config_term_tracepoint().
749 */
750 list_for_each_entry_safe(term, temp, evt_head_config, list)
751 if (!parse_events__is_hardcoded_term(term))
752 list_move_tail(&term->list, obj_head_config);
753}
754
723int parse_events_load_bpf(struct parse_events_evlist *data, 755int parse_events_load_bpf(struct parse_events_evlist *data,
724 struct list_head *list, 756 struct list_head *list,
725 char *bpf_file_name, 757 char *bpf_file_name,
726 bool source, 758 bool source,
727 struct list_head *head_config) 759 struct list_head *head_config)
728{ 760{
729 struct bpf_object *obj;
730 int err; 761 int err;
762 struct bpf_object *obj;
763 LIST_HEAD(obj_head_config);
764
765 if (head_config)
766 split_bpf_config_terms(head_config, &obj_head_config);
731 767
732 obj = bpf__prepare_load(bpf_file_name, source); 768 obj = bpf__prepare_load(bpf_file_name, source);
733 if (IS_ERR(obj)) { 769 if (IS_ERR(obj)) {
@@ -749,10 +785,18 @@ int parse_events_load_bpf(struct parse_events_evlist *data,
749 return err; 785 return err;
750 } 786 }
751 787
752 err = parse_events_load_bpf_obj(data, list, obj); 788 err = parse_events_load_bpf_obj(data, list, obj, head_config);
753 if (err) 789 if (err)
754 return err; 790 return err;
755 return parse_events_config_bpf(data, obj, head_config); 791 err = parse_events_config_bpf(data, obj, &obj_head_config);
792
793 /*
794 * Caller doesn't know anything about obj_head_config,
795 * so combine them together again before returnning.
796 */
797 if (head_config)
798 list_splice_tail(&obj_head_config, head_config);
799 return err;
756} 800}
757 801
758static int 802static int