From patchwork Sun Jun 26 11:21:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: He Kuang X-Patchwork-Id: 70879 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp615532qgy; Sun, 26 Jun 2016 04:22:45 -0700 (PDT) X-Received: by 10.98.131.206 with SMTP id h197mr23479502pfe.124.1466940165026; Sun, 26 Jun 2016 04:22:45 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z125si5052483pfz.64.2016.06.26.04.22.44; Sun, 26 Jun 2016 04:22:45 -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 S1752692AbcFZLWd (ORCPT + 30 others); Sun, 26 Jun 2016 07:22:33 -0400 Received: from szxga04-in.huawei.com ([58.251.152.52]:22562 "EHLO szxga04-in.huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752422AbcFZLWS (ORCPT ); Sun, 26 Jun 2016 07:22:18 -0400 Received: from 172.24.1.46 (EHLO lggeml424-hub.china.huawei.com) ([172.24.1.46]) by szxrg04-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id BSN99645; Sun, 26 Jun 2016 19:11:09 +0800 (CST) Received: from euler.hulk-profiling (10.107.193.250) by lggeml424-hub.china.huawei.com (10.72.61.34) with Microsoft SMTP Server id 14.3.235.1; Sun, 26 Jun 2016 19:21:45 +0800 From: He Kuang To: , , , , , , , , CC: Subject: [RFC PATCH v2 26/26] perf tests: Add uBPF test case Date: Sun, 26 Jun 2016 11:21:18 +0000 Message-ID: <1466940078-65581-27-git-send-email-hekuang@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1466940078-65581-1-git-send-email-hekuang@huawei.com> References: <1466940078-65581-1-git-send-email-hekuang@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.250] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090204.576FBADB.007F, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: fcd9ee1afc76b0d44019af1896390249 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wang Nan Introduce a BPF script use uBPF, test compiling, helper and hook. Validate passing information through helper and hooks. Signed-off-by: Wang Nan Signed-off-by: He Kuang --- tools/perf/tests/Build | 8 +++ tools/perf/tests/bpf-script-test-ubpf.c | 88 +++++++++++++++++++++++++++++++++ tools/perf/tests/bpf.c | 78 ++++++++++++++++++++++++++++- tools/perf/tests/llvm.c | 4 ++ tools/perf/tests/llvm.h | 2 + 5 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 tools/perf/tests/bpf-script-test-ubpf.c -- 1.8.5.2 diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 66a2898..74da237 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 @@ -68,6 +69,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..5064ee9 --- /dev/null +++ b/tools/perf/tests/bpf-script-test-ubpf.c @@ -0,0 +1,88 @@ +/* + * 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)) +SEC("maps") +struct bpf_map_def 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; + +#define UBPF_FUNC_printf 4 +#define UBPF_FUNC_map_lookup_elem 5 +#define UBPF_FUNC_map_update_elem 6 +#define UBPF_FUNC_test_report 63 + +static int (*ubpf_printf)(char *fmt, ...) = (void *)UBPF_FUNC_printf; +static void +(*ubpf_map_lookup_elem)(struct bpf_map_def *, void *, void *) = + (void *)UBPF_FUNC_map_lookup_elem; +static void +(*ubpf_map_update_elem)(struct bpf_map_def *, void *, void *, int flags) = + (void *)UBPF_FUNC_map_update_elem; +static void (*ubpf_test_report)(int) = (void *)UBPF_FUNC_test_report; + +struct perf_record_end_ctx { + int samples; + int dummy; +}; + +SEC("UBPF;perf_record_start") +int perf_record_start(void) +{ + int idx = 0, val = 1000; + + ubpf_map_update_elem(&counter, &idx, &val, 0); + return 0; +} + +SEC("UBPF;perf_record_end") +int perf_record_end(struct perf_record_end_ctx *ctx) +{ + int idx = 0, val; + + ubpf_map_lookup_elem(&counter, &idx, &val); + ubpf_test_report(val + ctx->samples); + + return 0; +} diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index f31eed3..0c094e6 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,35 @@ 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) +{ + printf("test_report val = %d\n", 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(1234, 0); + if (__ubpf_report_val != 1234 + NR_ITERS + 1000) + return TEST_FAIL; + return TEST_OK; +} +#endif + static struct { enum test_llvm__testcase prog_id; const char *desc; @@ -54,6 +86,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 +99,7 @@ static struct { "load bpf object failed", &epoll_pwait_loop, (NR_ITERS + 1) / 2, + {0}, NULL, NULL }, #ifdef HAVE_BPF_PROLOGUE { @@ -73,6 +110,7 @@ static struct { "check your vmlinux setting?", &llseek_loop, (NR_ITERS + 1) / 4, + {0}, NULL, NULL }, #endif { @@ -83,11 +121,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 +208,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 +238,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 +265,13 @@ static int __test__bpf(int idx) size_t obj_buf_sz; struct bpf_object *obj; +#ifdef HAVE_UBPF_SUPPORT + ret = libbpf_set_ubpf_func(63, "test_report", test_report); + if (ret) { + pr_debug("Unable to set UBPF helper function\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 +300,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, };