From: Wang Nan <wangnan0@huawei.com>
To: <acme@kernel.org>, <jolsa@redhat.com>, <brendan.d.gregg@gmail.com>
Cc: <linux-kernel@vger.kernel.org>, <pi3orama@163.com>,
Wang Nan <wangnan0@huawei.com>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
"Alexei Starovoitov" <ast@kernel.org>,
Jiri Olsa <jolsa@kernel.org>, Li Zefan <lizefan@huawei.com>
Subject: [RFC PATCH 00/13] perf tools: Support uBPF script
Date: Wed, 20 Apr 2016 18:01:40 +0000 [thread overview]
Message-ID: <1461175313-38310-1-git-send-email-wangnan0@huawei.com> (raw)
This patch set allows to perf invoke some user space BPF scripts on some
point. uBPF scripts and kernel BPF scripts reside in one BPF object.
They communicate with each other with BPF maps. uBPF scripts can invoke
helper functions provided by perf.
At least following new features can be achieved based on uBPF support:
1) Report statistical result:
Like DTrace, perf print statistical report before quit. No need to
extract data using 'perf report'. Statistical method is controled by
user.
2) Control perf's behavior:
Dynamically adjust period of different events. Policy is defined by
user.
uBPF library is required before compile. It can be found from github:
https://github.com/iovisor/ubpf.git
Following is an example:
Using BPF script attached at the bottom of this commit message, one
can print histogram of write size before perf exit like this:
# ~/perf record -a -e ./test_ubpf.c &
[1] 16800
# dd if=/dev/zero of=/dev/null bs=512 count=5000
5000+0 records in
5000+0 records out
2560000 bytes (2.6 MB) copied, 0.00552838 s, 463 MB/s
# dd if=/dev/zero of=/dev/null bs=2048 count=5000
5000+0 records in
5000+0 records out
10240000 bytes (10 MB) copied, 0.0188971 s, 542 MB/s
# fg
^C <--- *Press Ctrl-c*
2^^0: 47
2^^1: 13
2^^2: 4
2^^3: 130
2^^4: 11
2^^5: 1051
2^^6: 486
2^^7: 4863
2^^8: 0
2^^9: 5003
2^^10: 4
2^^11: 5003
2^^12: 1
2^^13: 0
2^^14: 0
2^^15: 0
2^^16: 0
2^^17: 0
2^^18: 0
2^^19: 0
2^^20: 0
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.788 MB perf.data ]
Here is test_ubpf.c.
/************ BEGIN ***************/
#include <uapi/linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))
struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
};
#define BPF_ANY 0
static void *(*map_lookup_elem)(struct bpf_map_def *, void *) =
(void *)BPF_FUNC_map_lookup_elem;
static inline unsigned int log2(unsigned int v)
{
unsigned int r;
unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
shift = (v > 0xF) << 2; v >>= shift; r |= shift;
shift = (v > 0x3) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
return r;
}
static inline unsigned int log2l(unsigned long v)
{
unsigned int hi = v >> 32;
if (hi)
return log2(hi) + 32;
else
return log2(v);
}
struct bpf_map_def SEC("maps") my_hist_map = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(long),
.max_entries = 21,
};
SEC("sys_write=sys_write count")
int sys_write(void *ctx, int err, long write_size)
{
long *value;
int key = 0;
if (err)
return 0;
key = log2l(write_size);
if (key > 20)
key = 20;
value = map_lookup_elem(&my_hist_map, &key);
if (!value)
return 0;
__sync_fetch_and_add(value, 1);
return 0;
}
char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
/* Following ugly magic numbers can be find from tools/perf/util/ubpf-helpers-list.h */
static int (*ubpf_memcmp)(void *s1, void *s2, unsigned int n) = (void *)1;
static void (*ubpf_memcpy)(void *d, void *s, unsigned int size) = (void *)2;
static int (*ubpf_strcmp)(void *s1, void *s2) = (void *)3;
static int (*ubpf_printf)(char *fmt, ...) = (void *)4;
static int (*ubpf_map_lookup_elem)(void *map_desc, void *key, void *value) = (void *)5;
static int (*ubpf_map_update_elem)(void *map_desc, void *key, void *value, unsigned long long flags) = (void *)6;
static int (*ubpf_map_get_next_key)(void *map_desc, void *key, void *value) = (void *)7;
SEC("UBPF;perf_record_end")
int perf_record_end(int samples)
{
int i, key;
long value;
char fmt[] = "2^^%d: %d\n";
for (i = 0; i < 21; i++) {
ubpf_map_lookup_elem(&my_hist_map, &i, &value);
ubpf_printf(fmt, i, value);
}
return 0;
}
/************** END ***************/
Cc: 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>
Wang Nan (13):
bpf tools: Add map related BPF helper
tools: Add ubpf feature test
bpf tools: Add ubpf include and makefile options
bpf tools: Replace fd array to union array
bpf tools: Save engine type in bpf_program
bpf tools: Introduce ubpf_vm to program instance union
bpf tools: Load ubpf program
bpf tools: Add API for fetching ubpf_vm
bpf tools: Register extern functions for ubpf programs
perf tools: Register basic UBPF helpers
perf bpf: Accept ubpf programs
perf record: Add UBPF hooks at beginning and end of perf record
perf tests: Add UBPF test case
tools/build/Makefile.feature | 6 +-
tools/build/feature/Makefile | 6 +-
tools/build/feature/test-ubpf.c | 11 ++
tools/lib/bpf/Makefile | 16 +-
tools/lib/bpf/bpf.c | 24 +++
tools/lib/bpf/bpf.h | 2 +
tools/lib/bpf/libbpf.c | 281 ++++++++++++++++++++++++++++----
tools/lib/bpf/libbpf.h | 21 ++-
tools/perf/Makefile.perf | 2 +
tools/perf/builtin-record.c | 4 +
tools/perf/config/Makefile | 7 +
tools/perf/perf.c | 3 +
tools/perf/tests/Build | 8 +
tools/perf/tests/bpf-script-test-ubpf.c | 68 ++++++++
tools/perf/tests/bpf.c | 77 ++++++++-
tools/perf/tests/llvm.c | 4 +
tools/perf/tests/llvm.h | 2 +
tools/perf/util/Build | 1 +
tools/perf/util/bpf-loader.c | 22 +++
tools/perf/util/ubpf-helpers-list.h | 7 +
tools/perf/util/ubpf-helpers.c | 66 ++++++++
tools/perf/util/ubpf-helpers.h | 21 +++
tools/perf/util/ubpf-hooks-list.h | 10 ++
tools/perf/util/ubpf-hooks.c | 81 +++++++++
tools/perf/util/ubpf-hooks.h | 35 ++++
25 files changed, 745 insertions(+), 40 deletions(-)
create mode 100644 tools/build/feature/test-ubpf.c
create mode 100644 tools/perf/tests/bpf-script-test-ubpf.c
create mode 100644 tools/perf/util/ubpf-helpers-list.h
create mode 100644 tools/perf/util/ubpf-helpers.c
create mode 100644 tools/perf/util/ubpf-helpers.h
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
next reply other threads:[~2016-04-20 18:06 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-20 18:01 Wang Nan [this message]
2016-04-20 18:01 ` [RFC PATCH 01/13] bpf tools: Add map related BPF helper Wang Nan
2016-04-20 18:01 ` [RFC PATCH 02/13] tools: Add ubpf feature test Wang Nan
2016-04-20 19:11 ` Arnaldo Carvalho de Melo
2016-04-20 18:01 ` [RFC PATCH 03/13] bpf tools: Add ubpf include and makefile options Wang Nan
2016-04-20 18:01 ` [RFC PATCH 04/13] bpf tools: Replace fd array to union array Wang Nan
2016-04-20 19:20 ` Arnaldo Carvalho de Melo
2016-04-20 18:01 ` [RFC PATCH 05/13] bpf tools: Save engine type in bpf_program Wang Nan
2016-04-20 19:23 ` Arnaldo Carvalho de Melo
2016-04-20 19:29 ` pi3orama
2016-04-20 18:01 ` [RFC PATCH 06/13] bpf tools: Introduce ubpf_vm to program instance union Wang Nan
2016-04-20 19:30 ` Arnaldo Carvalho de Melo
2016-04-20 18:01 ` [RFC PATCH 07/13] bpf tools: Load ubpf program Wang Nan
2016-04-20 19:34 ` Arnaldo Carvalho de Melo
2016-04-20 18:01 ` [RFC PATCH 08/13] bpf tools: Add API for fetching ubpf_vm Wang Nan
2016-04-20 18:01 ` [RFC PATCH 09/13] bpf tools: Register extern functions for ubpf programs Wang Nan
2016-04-20 18:01 ` [RFC PATCH 10/13] perf tools: Register basic UBPF helpers Wang Nan
2016-04-20 18:01 ` [RFC PATCH 11/13] perf bpf: Accept ubpf programs Wang Nan
2016-04-20 18:01 ` [RFC PATCH 12/13] perf record: Add UBPF hooks at beginning and end of perf record Wang Nan
2016-04-20 18:01 ` [RFC PATCH 13/13] perf tests: Add UBPF test case Wang Nan
2016-04-20 22:06 ` [RFC PATCH 00/13] perf tools: Support uBPF script Alexei Starovoitov
2016-04-21 8:17 ` Wangnan (F)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1461175313-38310-1-git-send-email-wangnan0@huawei.com \
--to=wangnan0@huawei.com \
--cc=acme@kernel.org \
--cc=acme@redhat.com \
--cc=ast@kernel.org \
--cc=brendan.d.gregg@gmail.com \
--cc=jolsa@kernel.org \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@huawei.com \
--cc=pi3orama@163.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®