From patchwork Fri Aug 28 06:20:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 52793 Delivered-To: patch@linaro.org Received: by 10.112.151.194 with SMTP id us2csp298663lbb; Thu, 27 Aug 2015 23:23:57 -0700 (PDT) X-Received: by 10.68.138.200 with SMTP id qs8mr12700460pbb.19.1440743037407; Thu, 27 Aug 2015 23:23:57 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id nh14si8093314pdb.40.2015.08.27.23.23.56; Thu, 27 Aug 2015 23:23:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752144AbbH1GXy (ORCPT + 28 others); Fri, 28 Aug 2015 02:23:54 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:49404 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751327AbbH1GXx (ORCPT ); Fri, 28 Aug 2015 02:23:53 -0400 Received: from 172.24.1.49 (EHLO szxeml431-hub.china.huawei.com) ([172.24.1.49]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BLU98358; Fri, 28 Aug 2015 14:21:11 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by szxeml431-hub.china.huawei.com (10.82.67.208) with Microsoft SMTP Server id 14.3.235.1; Fri, 28 Aug 2015 14:20:41 +0800 From: Wang Nan To: CC: , , , , , , , , , , , , , Wang Nan , Paul Mackerras Subject: [PATCH 12/32] perf tools: Allow filter option to be applied to bof object Date: Fri, 28 Aug 2015 06:20:21 +0000 Message-ID: <1440742821-44548-5-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1440742821-44548-1-git-send-email-wangnan0@huawei.com> References: <1440742821-44548-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020204.55DFFDD8.00BF, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 1a868dead138749c4e90856faf2aa260 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Before this patch, --filter options can't be applied to BPF object 'events'. For example, the following command: # perf record -e cycles -e test_bpf.o --exclude-perf -a sleep 1 doesn't apply '--exclude-perf' to events in test_bpf.o. Instead, the filter will be applied to 'cycles' event. This is caused by the delay manner of adding real BPF events. Because all BPF probing points are probed by one call, we can't add real events until all BPF objects are collected. In previous patch (perf tools: Enable passing bpf object file to --event), nothing is appended to evlist. This patch fixes this by utilizing the dummy event linked during parse_events(). Filter settings goes to dummy event, and be synced with real events in add_bpf_event(). 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/builtin-record.c | 6 ++++- tools/perf/util/bpf-loader.c | 8 ++++++- tools/perf/util/bpf-loader.h | 2 ++ tools/perf/util/evlist.c | 53 +++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 64 insertions(+), 5 deletions(-) -- 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 5051d3b..fd56a5b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1113,7 +1113,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) argc = parse_options(argc, argv, record_options, record_usage, PARSE_OPT_STOP_AT_NON_OPTION); - perf_evlist__purge_dummy(rec->evlist); if (!argc && target__none(&rec->opts.target)) usage_with_options(record_usage, record_options); @@ -1178,6 +1177,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) pr_err("Failed to add events from BPF object(s)\n"); goto out_symbol_exit; } + /* + * Until now let's purge dummy event. Filter options should + * have been attached to real events by perf_evlist__add_bpf(). + */ + perf_evlist__purge_dummy(rec->evlist); symbol__init(NULL); diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 126aa71..c3bc0a8 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -293,6 +293,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]"; + bpf_object__for_each_program(prog, obj) { struct probe_trace_event *tev; struct perf_probe_event *pev; @@ -316,7 +322,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..323e664 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -6,6 +6,7 @@ #define __BPF_LOADER_H #include +#include #include #include "probe-event.h" #include "debug.h" @@ -13,6 +14,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 3bedf64..21a11c9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -195,7 +195,45 @@ error: return -ENOMEM; } -static int add_bpf_event(struct probe_trace_event *tev, int fd, +static void +sync_with_dummy(struct perf_evlist *evlist, const char *obj_name, + struct list_head *list) +{ + struct perf_evsel *dummy_evsel, *pos; + const char *filter; + bool found = false; + int err; + + evlist__for_each(evlist, dummy_evsel) { + if (!perf_evsel__is_dummy(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; + if (!filter) + return; + + list_for_each_entry(pos, list, node) { + err = perf_evsel__set_filter(pos, filter); + if (err) + pr_debug("Failed to set filter '%s' to evsel %s\n", + filter, pos->name); + } +} + +static int add_bpf_event(struct probe_trace_event *tev, + const char *obj_name, int fd, void *arg) { struct perf_evlist *evlist = arg; @@ -203,8 +241,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; @@ -226,6 +264,15 @@ 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_dummy(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; }