@@ -35,6 +35,7 @@
#include "util/llvm-utils.h"
#include "util/bpf-loader.h"
#include "util/trigger.h"
+#include "util/ubpf-hooks.h"
#include "asm/bug.h"
#include <unistd.h>
@@ -824,6 +825,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
auxtrace_snapshot_ready();
switch_output_ready();
+ ubpf_hook_perf_record_start(0);
for (;;) {
unsigned long long hits = rec->samples;
@@ -888,6 +890,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
disabled = true;
}
}
+ ubpf_hook_perf_record_end(0, rec->samples);
+
auxtrace_snapshot_off();
switch_output_off();
@@ -87,7 +87,7 @@ libperf-y += mem-events.o
libperf-$(CONFIG_LIBBPF) += bpf-loader.o
libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
-libperf-$(CONFIG_UBPF) += ubpf-helpers.o
+libperf-$(CONFIG_UBPF) += ubpf-helpers.o ubpf-hooks.o
libperf-$(CONFIG_LIBELF) += symbol-elf.o
libperf-$(CONFIG_LIBELF) += probe-file.o
libperf-$(CONFIG_LIBELF) += probe-event.o
new file mode 100644
@@ -0,0 +1,10 @@
+UBPF_HOOK(perf_record_start,,)
+
+UBPF_HOOK(perf_record_end,
+ __UBPF_HOOK_ARG(
+ __arg(int, samples)
+ ),
+ __UBPF_HOOK_ASSIGN(
+ __entry.samples = samples;
+ )
+ )
new file mode 100644
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016, Wang Nan <wangnan0@huawei.com>
+ * Copyright (C) 2016, Huawei Inc.
+ */
+
+#include <bpf/libbpf.h>
+#include <asm/bug.h>
+#include <ubpf.h>
+#include "ubpf-hooks.h"
+#include "debug.h"
+
+static int run_ubpf_program(struct bpf_program *prog, void *mem, size_t len)
+{
+ struct ubpf_vm *vm;
+ int ret;
+
+ vm = bpf_program__vm(prog);
+ if (!vm) {
+ WARN_ONCE(!vm, "Unable to fetch vm from UBPF program\n");
+ return -EINVAL;
+ }
+
+ ret = ubpf_exec(vm, mem, len);
+ pr_debug("program %s returns %d\n",
+ bpf_program__title(prog, false), ret);
+ return ret;
+}
+
+static int
+run_ubpf_programs(unsigned long flags, const char *expect_title,
+ void *mem, size_t len)
+{
+
+ struct bpf_object *obj, *tmp;
+ struct bpf_program *prog;
+ const char *title;
+ int err;
+
+ if (!len)
+ mem = NULL;
+
+ bpf_object__for_each_safe(obj, tmp) {
+ bpf_object__for_each_program(prog, obj) {
+ if (bpf_program__is_ubpf(prog)) {
+ title = bpf_program__title(prog, false);
+ if (!title)
+ continue;
+ if (strcmp(title, expect_title) != 0)
+ continue;
+ err = run_ubpf_program(prog, mem, len);
+ if (err && (flags & UBPF_HOOK_BREAKABLE))
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#define __arg(t, n) t n;
+#define __UBPF_HOOK_ARG(args) args
+#define UBPF_HOOK(n, args, assign) struct ubpf_hook_##n##_proto {args};
+#include "ubpf-hooks-list.h"
+#undef UBPF_HOOK
+#undef __UBPF_HOOK_ARG
+#undef __arg
+
+#define __arg(t, n) , t n
+#define __UBPF_HOOK_ASSIGN(code) do {code;} while(0)
+#define __UBPF_HOOK_ARG(args) args
+#define UBPF_HOOK(n, a, assign) \
+int ubpf_hook_##n(unsigned long flags a) { \
+ struct ubpf_hook_##n##_proto __entry; \
+ assign; \
+ return run_ubpf_programs(flags, "UBPF;"#n, &__entry, sizeof(__entry));\
+}
+#include "ubpf-hooks-list.h"
+#undef UBPF_HOOK
+#undef __UBPF_HOOK_ARG
+#undef __UBPF_HOOK_ASSIGN
+#undef __arg
new file mode 100644
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016, Wang Nan <wangnan0@huawei.com>
+ * Copyright (C) 2016, Huawei Inc.
+ */
+#ifndef __PERF_UBPF_HOOKS_H
+#define __PERF_UBPF_HOOKS_H
+
+#include <linux/compiler.h>
+
+#define UBPF_HOOK_BREAKABLE 1
+
+#ifdef HAVE_UBPF_SUPPORT
+
+#define __arg(t, n) , t n
+#define __UBPF_HOOK_ARG(args) args
+#define UBPF_HOOK(n, args, assign) int ubpf_hook_##n(unsigned long flags args);
+#include "ubpf-hooks-list.h"
+#undef UBPF_HOOK
+#undef __UBPF_HOOK_ARG
+#undef __arg
+
+#else
+
+#define __arg(t, n) , t n __maybe_unused
+#define __UBPF_HOOK_ARG(args) args
+#define UBPF_HOOK(n, args, assign) \
+static inline int ubpf_hook_##n(unsigned long flags __maybe_unused args) {return 0;};
+#include "ubpf-hooks-list.h"
+#undef UBPF_HOOK
+#undef __UBPF_HOOK_ARG
+#undef __arg
+
+#endif
+
+#endif
Like tracepoint in kernel code, UBPF hooks can be added in perf code and trigger UBPF programs passed by BPF scripts. The first two UBPF hooks added are record start/end. UBPF scripts can initial BPF maps in record start, and report result when record finished. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Li Zefan <lizefan@huawei.com> --- tools/perf/builtin-record.c | 4 ++ tools/perf/util/Build | 2 +- tools/perf/util/ubpf-hooks-list.h | 10 +++++ tools/perf/util/ubpf-hooks.c | 81 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/ubpf-hooks.h | 35 +++++++++++++++++ 5 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 tools/perf/util/ubpf-hooks-list.h create mode 100644 tools/perf/util/ubpf-hooks.c create mode 100644 tools/perf/util/ubpf-hooks.h -- 1.8.3.4