Messages in this thread Patch in this message | | | From | He Kuang <> | Subject | [RFC PATCH v2 23/26] perf record: Add uBPF hooks at beginning and end of perf record | Date | Sun, 26 Jun 2016 11:21:15 +0000 |
| |
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: He Kuang <hekuang@huawei.com> Signed-off-by: Wang Nan <wangnan0@huawei.com> --- tools/perf/builtin-record.c | 4 +++ tools/perf/util/Build | 2 +- tools/perf/util/ubpf-hooks-list.h | 34 ++++++++++++++++++++ tools/perf/util/ubpf-hooks.c | 68 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/ubpf-hooks.h | 41 +++++++++++++++++++++++ 5 files changed, 148 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
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 81411b1..c956d57 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -36,6 +36,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> @@ -893,6 +894,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) trigger_ready(&auxtrace_snapshot_trigger); trigger_ready(&switch_output_trigger); + ubpf_hook_perf_record_start(0); for (;;) { unsigned long long hits = rec->samples; @@ -957,6 +959,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) disabled = true; } } + ubpf_hook_perf_record_end(rec->samples, 0); + trigger_off(&auxtrace_snapshot_trigger); trigger_off(&switch_output_trigger); diff --git a/tools/perf/util/Build b/tools/perf/util/Build index d12ef7d..80f3c20 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -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 diff --git a/tools/perf/util/ubpf-hooks-list.h b/tools/perf/util/ubpf-hooks-list.h new file mode 100644 index 0000000..b796334 --- /dev/null +++ b/tools/perf/util/ubpf-hooks-list.h @@ -0,0 +1,34 @@ +UBPF_HOOK(perf_record_start, + __UBPF_HOOK_PROTO( + __proto(int dummy) + ), + + __UBPF_HOOK_ARGS(dummy), + + __UBPF_HOOK_STRUCT__entry( + __field(int, dummy) + ), + + __UBPF_HOOK_ASSIGN( + __entry.dummy = dummy; + ) + ); + +UBPF_HOOK(perf_record_end, + __UBPF_HOOK_PROTO( + __proto(int samples), + __proto(int dummy) + ), + + __UBPF_HOOK_ARGS(samples, dummy), + + __UBPF_HOOK_STRUCT__entry( + __field(int, samples) + __field(int, dummy) + ), + + __UBPF_HOOK_ASSIGN( + __entry.samples = samples; + __entry.dummy = dummy; + ) + ); diff --git a/tools/perf/util/ubpf-hooks.c b/tools/perf/util/ubpf-hooks.c new file mode 100644 index 0000000..6ffe344 --- /dev/null +++ b/tools/perf/util/ubpf-hooks.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016, Wang Nan <wangnan0@huawei.com> + * Copyright (C) 2016, He Kuang <hekuang@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 __maybe_unused, + void *mem __maybe_unused, size_t len __maybe_unused) +{ + return 0; +} + +static int +run_ubpf_programs(const char *expect_title, void *mem, size_t len) +{ + + struct bpf_object *obj, *tmp; + struct bpf_program *prog; + const char *title; + int err; + + 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) + return err; + } + } + } + + return 0; +} + +#define __UBPF_HOOK_PROTO(args...) args +#define __UBPF_HOOK_ARG(args...) args +#define __UBPF_HOOK_STRUCT__entry(args...) args +#define __proto(args) args +#define __field(type, item) type item; + +#define UBPF_HOOK(name, proto, args, tstruct, assign) \ + struct ubpf_hook_##name##_proto {tstruct} +#include "ubpf-hooks-list.h" +#undef UBPF_HOOK + +#define __UBPF_HOOK_ASSIGN(code...) code + +#define UBPF_HOOK(name, proto, args, tstruct, assign) \ + int ubpf_hook_##name(proto) \ + { \ + struct ubpf_hook_##name##_proto __entry; \ + assign; \ + return run_ubpf_programs("UBPF;"#name, \ + &__entry, sizeof(__entry)); \ + } +#include "ubpf-hooks-list.h" +#undef UBPF_HOOK diff --git a/tools/perf/util/ubpf-hooks.h b/tools/perf/util/ubpf-hooks.h new file mode 100644 index 0000000..4d2f23e --- /dev/null +++ b/tools/perf/util/ubpf-hooks.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2016, Wang Nan <wangnan0@huawei.com> + * Copyright (C) 2016, He Kuang <hekuang@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 + +#define __UBPF_HOOK_PROTO(args...) args +#define __UBPF_HOOK_ARG(args...) args +#define __UBPF_HOOK_STRUCT__entry(args...) args +#define __field(type, item) type item; + +#ifdef HAVE_UBPF_SUPPORT + +#define __proto(args) args +#define UBPF_HOOK(name, proto, args, struct, assign) int ubpf_hook_##name(proto) + +#include "ubpf-hooks-list.h" + +#else + +#define __proto(args) args __maybe_unused +#define UBPF_HOOK(name, proto, args, struct, assign) \ + static inline int ubpf_hook_##name(proto) {return 0; } \ + +#include "ubpf-hooks-list.h" +#endif + +#undef UBPF_HOOK +#undef __UBPF_HOOK_PROTO +#undef __UBPF_HOOK_ARG +#undef __UBPF_HOOK_STRUCT__entry +#undef __field +#undef __proto + +#endif /* __PERF_UBPF_HOOKS_H */ -- 1.8.5.2
| |