From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965552AbbKEE1c (ORCPT ); Wed, 4 Nov 2015 23:27:32 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:55078 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965425AbbKEE13 (ORCPT ); Wed, 4 Nov 2015 23:27:29 -0500 From: Wang Nan To: , CC: , , , Wang Nan , He Kuang , "Arnaldo Carvalho de Melo" Subject: [PATCH 3/5] perf test: Enforce LLVM test: update basic BPF test program Date: Thu, 5 Nov 2015 04:27:00 +0000 Message-ID: <1446697622-4072-4-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1446697622-4072-1-git-send-email-wangnan0@huawei.com> References: <1446697622-4072-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.0A020204.563ADAA7.0015,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: 0c1b21f7a177171204f695830c49bf60 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch replaces the original toy BPF program with previous introduced bpf-script-example.c. Dynamically embedded it into 'llvm-src-base.c'. The newly introduced BPF program attaches a BPF program to 'sys_epoll_pwait()'. perf itself never use that syscall, so further test can verify their result with it. The program would generate 1 sample in every 2 calls of epoll_pwait() system call. Since the resuling BPF object is useful, test_llvm__fetch_bpf_obj() is introduced for creating BPF objects for source. llvm test is rewritten according to it. Signed-off-by: He Kuang Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com --- tools/perf/tests/Build | 9 ++- tools/perf/tests/bpf-script-example.c | 4 ++ tools/perf/tests/llvm.c | 131 ++++++++++++++++++++++++++-------- tools/perf/tests/llvm.h | 16 +++++ 4 files changed, 129 insertions(+), 31 deletions(-) create mode 100644 tools/perf/tests/llvm.h diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 50de225..6c095b3 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -31,9 +31,16 @@ perf-y += sample-parsing.o perf-y += parse-no-sample-id-all.o perf-y += kmod-path.o perf-y += thread-map.o -perf-y += llvm.o +perf-y += llvm.o llvm-src-base.o perf-y += topology.o +$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c + $(call rule_mkdir) + $(Q)echo '#include ' > $@ + $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@ + $(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-example.c b/tools/perf/tests/bpf-script-example.c index 410a70b..0ec9c2c 100644 --- a/tools/perf/tests/bpf-script-example.c +++ b/tools/perf/tests/bpf-script-example.c @@ -1,3 +1,7 @@ +/* + * bpf-script-example.c + * Test basic LLVM building + */ #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' diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 8f713f6..05683c5 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -2,6 +2,7 @@ #include #include #include +#include "llvm.h" #include "tests.h" #include "debug.h" @@ -11,16 +12,6 @@ static int perf_config_cb(const char *var, const char *val, return perf_default_config(var, val, arg); } -/* - * Randomly give it a "version" section since we don't really load it - * into kernel - */ -static const char test_bpf_prog[] = - "__attribute__((section(\"do_fork\"), used)) " - "int fork(void *ctx) {return 0;} " - "char _license[] __attribute__((section(\"license\"), used)) = \"GPL\";" - "int _version __attribute__((section(\"version\"), used)) = 0x40100;"; - #ifdef HAVE_LIBBPF_SUPPORT static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) { @@ -28,25 +19,47 @@ static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL); if (IS_ERR(obj)) - return -1; + return TEST_FAIL; bpf_object__close(obj); - return 0; + return TEST_OK; } #else static int test__bpf_parsing(void *obj_buf __maybe_unused, size_t obj_buf_sz __maybe_unused) { pr_debug("Skip bpf parsing\n"); - return 0; + return TEST_OK; } #endif -int test__llvm(void) +static struct { + const char *source; + const char *desc; +} bpf_source_table[__LLVM_TESTCASE_MAX] = { + [LLVM_TESTCASE_BASE] = { + .source = test_llvm__bpf_base_prog, + .desc = "Basic BPF llvm compiling test", + }, +}; + + +int +test_llvm__fetch_bpf_obj(void **p_obj_buf, + size_t *p_obj_buf_sz, + enum test_llvm__testcase index, + bool force) { - char *tmpl_new, *clang_opt_new; - void *obj_buf; - size_t obj_buf_sz; - int err, old_verbose; + const char *source; + const char *desc; + const char *tmpl_old, *clang_opt_old; + char *tmpl_new = NULL, *clang_opt_new = NULL; + int err, old_verbose, ret = TEST_FAIL; + + if (index >= __LLVM_TESTCASE_MAX) + return TEST_FAIL; + + source = bpf_source_table[index].source; + desc = bpf_source_table[index].desc; perf_config(perf_config_cb, NULL); @@ -54,42 +67,100 @@ int test__llvm(void) * Skip this test if user's .perfconfig doesn't set [llvm] section * and clang is not found in $PATH, and this is not perf test -v */ - if (verbose == 0 && !llvm_param.user_set_param && llvm__search_clang()) { + if (!force && (verbose == 0 && + !llvm_param.user_set_param && + llvm__search_clang())) { pr_debug("No clang and no verbosive, skip this test\n"); return TEST_SKIP; } - old_verbose = verbose; /* * llvm is verbosity when error. Suppress all error output if * not 'perf test -v'. */ + old_verbose = verbose; if (verbose == 0) verbose = -1; + *p_obj_buf = NULL; + *p_obj_buf_sz = 0; + if (!llvm_param.clang_bpf_cmd_template) - return -1; + goto out; if (!llvm_param.clang_opt) llvm_param.clang_opt = strdup(""); - err = asprintf(&tmpl_new, "echo '%s' | %s", test_bpf_prog, - llvm_param.clang_bpf_cmd_template); + err = asprintf(&tmpl_new, "echo '%s' | %s%s", source, + llvm_param.clang_bpf_cmd_template, + old_verbose ? "" : " 2>/dev/null"); if (err < 0) - return -1; + goto out; err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt); if (err < 0) - return -1; + goto out; + tmpl_old = llvm_param.clang_bpf_cmd_template; llvm_param.clang_bpf_cmd_template = tmpl_new; + clang_opt_old = llvm_param.clang_opt; llvm_param.clang_opt = clang_opt_new; - err = llvm__compile_bpf("-", &obj_buf, &obj_buf_sz); + + err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz); + + llvm_param.clang_bpf_cmd_template = tmpl_old; + llvm_param.clang_opt = clang_opt_old; verbose = old_verbose; if (err) - return TEST_FAIL; + goto out; + + ret = TEST_OK; +out: + free(tmpl_new); + free(clang_opt_new); + if (ret != TEST_OK) + pr_debug("Failed to compile test case: '%s'\n", desc); + return ret; +} - err = test__bpf_parsing(obj_buf, obj_buf_sz); - free(obj_buf); - return err; +int test__llvm(void) +{ + enum test_llvm__testcase i; + + for (i = 0; i < __LLVM_TESTCASE_MAX; i++) { + int ret; + void *obj_buf = NULL; + size_t obj_buf_sz = 0; + + ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, + i, false); + + if (ret == TEST_OK) { + ret = test__bpf_parsing(obj_buf, obj_buf_sz); + if (ret != TEST_OK) + pr_debug("Failed to parse test case '%s'\n", + bpf_source_table[i].desc); + } + free(obj_buf); + + switch (ret) { + case TEST_SKIP: + return TEST_SKIP; + case TEST_OK: + break; + default: + /* + * Test 0 is the basic LLVM test. If test 0 + * fail, the basic LLVM support not functional + * so the whole test should fail. If other test + * case fail, it can be fixed by adjusting + * config so don't report error. + */ + if (i == 0) + return TEST_FAIL; + else + return TEST_SKIP; + } + } + return TEST_OK; } diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h new file mode 100644 index 0000000..bd63cee --- /dev/null +++ b/tools/perf/tests/llvm.h @@ -0,0 +1,16 @@ +#ifndef PERF_TEST_LLVM_H +#define PERF_TEST_LLVM_H + +#include /* for size_t */ +#include /* for bool */ + +extern const char test_llvm__bpf_base_prog[]; + +enum test_llvm__testcase { + LLVM_TESTCASE_BASE, + __LLVM_TESTCASE_MAX, +}; + +int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz, + enum test_llvm__testcase index, bool force); +#endif -- 1.8.3.4