[PATCH v6 tip 6/8] samples: bpf: counting example for kfree_skb and write syscall
this example has two probes in one C file that attach to different kprove events and use two different maps. 1st probe is x64 specific equivalent of dropmon. It attaches to kfree_skb, retrevies 'ip' address of kfree_skb() caller and counts number of packet drops at that 'ip' address. User space prints 'location - count' map every second. 2nd probe attaches to kprobe:sys_write and computes a histogram of different write sizes Usage: $ sudo tracex2 location 0x81695995 count 1 location 0x816d0da9 count 2 location 0x81695995 count 2 location 0x816d0da9 count 2 location 0x81695995 count 3 location 0x816d0da9 count 2 557145+0 records in 557145+0 records out 285258240 bytes (285 MB) copied, 1.02379 s, 279 MB/s syscall write() stats byte_size : count distribution 1 -> 1: 3| | 2 -> 3: 0| | 4 -> 7: 0| | 8 -> 15 : 0| | 16 -> 31 : 2| | 32 -> 63 : 3| | 64 -> 127 : 1| | 128 -> 255 : 1| | 256 -> 511 : 0| | 512 -> 1023 : 1118968 |* | Ctrl-C at any time. Kernel will auto cleanup maps and programs $ addr2line -ape ./bld_x64/vmlinux 0x81695995 0x816d0da9 0x81695995: ./bld_x64/../net/ipv4/icmp.c:1038 0x816d0da9: ./bld_x64/../net/unix/af_unix.c:1231 Signed-off-by: Alexei Starovoitov --- samples/bpf/Makefile |4 ++ samples/bpf/tracex2_kern.c | 86 +++ samples/bpf/tracex2_user.c | 95 3 files changed, 185 insertions(+) create mode 100644 samples/bpf/tracex2_kern.c create mode 100644 samples/bpf/tracex2_user.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 51f6f01e5a3a..6dd272143733 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -7,6 +7,7 @@ hostprogs-y += sock_example hostprogs-y += sockex1 hostprogs-y += sockex2 hostprogs-y += tracex1 +hostprogs-y += tracex2 test_verifier-objs := test_verifier.o libbpf.o test_maps-objs := test_maps.o libbpf.o @@ -14,12 +15,14 @@ sock_example-objs := sock_example.o libbpf.o sockex1-objs := bpf_load.o libbpf.o sockex1_user.o sockex2-objs := bpf_load.o libbpf.o sockex2_user.o tracex1-objs := bpf_load.o libbpf.o tracex1_user.o +tracex2-objs := bpf_load.o libbpf.o tracex2_user.o # Tell kbuild to always build the programs always := $(hostprogs-y) always += sockex1_kern.o always += sockex2_kern.o always += tracex1_kern.o +always += tracex2_kern.o HOSTCFLAGS += -I$(objtree)/usr/include @@ -27,6 +30,7 @@ HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable HOSTLOADLIBES_sockex1 += -lelf HOSTLOADLIBES_sockex2 += -lelf HOSTLOADLIBES_tracex1 += -lelf +HOSTLOADLIBES_tracex2 += -lelf # point this to your LLVM backend with bpf support LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c new file mode 100644 index ..334348335795 --- /dev/null +++ b/samples/bpf/tracex2_kern.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include "bpf_helpers.h" + +struct bpf_map_def SEC("maps") my_map = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(long), + .value_size = sizeof(long), + .max_entries = 1024, +}; + +/* kprobe is NOT a stable ABI + * This bpf+kprobe example can stop working any time. + */ +SEC("kprobe/kfree_skb") +int bpf_prog2(struct pt_regs *ctx) +{ + long loc = 0; + long init_val = 1; + long *value; + + /* x64 specific: read ip of kfree_skb caller. +* non-portable version of __builtin_return_address(0) +*/ + bpf_probe_read(, sizeof(loc), (void *)ctx->sp); + + value = bpf_map_lookup_elem(_map, ); + if (value) + *value += 1; + else + bpf_map_update_elem(_map, , _val, BPF_ANY); + return 0; +} + +static unsigned int log2(unsigned int v) +{ + unsigned int r; + unsigned int shift; + + r = (v > 0x) << 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
[PATCH v6 tip 6/8] samples: bpf: counting example for kfree_skb and write syscall
this example has two probes in one C file that attach to different kprove events and use two different maps. 1st probe is x64 specific equivalent of dropmon. It attaches to kfree_skb, retrevies 'ip' address of kfree_skb() caller and counts number of packet drops at that 'ip' address. User space prints 'location - count' map every second. 2nd probe attaches to kprobe:sys_write and computes a histogram of different write sizes Usage: $ sudo tracex2 location 0x81695995 count 1 location 0x816d0da9 count 2 location 0x81695995 count 2 location 0x816d0da9 count 2 location 0x81695995 count 3 location 0x816d0da9 count 2 557145+0 records in 557145+0 records out 285258240 bytes (285 MB) copied, 1.02379 s, 279 MB/s syscall write() stats byte_size : count distribution 1 - 1: 3| | 2 - 3: 0| | 4 - 7: 0| | 8 - 15 : 0| | 16 - 31 : 2| | 32 - 63 : 3| | 64 - 127 : 1| | 128 - 255 : 1| | 256 - 511 : 0| | 512 - 1023 : 1118968 |* | Ctrl-C at any time. Kernel will auto cleanup maps and programs $ addr2line -ape ./bld_x64/vmlinux 0x81695995 0x816d0da9 0x81695995: ./bld_x64/../net/ipv4/icmp.c:1038 0x816d0da9: ./bld_x64/../net/unix/af_unix.c:1231 Signed-off-by: Alexei Starovoitov a...@plumgrid.com --- samples/bpf/Makefile |4 ++ samples/bpf/tracex2_kern.c | 86 +++ samples/bpf/tracex2_user.c | 95 3 files changed, 185 insertions(+) create mode 100644 samples/bpf/tracex2_kern.c create mode 100644 samples/bpf/tracex2_user.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 51f6f01e5a3a..6dd272143733 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -7,6 +7,7 @@ hostprogs-y += sock_example hostprogs-y += sockex1 hostprogs-y += sockex2 hostprogs-y += tracex1 +hostprogs-y += tracex2 test_verifier-objs := test_verifier.o libbpf.o test_maps-objs := test_maps.o libbpf.o @@ -14,12 +15,14 @@ sock_example-objs := sock_example.o libbpf.o sockex1-objs := bpf_load.o libbpf.o sockex1_user.o sockex2-objs := bpf_load.o libbpf.o sockex2_user.o tracex1-objs := bpf_load.o libbpf.o tracex1_user.o +tracex2-objs := bpf_load.o libbpf.o tracex2_user.o # Tell kbuild to always build the programs always := $(hostprogs-y) always += sockex1_kern.o always += sockex2_kern.o always += tracex1_kern.o +always += tracex2_kern.o HOSTCFLAGS += -I$(objtree)/usr/include @@ -27,6 +30,7 @@ HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable HOSTLOADLIBES_sockex1 += -lelf HOSTLOADLIBES_sockex2 += -lelf HOSTLOADLIBES_tracex1 += -lelf +HOSTLOADLIBES_tracex2 += -lelf # point this to your LLVM backend with bpf support LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c new file mode 100644 index ..334348335795 --- /dev/null +++ b/samples/bpf/tracex2_kern.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#include linux/skbuff.h +#include linux/netdevice.h +#include linux/version.h +#include uapi/linux/bpf.h +#include bpf_helpers.h + +struct bpf_map_def SEC(maps) my_map = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(long), + .value_size = sizeof(long), + .max_entries = 1024, +}; + +/* kprobe is NOT a stable ABI + * This bpf+kprobe example can stop working any time. + */ +SEC(kprobe/kfree_skb) +int bpf_prog2(struct pt_regs *ctx) +{ + long loc = 0; + long init_val = 1; + long *value; + + /* x64 specific: read ip of kfree_skb caller. +* non-portable version of __builtin_return_address(0) +*/ + bpf_probe_read(loc, sizeof(loc), (void *)ctx-sp); + + value = bpf_map_lookup_elem(my_map, loc); + if (value) + *value += 1; + else + bpf_map_update_elem(my_map, loc, init_val, BPF_ANY); + return 0; +} + +static unsigned int log2(unsigned int v) +{ + unsigned int r; + unsigned int shift; + + r = (v 0x) 4; v = r; + shift = (v 0xFF) 3; v = shift; r |= shift; + shift = (v 0xF) 2; v =