[RFC PATCH v2 13/15] perf bpf: Combine bpf prologue and bpf prog

From: He Kuang
Date: Sun May 24 2015 - 04:29:44 EST


Combine bpf prologue before attaching bpf progs to perf probe event. If
prologue is generated, it will be pasted in front of the original bpf
prog.

Signed-off-by: He Kuang <hekuang@xxxxxxxxxx>
---
tools/lib/bpf/libbpf.c | 27 +++++++++++++++++++++++++++
tools/lib/bpf/libbpf.h | 2 ++
tools/perf/util/bpf-loader.c | 27 +++++++++++++++++++++++++++
3 files changed, 56 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 89c725a..c0b792f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1087,3 +1087,30 @@ int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd)
*pfd = prog->fd;
return 0;
}
+
+int bpf_obj_prologue(struct bpf_prog_handler *handler, char *result, int size)
+{
+ struct bpf_program *prog;
+ int new_count;
+ int count = size / sizeof(struct bpf_insn);
+
+ prog = handler_to_prog(handler);
+ if (!prog)
+ return -EINVAL;
+
+ new_count = prog->insns_cnt + count;
+ result = realloc(result,
+ new_count * sizeof(struct bpf_insn));
+ if (!result)
+ return -ENOMEM;
+
+ memcpy(result + count * sizeof(struct bpf_insn),
+ prog->insns,
+ prog->insns_cnt * sizeof(struct bpf_insn));
+
+ free(prog->insns);
+ prog->insns = (struct bpf_insn *)result;
+ prog->insns_cnt = new_count;
+
+ return 0;
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 9d6d4f7..7df58fd 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -53,6 +53,8 @@ int bpf_prog_get_title(struct bpf_prog_handler *handler,

int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd);

+int bpf_obj_prologue(struct bpf_prog_handler *handler, char *result, int count);
+
/*
* packed attribute is unnecessary for 'bpf_map_def'.
*/
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index b793c69..3f93d04 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -168,6 +168,31 @@ void bpf_clear(void)
bpf_close_object(params.objects[i]);
}

+static int bpf_prologue(void)
+{
+ int i, ret;
+
+ for (i = 0; i < (int)params.nr_progs; i++) {
+ struct bpf_prog_handler *prog =
+ params.progs[i].prog;
+ struct perf_probe_event *pevent =
+ params.progs[i].pevent;
+ int count;
+ char *result;
+
+ ret = get_bpf_prologue(pevent, &result, &count);
+ if (ret)
+ return ret;
+
+ if (count > 0)
+ ret = bpf_obj_prologue(prog, result, count);
+ else
+ pr_debug("bpf: no prologue generated\n");
+ }
+
+ return ret;
+}
+
static bool is_probing = false;

int bpf_unprobe(void)
@@ -220,6 +245,8 @@ int bpf_load(void)
size_t i;
int err;

+ bpf_prologue();
+
for (i = 0; i < params.nr_objects; i++) {
err = bpf_load_object(params.objects[i]);
if (err) {
--
1.8.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/