Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752625AbcDTSCz (ORCPT ); Wed, 20 Apr 2016 14:02:55 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:22029 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752207AbcDTSCx (ORCPT ); Wed, 20 Apr 2016 14:02:53 -0400 From: Wang Nan To: , , CC: , , Wang Nan , Arnaldo Carvalho de Melo , "Alexei Starovoitov" , Jiri Olsa , Li Zefan Subject: [RFC PATCH 12/13] perf record: Add UBPF hooks at beginning and end of perf record Date: Wed, 20 Apr 2016 18:01:52 +0000 Message-ID: <1461175313-38310-13-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1461175313-38310-1-git-send-email-wangnan0@huawei.com> References: <1461175313-38310-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090205.5717C42B.0155,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 132cce2fd6125f827b883248bf94b9a8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5763 Lines: 210 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 Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: Jiri Olsa Cc: Li Zefan --- 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 diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index c7f92cc..0c49249 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -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 @@ -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(); diff --git a/tools/perf/util/Build b/tools/perf/util/Build index e193e6b..c3b8763 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..626d18a --- /dev/null +++ b/tools/perf/util/ubpf-hooks-list.h @@ -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; + ) + ) diff --git a/tools/perf/util/ubpf-hooks.c b/tools/perf/util/ubpf-hooks.c new file mode 100644 index 0000000..9a53f7c --- /dev/null +++ b/tools/perf/util/ubpf-hooks.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016, Wang Nan + * Copyright (C) 2016, Huawei Inc. + */ + +#include +#include +#include +#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 diff --git a/tools/perf/util/ubpf-hooks.h b/tools/perf/util/ubpf-hooks.h new file mode 100644 index 0000000..165f52d --- /dev/null +++ b/tools/perf/util/ubpf-hooks.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016, Wang Nan + * Copyright (C) 2016, Huawei Inc. + */ +#ifndef __PERF_UBPF_HOOKS_H +#define __PERF_UBPF_HOOKS_H + +#include + +#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 -- 1.8.3.4