From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751028AbbIFGCu (ORCPT ); Sun, 6 Sep 2015 02:02:50 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:24212 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750804AbbIFGCo (ORCPT ); Sun, 6 Sep 2015 02:02:44 -0400 From: Wang Nan To: CC: , Wang Nan , "Alexei Starovoitov" , Brendan Gregg , Daniel Borkmann , David Ahern , "He Kuang" , Jiri Olsa , Kaixu Xia , Masami Hiramatsu , Namhyung Kim , Paul Mackerras , Peter Zijlstra , Zefan Li , Subject: [PATCH] perf tools: Sync setting of real bpf events with placeholder Date: Sun, 6 Sep 2015 05:56:35 +0000 Message-ID: <1441518995-149427-1-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1441518918-149316-1-git-send-email-wangnan0@huawei.com> References: <1441518918-149316-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: Daniel Borkmann Cc: David Ahern Cc: He Kuang Cc: Jiri Olsa Cc: Kaixu Xia Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Zefan Li Cc: pi3orama@163.com Cc: Arnaldo Carvalho de Melo --- 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