From patchwork Wed Sep 23 11:22:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 54030 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f71.google.com (mail-la0-f71.google.com [209.85.215.71]) by patches.linaro.org (Postfix) with ESMTPS id AC4A622F10 for ; Wed, 23 Sep 2015 11:23:33 +0000 (UTC) Received: by lacao8 with SMTP id ao8sf10499672lac.3 for ; Wed, 23 Sep 2015 04:23:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe; bh=AMn7A1XtYMcZQxn5c1bRQrso9jRvwmKXx8KZ48KB/zo=; b=fiTfQoaemYJXvaaUCH0gK+JOS5liL6Z6yA5zguuGhqMP0mWxs0A9lN3Ui2RXgr8LIE nITAv+qP5GVL40aUaPupC023ajWY+EakEJhA/DyfoaLA1ho+ZYQdU0Dm6pq/uHmk3gdE cetHllQjdY40lDHmfKyPBfF9eWR98iW71+x/+C+2/tZo1CVw9F/XPRqhmYI1AbDiZgR6 RnscvrohNGiYtI+hQlqeorrwB2WWV9/QycoqVGRIN7IJ3Rji9A6ihmm7riUNPO1HpqtJ 7/AkS7JE9hWAehA60x5obtHFnliEwFG5l8WcDK0tzSITHMTd1nUM2NSrVRwfYftVm2Qy iijw== X-Gm-Message-State: ALoCoQk4ALjSVhZbz55LEjRRYTNkr9LO6+f9ZkAm03AJ/ZU8VPztbqwnvRbSpODiER9bsKxYmS9o X-Received: by 10.180.10.202 with SMTP id k10mr505606wib.2.1443007412717; Wed, 23 Sep 2015 04:23:32 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.6.196 with SMTP id d4ls34718laa.100.gmail; Wed, 23 Sep 2015 04:23:32 -0700 (PDT) X-Received: by 10.152.5.133 with SMTP id s5mr11296919las.19.1443007412533; Wed, 23 Sep 2015 04:23:32 -0700 (PDT) Received: from mail-la0-f42.google.com (mail-la0-f42.google.com. [209.85.215.42]) by mx.google.com with ESMTPS id ku10si3508377lac.18.2015.09.23.04.23.32 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Sep 2015 04:23:32 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) client-ip=209.85.215.42; Received: by lahh2 with SMTP id h2so22040992lah.0 for ; Wed, 23 Sep 2015 04:23:32 -0700 (PDT) X-Received: by 10.152.21.196 with SMTP id x4mr11409371lae.86.1443007412308; Wed, 23 Sep 2015 04:23:32 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1043053lbq; Wed, 23 Sep 2015 04:23:31 -0700 (PDT) X-Received: by 10.68.234.200 with SMTP id ug8mr37547093pbc.13.1443007409854; Wed, 23 Sep 2015 04:23:29 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b10si9930098pbu.47.2015.09.23.04.23.29; Wed, 23 Sep 2015 04:23:29 -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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754264AbbIWLX1 (ORCPT + 30 others); Wed, 23 Sep 2015 07:23:27 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:56713 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754105AbbIWLXW (ORCPT ); Wed, 23 Sep 2015 07:23:22 -0400 Received: from 172.24.1.49 (EHLO szxeml426-hub.china.huawei.com) ([172.24.1.49]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BNW12504; Wed, 23 Sep 2015 19:23:12 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by szxeml426-hub.china.huawei.com (10.82.67.181) with Microsoft SMTP Server id 14.3.235.1; Wed, 23 Sep 2015 19:23:04 +0800 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 , Peter Zijlstra , Zefan Li Subject: [PATCH 10/22] perf test: Add 'perf test BPF' Date: Wed, 23 Sep 2015 11:22:31 +0000 Message-ID: <1443007363-124182-11-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1443007363-124182-1-git-send-email-wangnan0@huawei.com> References: <1443007363-124182-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.0A010204.56028BA1.0030, 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: 7e09b3ade0571a7e5d44a7b3479a4260 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: wangnan0@huawei.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch adds BPF testcase for testing BPF event filtering. By utilizing the result of 'perf test LLVM', this patch compiles the eBPF sample program then test it ability. The BPF script in 'perf test LLVM' collects half of execution of epoll_pwait(). This patch runs 111 times of it, so the resule should contains 56 samples. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo 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: Peter Zijlstra Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/n/ebpf-6yw9eg0ej3l4jnqhinngkw86@git.kernel.org --- tools/perf/tests/Build | 1 + tools/perf/tests/bpf.c | 171 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/llvm.c | 19 +++++ tools/perf/tests/llvm.h | 1 + tools/perf/tests/tests.h | 1 + tools/perf/util/bpf-loader.c | 14 ++++ tools/perf/util/bpf-loader.h | 9 +++ 8 files changed, 220 insertions(+) create mode 100644 tools/perf/tests/bpf.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index e80f787..5cfb420 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -33,6 +33,7 @@ perf-y += parse-no-sample-id-all.o perf-y += kmod-path.o perf-y += thread-map.o perf-y += llvm.o llvm-src.o +perf-y += bpf.o perf-y += topology.o $(OUTPUT)tests/llvm-src.c: tests/bpf-script-example.c diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c new file mode 100644 index 0000000..d7cdc84 --- /dev/null +++ b/tools/perf/tests/bpf.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include "tests.h" +#include "llvm.h" +#include "debug.h" +#define NR_ITERS 111 + +#ifdef HAVE_LIBBPF_SUPPORT + +static int epoll_pwait_loop(void) +{ + int i; + + /* Should fail NR_ITERS times */ + for (i = 0; i < NR_ITERS; i++) + epoll_pwait(-(i + 1), NULL, 0, 0, NULL); + return 0; +} + +static struct bpf_object *prepare_bpf(void *obj_buf, size_t obj_buf_sz) +{ + struct bpf_object *obj; + + obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, "[buffer]"); + if (IS_ERR(obj)) { + fprintf(stderr, " (compile failed)"); + return NULL; + } + return obj; +} + +static int do_test(struct bpf_object *obj) +{ + struct record_opts opts = { + .target = { + .uid = UINT_MAX, + .uses_mmap = true, + }, + .freq = 0, + .mmap_pages = 256, + .default_interval = 1, + }; + + int i, err = 0, count = 0; + char pid[16]; + char sbuf[STRERR_BUFSIZE]; + struct perf_evlist *evlist; + + struct parse_events_evlist parse_evlist; + struct parse_events_error parse_error; + + bzero(&parse_error, sizeof(parse_error)); + bzero(&parse_evlist, sizeof(parse_evlist)); + parse_evlist.error = &parse_error; + INIT_LIST_HEAD(&parse_evlist.list); + + err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj); + if (err || list_empty(&parse_evlist.list)) { + fprintf(stderr, " (Failed to add events selected by BPF)"); + if (!err) + err = -EINVAL; + goto out; + } + + snprintf(pid, sizeof(pid), "%d", getpid()); + pid[sizeof(pid) - 1] = '\0'; + opts.target.tid = opts.target.pid = pid; + + /* Instead of perf_evlist__new_default, don't add default events */ + evlist = perf_evlist__new(); + if (!evlist) { + pr_debug("No ehough memory to create evlist\n"); + return -ENOMEM; + } + + err = perf_evlist__create_maps(evlist, &opts.target); + if (err < 0) { + pr_debug("Not enough memory to create thread/cpu maps\n"); + goto out_delete_evlist; + } + + perf_evlist__splice_list_tail(evlist, &parse_evlist.list); + evlist->nr_groups = parse_evlist.nr_groups; + + perf_evlist__config(evlist, &opts); + + err = perf_evlist__open(evlist); + if (err < 0) { + pr_debug("perf_evlist__open: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); + goto out_delete_evlist; + } + + err = perf_evlist__mmap(evlist, opts.mmap_pages, false); + if (err < 0) { + pr_debug("perf_evlist__mmap: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); + goto out_delete_evlist; + } + + perf_evlist__enable(evlist); + epoll_pwait_loop(); + perf_evlist__disable(evlist); + + for (i = 0; i < evlist->nr_mmaps; i++) { + union perf_event *event; + + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { + const u32 type = event->header.type; + + if (type == PERF_RECORD_SAMPLE) + count ++; + } + } + + if (count != (NR_ITERS + 1) / 2) { + fprintf(stderr, " (filter result incorrect)"); + err = -EBADF; + } + +out_delete_evlist: + perf_evlist__delete(evlist); +out: + if (err) + return TEST_FAIL; + return 0; +} + +int test__bpf(void) +{ + int err; + void *obj_buf; + size_t obj_buf_sz; + struct bpf_object *obj; + + if (geteuid() != 0) { + fprintf(stderr, " (try run as root)"); + return TEST_SKIP; + } + + test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz); + if (!obj_buf || !obj_buf_sz) { + if (verbose == 0) + fprintf(stderr, " (fix 'perf test LLVM' first)"); + return TEST_SKIP; + } + + obj = prepare_bpf(obj_buf, obj_buf_sz); + if (!obj) { + err = -EINVAL; + goto out; + } + + err = do_test(obj); + if (err) + goto out; +out: + bpf__clear(); + if (err) + return TEST_FAIL; + return 0; +} + +#else +int test__bpf(void) +{ + return TEST_SKIP; +} +#endif diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 09f3eb8..2cb19fe 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -195,6 +195,10 @@ static struct test { .func = test_session_topology, }, { + .desc = "Test BPF filter", + .func = test__bpf, + }, + { .func = NULL, }, }; diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 236bf39..fd5fdb0 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -174,3 +174,22 @@ void test__llvm_cleanup(void) (~((unsigned long)page_size - 1)); munmap((void *)boundary, buf_end - boundary); } + +void +test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz) +{ + *p_obj_buf = NULL; + *p_obj_buf_sz = 0; + + if (!p_test_llvm__bpf_result) { + test__llvm_prepare(); + test__llvm(); + test__llvm_cleanup(); + } + + if (!p_test_llvm__bpf_result) + return; + + *p_obj_buf = p_test_llvm__bpf_result->object; + *p_obj_buf_sz = p_test_llvm__bpf_result->size; +} diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h index 1e89e46..2fd7ed6 100644 --- a/tools/perf/tests/llvm.h +++ b/tools/perf/tests/llvm.h @@ -10,5 +10,6 @@ struct test_llvm__bpf_result { extern struct test_llvm__bpf_result *p_test_llvm__bpf_result; extern const char test_llvm__bpf_prog[]; +void test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz); #endif diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index a5e6f641..b413f08 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -65,6 +65,7 @@ int test__thread_map(void); int test__llvm(void); void test__llvm_prepare(void); void test__llvm_cleanup(void); +int test__bpf(void); int test__insn_x86(void); int test_session_topology(void); diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 286d3a9..578292c 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -34,6 +34,20 @@ struct bpf_prog_priv { struct perf_probe_event pev; }; +struct bpf_object * +bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) +{ + struct bpf_object *obj; + + obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name); + if (!obj) { + pr_debug("bpf: failed to load buffer\n"); + return ERR_PTR(-EINVAL); + } + + return obj; +} + struct bpf_object *bpf__prepare_load(const char *filename, bool source) { struct bpf_object *obj; diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index fc6eb24..bdbd09c 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -19,6 +19,8 @@ typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev, #ifdef HAVE_LIBBPF_SUPPORT struct bpf_object *bpf__prepare_load(const char *filename, bool source); +struct bpf_object *bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, + const char *name); void bpf__clear(void); @@ -42,6 +44,13 @@ bpf__prepare_load(const char *filename __maybe_unused, return ERR_PTR(-ENOTSUP); } +static inline struct bpf_object * +bpf__prepare_load_buffer(void *obj_buf __maybe_unused, + size_t obj_buf_sz __maybe_unused) +{ + return ERR_PTR(-ENOTSUP); +} + static inline void bpf__clear(void) { } static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;}