aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2016-02-22 04:10:31 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-02-22 10:20:35 -0500
commita34f3be70cdf986850552e62b9f22d659bfbcef3 (patch)
tree0bd3d7848a84524bb5c55b4eb38466bdfda36a77 /tools/perf/util/parse-events.c
parent066dacbf2a32defb4de23ea4c1af9e77578b5ac2 (diff)
perf tools: Enable BPF object configure syntax
This patch adds the final step for BPF map configuration. A new syntax is appended into parser so user can config BPF objects through '/' '/' enclosed config terms. After this patch, following syntax is available: # perf record -e ./test_bpf_map_1.c/map:channel.value=10/ ... It would takes effect after appling following commits. Test result: # cat ./test_bpf_map_1.c /************************ BEGIN **************************/ #include <uapi/linux/bpf.h> #define SEC(NAME) __attribute__((section(NAME), used)) struct bpf_map_def { unsigned int type; unsigned int key_size; unsigned int value_size; unsigned int max_entries; }; static void *(*map_lookup_elem)(struct bpf_map_def *, void *) = (void *)BPF_FUNC_map_lookup_elem; static int (*trace_printk)(const char *fmt, int fmt_size, ...) = (void *)BPF_FUNC_trace_printk; struct bpf_map_def SEC("maps") channel = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), .value_size = sizeof(int), .max_entries = 1, }; SEC("func=sys_nanosleep") int func(void *ctx) { int key = 0; char fmt[] = "%d\n"; int *pval = map_lookup_elem(&channel, &key); if (!pval) return 0; trace_printk(fmt, sizeof(fmt), *pval); return 0; } char _license[] SEC("license") = "GPL"; int _version SEC("version") = LINUX_VERSION_CODE; /************************* END ***************************/ - Normal case: # ./perf record -e './test_bpf_map_1.c/map:channel.value=10/' usleep 10 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.012 MB perf.data ] - Error case: # ./perf record -e './test_bpf_map_1.c/map:channel.value/' usleep 10 event syntax error: '..ps:channel:value/' \___ Config value not set (missing '=') Hint: Valid config term: map:[<arraymap>]:value=[value] (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 # ./perf record -e './test_bpf_map_1.c/xmap:channel.value=10/' usleep 10 event syntax error: '..pf_map_1.c/xmap:channel.value=10/' \___ Invalid object config option [SNIP] # ./perf record -e './test_bpf_map_1.c/map:xchannel.value=10/' usleep 10 event syntax error: '..p_1.c/map:xchannel.value=10/' \___ Target map not exist [SNIP] # ./perf record -e './test_bpf_map_1.c/map:channel.xvalue=10/' usleep 10 event syntax error: '..ps:channel.xvalue=10/' \___ Invalid object map config option [SNIP] # ./perf record -e './test_bpf_map_1.c/map:channel.value=x10/' usleep 10 event syntax error: '..nnel.value=x10/' \___ Incorrect value type for map [SNIP] Change BPF_MAP_TYPE_ARRAY to '1' in test_bpf_map_1.c: # ./perf record -e './test_bpf_map_1.c/map:channel.value=10/' usleep 10 event syntax error: '..ps:channel.value=10/' \___ Can't use this config term to this type of map Hint: Valid config term: map:[<arraymap>].value=[value] (add -v to see detail) Signed-off-by: Wang Nan <wangnan0@huawei.com> [for parser part] Acked-by: Jiri Olsa <jolsa@kernel.org> 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: 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-5-git-send-email-wangnan0@huawei.com Signed-off-by: He Kuang <hekuang@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.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index b0b329539db5..a5dd6703a56b 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -672,17 +672,63 @@ errout:
672 return err; 672 return err;
673} 673}
674 674
675static int
676parse_events_config_bpf(struct parse_events_evlist *data,
677 struct bpf_object *obj,
678 struct list_head *head_config)
679{
680 struct parse_events_term *term;
681 int error_pos;
682
683 if (!head_config || list_empty(head_config))
684 return 0;
685
686 list_for_each_entry(term, head_config, list) {
687 char errbuf[BUFSIZ];
688 int err;
689
690 if (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) {
691 snprintf(errbuf, sizeof(errbuf),
692 "Invalid config term for BPF object");
693 errbuf[BUFSIZ - 1] = '\0';
694
695 data->error->idx = term->err_term;
696 data->error->str = strdup(errbuf);
697 return -EINVAL;
698 }
699
700 err = bpf__config_obj(obj, term, NULL, &error_pos);
701 if (err) {
702 bpf__strerror_config_obj(obj, term, NULL,
703 &error_pos, err, errbuf,
704 sizeof(errbuf));
705 data->error->help = strdup(
706"Hint:\tValid config term:\n"
707" \tmap:[<arraymap>].value=[value]\n"
708" \t(add -v to see detail)");
709 data->error->str = strdup(errbuf);
710 if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
711 data->error->idx = term->err_val;
712 else
713 data->error->idx = term->err_term + error_pos;
714 return err;
715 }
716 }
717 return 0;
718}
719
675int parse_events_load_bpf(struct parse_events_evlist *data, 720int parse_events_load_bpf(struct parse_events_evlist *data,
676 struct list_head *list, 721 struct list_head *list,
677 char *bpf_file_name, 722 char *bpf_file_name,
678 bool source) 723 bool source,
724 struct list_head *head_config)
679{ 725{
680 struct bpf_object *obj; 726 struct bpf_object *obj;
727 int err;
681 728
682 obj = bpf__prepare_load(bpf_file_name, source); 729 obj = bpf__prepare_load(bpf_file_name, source);
683 if (IS_ERR(obj)) { 730 if (IS_ERR(obj)) {
684 char errbuf[BUFSIZ]; 731 char errbuf[BUFSIZ];
685 int err;
686 732
687 err = PTR_ERR(obj); 733 err = PTR_ERR(obj);
688 734
@@ -700,7 +746,10 @@ int parse_events_load_bpf(struct parse_events_evlist *data,
700 return err; 746 return err;
701 } 747 }
702 748
703 return parse_events_load_bpf_obj(data, list, obj); 749 err = parse_events_load_bpf_obj(data, list, obj);
750 if (err)
751 return err;
752 return parse_events_config_bpf(data, obj, head_config);
704} 753}
705 754
706static int 755static int