From patchwork Fri Sep 23 12:49:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 76850 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp552502qgf; Fri, 23 Sep 2016 05:51:23 -0700 (PDT) X-Received: by 10.66.62.232 with SMTP id b8mr348416pas.38.1474635083844; Fri, 23 Sep 2016 05:51:23 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s64si7802262pfg.294.2016.09.23.05.51.23; Fri, 23 Sep 2016 05:51:23 -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 S1030223AbcIWMvM (ORCPT + 27 others); Fri, 23 Sep 2016 08:51:12 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:19007 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759615AbcIWMvH (ORCPT ); Fri, 23 Sep 2016 08:51:07 -0400 Received: from 172.24.1.137 (EHLO szxeml431-hub.china.huawei.com) ([172.24.1.137]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DRL70284; Fri, 23 Sep 2016 20:50:26 +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; Fri, 23 Sep 2016 20:50:14 +0800 From: Wang Nan To: , CC: , , , Wang Nan , Arnaldo Carvalho de Melo , He Kuang , Jiri Olsa Subject: [PATCH 12/14] perf bpf: Compile BPF script use builtin cflags support Date: Fri, 23 Sep 2016 12:49:59 +0000 Message-ID: <1474635001-153850-13-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1474635001-153850-1-git-send-email-wangnan0@huawei.com> References: <1474635001-153850-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.0A020204.57E52512.021A, 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: 3f88707faf17cf80b17be3435ecbea08 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org After this patch, perf utilizes builtin cflags support to build BPF script, no longer depend on external clang. Test: $ type clang -bash: type: clang: not found $ cat ~/.perfconfig $ echo '#define LINUX_VERSION_CODE 0x040700' > ./test.c $ cat ./tools/perf/tests/bpf-script-example.c >> ./test.c $ ./perf record -v --dry-run -e ./test.c 2>&1 | grep builtin bpf: builtin compiling successful Can't pass cflags so unable to include kernel headers now. Will be fixed by following commits. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: He Kuang Cc: Jiri Olsa --- tools/perf/util/bpf-loader.c | 15 +++++++++++---- tools/perf/util/c++/clang-c.h | 26 ++++++++++++++++++++++++++ tools/perf/util/c++/clang.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) -- 1.8.3.4 diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 2b2c9b8..a5ddb8e 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -14,11 +14,11 @@ #include "debug.h" #include "bpf-loader.h" #include "bpf-prologue.h" -#include "llvm-utils.h" #include "probe-event.h" #include "probe-finder.h" // for MAX_PROBES #include "parse-events.h" #include "llvm-utils.h" +#include "c++/clang-c.h" #define DEFINE_PRINT_FN(name, level) \ static int libbpf_##name(const char *fmt, ...) \ @@ -86,9 +86,16 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source) void *obj_buf; size_t obj_buf_sz; - err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz); - if (err) - return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); + perf_clang__init(); + err = perf_clang__compile_bpf(filename, &obj_buf, &obj_buf_sz); + perf_clang__cleanup(); + if (err) { + pr_debug("bpf: builtin compiling failed: %d, try external compiler\n", err); + err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz); + if (err) + return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); + } else + pr_debug("bpf: builtin compiling successful\n"); obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); free(obj_buf); } else diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h index 22b3936..0eadd79 100644 --- a/tools/perf/util/c++/clang-c.h +++ b/tools/perf/util/c++/clang-c.h @@ -1,16 +1,42 @@ #ifndef PERF_UTIL_CLANG_C_H #define PERF_UTIL_CLANG_C_H +#include /* for size_t */ +#include /* for __maybe_unused */ + #ifdef __cplusplus extern "C" { #endif +#ifdef HAVE_LIBCLANGLLVM_SUPPORT extern void perf_clang__init(void); extern void perf_clang__cleanup(void); extern int test__clang_to_IR(void); extern int test__clang_to_obj(void); +extern int perf_clang__compile_bpf(const char *filename, + void **p_obj_buf, + size_t *p_obj_buf_sz); +#else + + +static inline void perf_clang__init(void) { } +static inline void perf_clang__cleanup(void) { } + +static inline int test__clang_to_IR(void) { return -1; } +static inline int test__clang_to_obj(void) { return -1;} + +static inline int +perf_clang__compile_bpf(const char *filename __maybe_unused, + void **p_obj_buf __maybe_unused, + size_t *p_obj_buf_sz __maybe_unused) +{ + return -ENOTSUP; +} + +#endif + #ifdef __cplusplus } #endif diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index 38dcc14..010b91e 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp @@ -163,4 +163,33 @@ void perf_clang__cleanup(void) perf::LLVMCtx.reset(nullptr); llvm::llvm_shutdown(); } + +int perf_clang__compile_bpf(const char *filename, + void **p_obj_buf, + size_t *p_obj_buf_sz) +{ + using namespace perf; + + if (!p_obj_buf || !p_obj_buf_sz) + return -EINVAL; + + llvm::opt::ArgStringList CFlags; + auto M = getModuleFromSource(std::move(CFlags), filename); + if (!M) + return -EINVAL; + auto O = getBPFObjectFromModule(&*M); + if (!O) + return -EINVAL; + + size_t size = O->size_in_bytes(); + void *buffer; + + buffer = malloc(size); + if (!buffer) + return -ENOMEM; + memcpy(buffer, O->data(), size); + *p_obj_buf = buffer; + *p_obj_buf_sz = size; + return 0; +} }