Messages in this thread Patch in this message | | | From | Wang Nan <> | Subject | [PATCH] perf tools: Sync setting of real bpf events with placeholder | Date | Sun, 6 Sep 2015 05:56:35 +0000 |
| |
In this patch, when adding real events described in BPF objects, sync filter and tracking settings with previous dummy placeholder. After this patch, command like:
# perf record --test-filter.o --exclude-perf ls
work as we expect.
After all settings are synced, we remove those placeholder from evlist so they won't appear in the final perf.data.
Signed-off-by: Wang Nan <wangnan0@huawei.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: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Cc: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/bpf-loader.c | 8 ++++- tools/perf/util/bpf-loader.h | 1 + tools/perf/util/evlist.c | 75 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 2880dbf..3400538 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -325,6 +325,12 @@ int bpf__foreach_tev(bpf_prog_iter_callback_t func, void *arg) int err; bpf_object__for_each_safe(obj, tmp) { + const char *obj_name; + + obj_name = bpf_object__get_name(obj); + if (!obj_name) + obj_name = "[unknown].o"; + bpf_object__for_each_program(prog, obj) { struct probe_trace_event *tev; struct perf_probe_event *pev; @@ -348,7 +354,7 @@ int bpf__foreach_tev(bpf_prog_iter_callback_t func, void *arg) return fd; } - err = (*func)(tev, fd, arg); + err = (*func)(tev, obj_name, fd, arg); if (err) { pr_debug("bpf: call back failed, stop iterate\n"); return err; diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index 34656f8..5bac423 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -13,6 +13,7 @@ #define PERF_BPF_PROBE_GROUP "perf_bpf_probe" typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev, + const char *obj_name, int fd, void *arg); #ifdef HAVE_LIBBPF_SUPPORT diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 29212dc..7e36563 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -197,7 +197,54 @@ error: return -ENOMEM; } -static int add_bpf_event(struct probe_trace_event *tev, int fd, +static void sync_with_bpf_placeholder(struct perf_evlist *evlist, + const char *obj_name, + struct list_head *list) +{ + struct perf_evsel *dummy_evsel, *pos; + + const char *filter; + bool tracking_set = false; + bool found = false; + + evlist__for_each(evlist, dummy_evsel) { + if (!perf_evsel__is_bpf_placeholder(dummy_evsel)) + continue; + + if (strcmp(dummy_evsel->name, obj_name) == 0) { + found = true; + break; + } + } + + if (!found) { + pr_debug("Failed to find dummy event of '%s'\n", + obj_name); + return; + } + + filter = dummy_evsel->filter; + + list_for_each_entry(pos, list, node) { + if (filter && perf_evsel__set_filter(pos, filter)) { + pr_debug("Failed to set filter '%s' to evsel %s\n", + filter, pos->name); + } + + /* Sync tracking */ + if (dummy_evsel->tracking && !tracking_set) + pos->tracking = tracking_set = true; + + /* + * If someday we allow to add config terms or modifiers + * to placeholder, we should sync them with real events + * here. Currently only tracking needs to be considered. + */ + } +} + +static int add_bpf_event(struct probe_trace_event *tev, + const char *obj_name, int fd, void *arg) { struct perf_evlist *evlist = arg; @@ -205,8 +252,8 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd, struct list_head list; int err, idx, entries; - pr_debug("add bpf event %s:%s and attach bpf program %d\n", - tev->group, tev->event, fd); + pr_debug("add bpf event %s:%s and attach bpf program %d (from %s)\n", + tev->group, tev->event, fd, obj_name); INIT_LIST_HEAD(&list); idx = evlist->nr_entries; @@ -228,13 +275,33 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd, list_for_each_entry(pos, &list, node) pos->bpf_fd = fd; entries = idx - evlist->nr_entries; + + sync_with_bpf_placeholder(evlist, obj_name, &list); + /* + * Currectly we don't need to link those new events at the + * same place where dummy node reside because order of + * events in cmdline won't be used after + * 'perf_evlist__add_bpf'. + */ perf_evlist__splice_list_tail(evlist, &list, entries); return 0; } int perf_evlist__add_bpf(struct perf_evlist *evlist) { - return bpf__foreach_tev(add_bpf_event, evlist); + struct perf_evsel *pos, *n; + int err; + + err = bpf__foreach_tev(add_bpf_event, evlist); + + evlist__for_each_safe(evlist, n, pos) { + if (perf_evsel__is_bpf_placeholder(pos)) { + list_del_init(&pos->node); + perf_evsel__delete(pos); + evlist->nr_entries--; + } + } + return err; } static int perf_evlist__add_attrs(struct perf_evlist *evlist, -- 1.8.3.4
| |