Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1180712
| From | Wang Nan <wangnan0@huawei.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 35/39] perf tools: Generate prologue for BPF programs |
| Date | 2015-07-09 14:50 +0200 |
| Message-ID | <pKjr5-dD-37@gated-at.bofh.it> (permalink) |
| References | <pKjhn-9T-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
This patch generates prologue for each 'struct probe_trace_event' for
fetching arguments for BPF programs.
After bpf__probe(), iterate over each programs to check whether
prologue is required. If none of 'struct perf_probe_event' a program
will attach to has at least one argument, simply skip preprocessor
hooking. For those who prologue is required, calls bpf__gen_prologue()
and paste original instruction after prologue.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
---
tools/perf/util/bpf-loader.c | 132 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index bd2ebe1..41bffdd 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -5,10 +5,12 @@
* Copyright (C) 2015 Huawei Inc.
*/
+#include <linux/bpf.h>
#include <bpf/libbpf.h>
#include "perf.h"
#include "debug.h"
#include "bpf-loader.h"
+#include "bpf-prologue.h"
#include "llvm-utils.h"
#include "probe-event.h"
#include "probe-finder.h"
@@ -53,6 +55,8 @@ alloc_perf_probe_event(void)
struct bpf_prog_priv {
struct perf_probe_event *pev;
+ bool need_prologue;
+ struct bpf_insn *insns_buf;
};
static void
@@ -63,6 +67,7 @@ bpf_prog_priv__clear(struct bpf_program *prog __maybe_unused,
if (priv->pev)
clear_perf_probe_event(priv->pev);
+ zfree(&priv->insns_buf);
free(priv);
}
@@ -223,10 +228,109 @@ int bpf__unprobe(void)
return ret < 0 ? ret : 0;
}
+static int
+preproc_gen_prologue(struct bpf_program *prog, int n,
+ struct bpf_insn *orig_insns, int orig_insns_cnt,
+ struct bpf_prog_prep_result *res)
+{
+ struct probe_trace_event *tev;
+ struct perf_probe_event *pev;
+ struct bpf_prog_priv *priv;
+ struct bpf_insn *buf;
+ size_t prologue_cnt = 0;
+ int err;
+
+ err = bpf_program__get_private(prog, (void **)&priv);
+ if (err || !priv)
+ goto errout;
+
+ pev = priv->pev;
+
+ if (n < 0 || n >= pev->ntevs)
+ goto errout;
+
+ tev = &pev->tevs[n];
+
+ buf = priv->insns_buf;
+ err = bpf__gen_prologue(tev->args, tev->nargs,
+ buf, &prologue_cnt,
+ BPF_MAXINSNS - orig_insns_cnt);
+ if (err) {
+ const char *title;
+
+ title = bpf_program__title(prog, false);
+ if (!title)
+ title = "??";
+
+ pr_err("Failed to generate prologue for program %s\n",
+ title);
+ return err;
+ }
+
+ memcpy(&buf[prologue_cnt], orig_insns,
+ sizeof(struct bpf_insn) * orig_insns_cnt);
+
+ res->new_insn_ptr = buf;
+ res->new_insn_cnt = prologue_cnt + orig_insns_cnt;
+ res->pfd = NULL;
+ return 0;
+
+errout:
+ pr_err("Internal error in preproc_gen_prologue\n");
+ return -EINVAL;
+}
+
+static int hook_load_preprocessor(struct bpf_program *prog)
+{
+ struct perf_probe_event *pev;
+ struct bpf_prog_priv *priv;
+ bool need_prologue = false;
+ int err, i;
+
+ err = bpf_program__get_private(prog, (void **)&priv);
+ if (err || !priv) {
+ pr_err("Internal error when hook preprocessor\n");
+ return -EINVAL;
+ }
+
+ pev = priv->pev;
+ for (i = 0; i < pev->ntevs; i++) {
+ struct probe_trace_event *tev = &pev->tevs[i];
+
+ if (tev->nargs > 0) {
+ need_prologue = true;
+ break;
+ }
+ }
+
+ /*
+ * Since all tev doesn't have argument, we don't need generate
+ * prologue.
+ */
+ if (!need_prologue) {
+ priv->need_prologue = false;
+ return 0;
+ }
+
+ priv->need_prologue = true;
+ priv->insns_buf = malloc(sizeof(struct bpf_insn) *
+ BPF_MAXINSNS);
+ if (!priv->insns_buf) {
+ pr_err("No enough memory: alloc insns_buf failed\n");
+ return -ENOMEM;
+ }
+
+ err = bpf_program__set_prep(prog, pev->ntevs,
+ preproc_gen_prologue);
+ return err;
+}
+
int bpf__probe(void)
{
int err;
bool old_silent = probe_conf.silent;
+ struct bpf_object *obj, *tmp;
+ struct bpf_program *prog;
if (nr_probe_events <= 0)
return 0;
@@ -245,7 +349,27 @@ int bpf__probe(void)
else
is_probing = true;
- return err < 0 ? err : 0;
+ err = err < 0 ? err : 0;
+ if (err)
+ return err;
+
+ /*
+ * After probing, let's consider prologue, which
+ * add program fetcher to BPF programs.
+ *
+ * hook_load_preprocessorr() hooks pre-processor to bpf_program,
+ * let it generate prologue dynamically during loading.
+ */
+
+ bpf_object__for_each_safe(obj, tmp) {
+ bpf_object__for_each_program(prog, obj) {
+ err = hook_load_preprocessor(prog);
+ if (err)
+ return err;
+ }
+ }
+
+ return err;
}
int bpf__load(void)
@@ -291,7 +415,11 @@ int bpf__foreach_tev(bpf_prog_iter_callback_t func, void *arg)
for (i = 0; i < pev->ntevs; i++) {
tev = &pev->tevs[i];
- fd = bpf_program__fd(prog);
+ if (priv->need_prologue)
+ fd = bpf_program__nth_fd(prog, i);
+ else
+ fd = bpf_program__fd(prog);
+
if (fd < 0) {
pr_err("bpf: failed to get file descriptor\n");
return fd;
--
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/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[GIT PULL 00/39] perf tools: filtering events using eBPF programs Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:40 +0200
[PATCH 36/39] perf tools: Use same BPF program if arguments are identical Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 25/39] perf tools: Attach eBPF program to perf event Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 27/39] perf record: Add clang options for compiling BPF scripts Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 34/39] perf tools: Add prologue for BPF programs for fetching arguments Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 31/39] perf tools: Move linux/filter.h to tools/include Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 26/39] perf tools: Suppress probing messages when probing by BPF loading Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 28/39] bpf tools: Load a program with different instances using preprocessor Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
Re: [PATCH 28/39] bpf tools: Load a program with different instances using preprocessor "Wangnan (F)" <wangnan0@huawei.com> - 2015-07-13 08:00 +0200
[PATCH 13/39] perf tools: Call clang to compile C source to object code Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 32/39] perf tools: Add BPF_PROLOGUE config options for further patches Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 06/39] bpf tools: Create eBPF maps defined in an object file Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
Re: [PATCH 06/39] bpf tools: Create eBPF maps defined in an object file "Wangnan (F)" <wangnan0@huawei.com> - 2015-07-14 06:10 +0200
[PATCH 35/39] perf tools: Generate prologue for BPF programs Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 30/39] perf probe: Reset args and nargs for probe_trace_event when failure Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 18/39] perf record: Enable passing bpf object file to --event Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 14/39] perf tools: Auto detecting kernel build directory Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 23/39] perf record: Load all eBPF object into kernel Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 24/39] perf tools: Add bpf_fd field to evsel and config it Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 22/39] perf record: Probe at kprobe points Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 15/39] perf tools: Auto detecting kernel include options Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 29/39] perf tools: Fix probe-event.h include Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 02/39] bpf tools: Collect eBPF programs from their own sections Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
Re: [PATCH 02/39] bpf tools: Collect eBPF programs from their own sections "Wangnan (F)" <wangnan0@huawei.com> - 2015-07-10 05:20 +0200
Re: [PATCH 02/39] bpf tools: Collect eBPF programs from their own sections "Wangnan (F)" <wangnan0@huawei.com> - 2015-07-14 06:10 +0200
[PATCH 21/39] perf probe: Attach trace_probe_event with perf_probe_event Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 09/39] bpf tools: Load eBPF programs in object files into kernel Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
[PATCH 37/39] perf record: Support custom vmlinux path Wang Nan <wangnan0@huawei.com> - 2015-07-09 14:50 +0200
perf test LLVM was: Re: [GIT PULL 00/39] perf tools: filtering events using eBPF programs Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-07-14 17:40 +0200
Re: perf test LLVM was: Re: [GIT PULL 00/39] perf tools: filtering events using eBPF programs "Wangnan (F)" <wangnan0@huawei.com> - 2015-07-15 13:10 +0200
Re: perf test LLVM was: Re: [GIT PULL 00/39] perf tools: filtering events using eBPF programs Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-07-15 13:30 +0200
csiph-web