From patchwork Sat Aug 29 04:21:52 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 52843 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by patches.linaro.org (Postfix) with ESMTPS id A69B320503 for ; Sat, 29 Aug 2015 04:29:45 +0000 (UTC) Received: by wicne3 with SMTP id ne3sf13875601wic.1 for ; Fri, 28 Aug 2015 21:29:45 -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=xv+Wf2gmyz4NVrr0kSXoi0LnOgHH3kaBM1N+rq0aND4=; b=MEwsRddDJzhQnOtPPBnwqDFeCwe3bEGKIhwYJZXv2BEhhhesWlNsvkDkTW41FB5YVv K6GQ4/E7MDHVSFPERnJkA+lsr8sMf0vOPOARapPo0UnJ0um1ikcvFp+YaDV8rfF4cgmm IA+L26muEDH2Z6k1TXwq17b8x0nPCxSAI9PCFjopQ6xdquIdTr4eiKPsav+PqHtNUjdf hcPzk54gZNfoEHyo1HA6/2u55DySoXJE8q6QkfPaaR3szO85OwPOP8lyI6MjSGM1yw5n F8TG/aYMtKkugXA8guXpC9HdoPWoTA9kzFE1zVW9pgmrVvOH/4CmfLhRBQraVjm8Z5wO 0edQ== X-Gm-Message-State: ALoCoQkhjN16pyKUglwt4tPXHcL4A1B/gdR4KTDhzw1h11YUsYc+/Vnpc3TkC2c5ys8EAJfNpC/5 X-Received: by 10.194.115.135 with SMTP id jo7mr3547157wjb.7.1440822585011; Fri, 28 Aug 2015 21:29:45 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.29.133 with SMTP id k5ls271485lah.42.gmail; Fri, 28 Aug 2015 21:29:44 -0700 (PDT) X-Received: by 10.152.203.203 with SMTP id ks11mr459730lac.22.1440822584826; Fri, 28 Aug 2015 21:29:44 -0700 (PDT) Received: from mail-la0-f54.google.com (mail-la0-f54.google.com. [209.85.215.54]) by mx.google.com with ESMTPS id l7si239577lbd.125.2015.08.28.21.29.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2015 21:29:44 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.54 as permitted sender) client-ip=209.85.215.54; Received: by lanb10 with SMTP id b10so8393820lan.2 for ; Fri, 28 Aug 2015 21:29:44 -0700 (PDT) X-Received: by 10.112.219.70 with SMTP id pm6mr6070480lbc.41.1440822584646; Fri, 28 Aug 2015 21:29:44 -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.151.194 with SMTP id us2csp269172lbb; Fri, 28 Aug 2015 21:29:43 -0700 (PDT) X-Received: by 10.68.190.38 with SMTP id gn6mr20538081pbc.125.1440822583275; Fri, 28 Aug 2015 21:29:43 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bi11si13357359pdb.163.2015.08.28.21.29.38; Fri, 28 Aug 2015 21:29:43 -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 S1753396AbbH2E3a (ORCPT + 28 others); Sat, 29 Aug 2015 00:29:30 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:39761 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752453AbbH2EXn (ORCPT ); Sat, 29 Aug 2015 00:23:43 -0400 Received: from 172.24.1.47 (EHLO szxeml431-hub.china.huawei.com) ([172.24.1.47]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id CTY94471; Sat, 29 Aug 2015 12:23:17 +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; Sat, 29 Aug 2015 12:23:10 +0800 From: Wang Nan To: , , CC: , , , Wang Nan , Brendan Gregg , Daniel Borkmann , David Ahern , "He Kuang" , Jiri Olsa , Kaixu Xia , Masami Hiramatsu , Namhyung Kim , Peter Zijlstra Subject: [PATCH 18/31] perf test: Add 'perf test BPF' Date: Sat, 29 Aug 2015 04:21:52 +0000 Message-ID: <1440822125-52691-19-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1440822125-52691-1-git-send-email-wangnan0@huawei.com> References: <1440822125-52691-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected 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.54 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/1440151770-129878-16-git-send-email-wangnan0@huawei.com --- tools/perf/tests/Build | 1 + tools/perf/tests/bpf.c | 170 ++++++++++++++++++++++++++++++++++++++++ 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 | 8 ++ 8 files changed, 218 insertions(+) create mode 100644 tools/perf/tests/bpf.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 8c98409..7ceb448 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 $(OUTPUT)tests/llvm-src.c: tests/bpf-script-example.c $(Q)echo '#include ' > $@ diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c new file mode 100644 index 0000000..6c238ca --- /dev/null +++ b/tools/perf/tests/bpf.c @@ -0,0 +1,170 @@ +#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 int prepare_bpf(void *obj_buf, size_t obj_buf_sz) +{ + int err; + char errbuf[BUFSIZ]; + + err = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, NULL); + if (err) { + bpf__strerror_prepare_load("[buffer]", false, err, errbuf, + sizeof(errbuf)); + fprintf(stderr, " (%s)", errbuf); + return TEST_FAIL; + } + + err = bpf__probe(); + if (err) { + bpf__strerror_load(err, errbuf, sizeof(errbuf)); + fprintf(stderr, " (%s)", errbuf); + if (getuid() != 0) + fprintf(stderr, " (try run as root)"); + return TEST_FAIL; + } + + err = bpf__load(); + if (err) { + bpf__strerror_load(err, errbuf, sizeof(errbuf)); + fprintf(stderr, " (%s)", errbuf); + return TEST_FAIL; + } + + return 0; +} + +static int do_test(void) +{ + struct record_opts opts = { + .target = { + .uid = UINT_MAX, + .uses_mmap = true, + }, + .freq = 0, + .mmap_pages = 256, + .default_interval = 1, + }; + + int err, i, count = 0; + char pid[16]; + char sbuf[STRERR_BUFSIZE]; + struct perf_evlist *evlist; + + 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; + } + + err = perf_evlist__add_bpf(evlist); + if (err) { + fprintf(stderr, " (Failed to add events selected by BPF)"); + goto out_delete_evlist; + } + + 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); + if (err) + return TEST_FAIL; + return 0; +} + +int test__bpf(void) +{ + int err; + void *obj_buf; + size_t obj_buf_sz; + + 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; + } + + err = prepare_bpf(obj_buf, obj_buf_sz); + if (err) + goto out; + + err = do_test(); + if (err) + goto out; +out: + bpf__unprobe(); + 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 1a349e8..c32c836 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -183,6 +183,10 @@ static struct test { .cleanup = test__llvm_cleanup, }, { + .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 0d79f04..f8ded73 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); #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__) #ifdef HAVE_DWARF_UNWIND_SUPPORT diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index c2aafe2..95e529b 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -153,6 +153,20 @@ sync_bpf_program_pev(struct bpf_program *prog) return 0; } +int 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 -EINVAL; + } + + return 0; +} + int 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 97aed65..dead4d4 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 int bpf__prepare_load(const char *filename, bool source); +int bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, + const char *name); int bpf__strerror_prepare_load(const char *filename, bool source, int err, char *buf, size_t size); int bpf__probe(void); @@ -39,6 +41,12 @@ static inline int bpf__prepare_load(const char *filename __maybe_unused, return -1; } +static inline int bpf__prepare_load_buffer(void *obj_buf __maybe_unused, + size_t obj_buf_sz __maybe_unused) +{ + return bpf__prepare_load(NULL, false); +} + static inline int bpf__probe(void) { return 0; } static inline int bpf__unprobe(void) { return 0; } static inline int bpf__load(void) { return 0; }