Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752468AbcDTSCj (ORCPT ); Wed, 20 Apr 2016 14:02:39 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:22023 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752281AbcDTSCg (ORCPT ); Wed, 20 Apr 2016 14:02:36 -0400 From: Wang Nan To: , , CC: , , Wang Nan , Arnaldo Carvalho de Melo , "Alexei Starovoitov" , Jiri Olsa , Li Zefan Subject: [RFC PATCH 13/13] perf tests: Add UBPF test case Date: Wed, 20 Apr 2016 18:01:53 +0000 Message-ID: <1461175313-38310-14-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1461175313-38310-1-git-send-email-wangnan0@huawei.com> References: <1461175313-38310-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 X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090202.5717C42B.0170,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: aeddd6ec410b7b5d94ec56c7508cae48 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8513 Lines: 313 Introduce a BPF script use UBPF, test compiling, helper and hook. Validate passing information through helper and hooks. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: Jiri Olsa Cc: Li Zefan --- tools/perf/tests/Build | 8 ++++ tools/perf/tests/bpf-script-test-ubpf.c | 68 +++++++++++++++++++++++++++++ tools/perf/tests/bpf.c | 77 ++++++++++++++++++++++++++++++++- tools/perf/tests/llvm.c | 4 ++ tools/perf/tests/llvm.h | 2 + 5 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 tools/perf/tests/bpf-script-test-ubpf.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 449fe97..0050ff8 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -32,6 +32,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-base.o llvm-src-kbuild.o llvm-src-prologue.o llvm-src-relocation.o +perf-y += llvm-src-ubpf.o perf-y += bpf.o perf-y += topology.o perf-y += cpumap.o @@ -67,6 +68,13 @@ $(OUTPUT)tests/llvm-src-relocation.c: tests/bpf-script-test-relocation.c tests/B $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ $(Q)echo ';' >> $@ +$(OUTPUT)tests/llvm-src-ubpf.c: tests/bpf-script-test-ubpf.c tests/Build + $(call rule_mkdir) + $(Q)echo '#include ' > $@ + $(Q)echo 'const char test_llvm__bpf_test_ubpf[] =' >> $@ + $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ + $(Q)echo ';' >> $@ + ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o endif diff --git a/tools/perf/tests/bpf-script-test-ubpf.c b/tools/perf/tests/bpf-script-test-ubpf.c new file mode 100644 index 0000000..67000d5 --- /dev/null +++ b/tools/perf/tests/bpf-script-test-ubpf.c @@ -0,0 +1,68 @@ +/* + * bpf-script-test-ubpf.c + * Test user space BPF + */ + +#ifndef LINUX_VERSION_CODE +# error Need LINUX_VERSION_CODE +# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' +#endif +#define BPF_ANY 0 +#define BPF_MAP_TYPE_ARRAY 2 +#define BPF_FUNC_map_lookup_elem 1 +#define BPF_FUNC_map_update_elem 2 + +static void *(*bpf_map_lookup_elem)(void *map, void *key) = + (void *) BPF_FUNC_map_lookup_elem; +static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = + (void *) BPF_FUNC_map_update_elem; + +struct bpf_map_def { + unsigned int type; + unsigned int key_size; + unsigned int value_size; + unsigned int max_entries; +}; + +#define SEC(NAME) __attribute__((section(NAME), used)) +struct bpf_map_def SEC("maps") counter = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(int), + .max_entries = 1, +}; + +SEC("func=sys_epoll_pwait") +int bpf_func__sys_epoll_pwait(void *ctx) +{ + int ind = 0; + int *flag = bpf_map_lookup_elem(&counter, &ind); + if (!flag) + return 0; + __sync_fetch_and_add(flag, 1); + return 0; +} +char _license[] SEC("license") = "GPL"; +int _version SEC("version") = LINUX_VERSION_CODE; + +static void (*ubpf_map_lookup_elem)(struct bpf_map_def *, void *, void *) = (void *)2; +static void (*ubpf_map_update_elem)(struct bpf_map_def *, void *, void *) = (void *)3; +static void (*ubpf_test_report)(int) = (void *)63; +SEC("UBPF;perf_record_start") +int perf_record_start(void) +{ + int idx = 0, val = 1000; + + ubpf_map_update_elem(&counter, &idx, &val); + return 0; +} + +SEC("UBPF;perf_record_end") +int perf_record_end(int *x) +{ + int idx = 0, val; + + ubpf_map_lookup_elem(&counter, &idx, &val); + ubpf_test_report(val + *x); + return 0; +} diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index f31eed3..2841718 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -5,10 +5,13 @@ #include #include #include +#include #include #include "tests.h" #include "llvm.h" #include "debug.h" +#include "ubpf-helpers.h" +#include "ubpf-hooks.h" #define NR_ITERS 111 #ifdef HAVE_LIBBPF_SUPPORT @@ -46,6 +49,34 @@ static int llseek_loop(void) #endif +union testcase_context { + void *ptr; + unsigned long num; +}; + +#ifdef HAVE_UBPF_SUPPORT +static int __ubpf_report_val; + +static void test_report(int val) +{ + __ubpf_report_val = val; +} + +static int ubpf_prepare(union testcase_context *ctx __maybe_unused) +{ + ubpf_hook_perf_record_start(0); + return 0; +} + +static int ubpf_verify(union testcase_context *ctx __maybe_unused) +{ + ubpf_hook_perf_record_end(0, 1234); + if (__ubpf_report_val != 2345) + return TEST_FAIL; + return TEST_OK; +} +#endif + static struct { enum test_llvm__testcase prog_id; const char *desc; @@ -54,6 +85,10 @@ static struct { const char *msg_load_fail; int (*target_func)(void); int expect_result; + + union testcase_context context; + int (*prepare)(union testcase_context *); + int (*verify)(union testcase_context *); } bpf_testcase_table[] = { { LLVM_TESTCASE_BASE, @@ -63,6 +98,7 @@ static struct { "load bpf object failed", &epoll_pwait_loop, (NR_ITERS + 1) / 2, + {0}, NULL, NULL }, #ifdef HAVE_BPF_PROLOGUE { @@ -73,6 +109,7 @@ static struct { "check your vmlinux setting?", &llseek_loop, (NR_ITERS + 1) / 4, + {0}, NULL, NULL }, #endif { @@ -83,11 +120,27 @@ static struct { "libbpf error when dealing with relocation", NULL, 0, + {0}, NULL, NULL }, +#ifdef HAVE_UBPF_SUPPORT + { + LLVM_TESTCASE_BPF_UBPF, + "Test UBPF support", + "[bpf_ubpf_test]", + "fix 'perf test LLVM' first", + "failed to load UBPF", + &epoll_pwait_loop, + 0, + {0}, ubpf_prepare, ubpf_verify, + } +#endif }; static int do_test(struct bpf_object *obj, int (*func)(void), - int expect) + int expect, + int (*prepare)(union testcase_context *), + int (*verify)(union testcase_context *), + union testcase_context *ctx) { struct record_opts opts = { .target = { @@ -154,6 +207,14 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } + if (prepare) { + err = prepare(ctx); + if (err < 0) { + pr_debug("prepare fail\n"); + goto out_delete_evlist; + } + } + perf_evlist__enable(evlist); (*func)(); perf_evlist__disable(evlist); @@ -176,6 +237,8 @@ static int do_test(struct bpf_object *obj, int (*func)(void), ret = TEST_OK; + if (verify) + ret = verify(ctx); out_delete_evlist: perf_evlist__delete(evlist); return ret; @@ -201,6 +264,13 @@ static int __test__bpf(int idx) size_t obj_buf_sz; struct bpf_object *obj; +#ifdef HAVE_UBPF_SUPPORT + ret = libbpf_register_ubpf_func(63, "test_report", test_report); + if (ret) { + pr_debug("Unable to register UBPF helper\n"); + return TEST_FAIL; + } +#endif ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, bpf_testcase_table[idx].prog_id, true, NULL); @@ -229,7 +299,10 @@ static int __test__bpf(int idx) if (obj) ret = do_test(obj, bpf_testcase_table[idx].target_func, - bpf_testcase_table[idx].expect_result); + bpf_testcase_table[idx].expect_result, + bpf_testcase_table[idx].prepare, + bpf_testcase_table[idx].verify, + &bpf_testcase_table[idx].context); out: bpf__clear(); return ret; diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index cff564f..92b0a42 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -48,6 +48,10 @@ static struct { .desc = "Compile source for BPF relocation test", .should_load_fail = true, }, + [LLVM_TESTCASE_BPF_UBPF] = { + .source = test_llvm__bpf_test_ubpf, + .desc = "Compile source for UBPF test", + }, }; int diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h index 0eaa604..8ae4aae 100644 --- a/tools/perf/tests/llvm.h +++ b/tools/perf/tests/llvm.h @@ -8,12 +8,14 @@ extern const char test_llvm__bpf_base_prog[]; extern const char test_llvm__bpf_test_kbuild_prog[]; extern const char test_llvm__bpf_test_prologue_prog[]; extern const char test_llvm__bpf_test_relocation[]; +extern const char test_llvm__bpf_test_ubpf[]; enum test_llvm__testcase { LLVM_TESTCASE_BASE, LLVM_TESTCASE_KBUILD, LLVM_TESTCASE_BPF_PROLOGUE, LLVM_TESTCASE_BPF_RELOCATION, + LLVM_TESTCASE_BPF_UBPF, __LLVM_TESTCASE_MAX, }; -- 1.8.3.4