Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934386AbbEOH4z (ORCPT ); Fri, 15 May 2015 03:56:55 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:62846 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1422789AbbEOH4u (ORCPT ); Fri, 15 May 2015 03:56:50 -0400 From: Wang Nan To: , , , , , , , , , , , CC: , , , Subject: [RFC PATCH v2 29/37] tools perf: add bpf-loader and open elf object files. Date: Fri, 15 May 2015 07:51:22 +0000 Message-ID: <1431676290-1230-30-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1431676290-1230-1-git-send-email-wangnan0@huawei.com> References: <1431676290-1230-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.200] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5477 Lines: 199 bpf_prepare_laod() is used to open each eBPF object files. The returned handlers are stored into an array. A corresponding bpf_clear() is introduced to free all resources. For the propose of logging, 3 printing functions are defined using DEFINE_PRINT_FN, which require a veprintf to process va_list args. Signed-off-by: Wang Nan --- tools/perf/builtin-bpf.c | 12 +++++++- tools/perf/util/Build | 1 + tools/perf/util/bpf-loader.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/bpf-loader.h | 13 +++++++++ tools/perf/util/debug.c | 5 ++++ tools/perf/util/debug.h | 1 + 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tools/perf/util/bpf-loader.c create mode 100644 tools/perf/util/bpf-loader.h diff --git a/tools/perf/builtin-bpf.c b/tools/perf/builtin-bpf.c index b5c613f..e922921 100644 --- a/tools/perf/builtin-bpf.c +++ b/tools/perf/builtin-bpf.c @@ -12,6 +12,7 @@ #include "perf.h" #include "debug.h" #include "parse-options.h" +#include "bpf-loader.h" typedef int (*bpf_cmd_fn_t)(int argc, const char **argv, const char *prefix); @@ -124,6 +125,7 @@ static int cmd_bpf_record(int argc, const char **argv, OPT_END() }; struct str_node *str_node; + int err; argc = parse_options(argc, argv, options, bpf_record_usage, PARSE_OPT_KEEP_DASHDASH); @@ -144,8 +146,16 @@ static int cmd_bpf_record(int argc, const char **argv, argc--; argv++; - strlist__for_each(str_node, param.object_file_names) + strlist__for_each(str_node, param.object_file_names) { + const char *fn = str_node->s; + pr_debug("loading %s\n", str_node->s); + if ((err = bpf_prepare_load(fn))) { + pr_err("bpf: failed to load object file %s\n", + fn); + return -1; + } + } return start_bpf_record(argc, argv); usage: diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 797490a..609f6d6 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -75,6 +75,7 @@ libperf-$(CONFIG_X86) += tsc.o libperf-y += cloexec.o libperf-y += thread-stack.o +libperf-$(CONFIG_LIBELF) += bpf-loader.o libperf-$(CONFIG_LIBELF) += symbol-elf.o libperf-$(CONFIG_LIBELF) += probe-event.o diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c new file mode 100644 index 0000000..17cd2b6 --- /dev/null +++ b/tools/perf/util/bpf-loader.c @@ -0,0 +1,69 @@ +/* + * bpf-loader.c + * + * Load bpf files into kernel using libbpf; create kprobe events. + */ + +#include +#include "perf.h" +#include "debug.h" +#include "bpf-loader.h" + +#define DEFINE_PRINT_FN(name, level) \ +static int libbpf_##name(const char *fmt, ...) \ +{ \ + va_list args; \ + int ret; \ + \ + va_start(args, fmt); \ + ret = veprintf(level, verbose, pr_fmt(fmt), args);\ + va_end(args); \ + return ret; \ +} + +DEFINE_PRINT_FN(warning, 0) +DEFINE_PRINT_FN(info, 0) +DEFINE_PRINT_FN(debug, 1) + +static bool libbpf_inited = false; + +#define MAX_OBJECTS 128 + +struct { + struct bpf_object *objects[MAX_OBJECTS]; + size_t nr_objects; +} params; + +int bpf_prepare_load(const char *filename) +{ + struct bpf_object *obj; + + if (!libbpf_inited) + libbpf_set_print(libbpf_warning, + libbpf_info, + libbpf_debug); + + pr_debug("bpf: loading %s\n", filename); + if (params.nr_objects + 1 > MAX_OBJECTS) { + pr_err("Too many objects to load. " + "Increase MAX_OBJECTS\n"); + return -EMFILE; + } + + obj = bpf_open_object(filename); + if (!obj) { + pr_err("bpf: failed to load %s\n", filename); + return -EINVAL; + } + + params.objects[params.nr_objects++] = obj; + return 0; +} + +void bpf_clear(void) +{ + size_t i; + + for (i = 0; i < params.nr_objects; i++) + bpf_close_object(params.objects[i]); +} diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h new file mode 100644 index 0000000..74eebc3 --- /dev/null +++ b/tools/perf/util/bpf-loader.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015, Wang Nan + * Copyright (C) 2015, Huawei Inc. + * + * Released under the GPL v2. (and only v2, not any later version) + */ +#ifndef __BPF_LOADER_H +#define __BPF_LOADER_H + +int bpf_prepare_load(const char *filename); + +void bpf_clear(void); +#endif diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 2da5581..86d9c73 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -36,6 +36,11 @@ static int _eprintf(int level, int var, const char *fmt, va_list args) return ret; } +int veprintf(int level, int var, const char *fmt, va_list args) +{ + return _eprintf(level, var, fmt, args); +} + int eprintf(int level, int var, const char *fmt, ...) { va_list args; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index caac2fd..8b9a088 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -50,6 +50,7 @@ void pr_stat(const char *fmt, ...); int eprintf(int level, int var, const char *fmt, ...) __attribute__((format(printf, 3, 4))); int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __attribute__((format(printf, 4, 5))); +int veprintf(int level, int var, const char *fmt, va_list args); int perf_debug_option(const char *str); -- 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/