diff options
Diffstat (limited to 'samples/bpf')
-rw-r--r-- | samples/bpf/Makefile | 4 | ||||
-rw-r--r-- | samples/bpf/tracex4_kern.c | 54 | ||||
-rw-r--r-- | samples/bpf/tracex4_user.c | 69 |
3 files changed, 127 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index dcd850546d52..fe98fb226e6e 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
@@ -9,6 +9,7 @@ hostprogs-y += sockex2 | |||
9 | hostprogs-y += tracex1 | 9 | hostprogs-y += tracex1 |
10 | hostprogs-y += tracex2 | 10 | hostprogs-y += tracex2 |
11 | hostprogs-y += tracex3 | 11 | hostprogs-y += tracex3 |
12 | hostprogs-y += tracex4 | ||
12 | 13 | ||
13 | test_verifier-objs := test_verifier.o libbpf.o | 14 | test_verifier-objs := test_verifier.o libbpf.o |
14 | test_maps-objs := test_maps.o libbpf.o | 15 | test_maps-objs := test_maps.o libbpf.o |
@@ -18,6 +19,7 @@ sockex2-objs := bpf_load.o libbpf.o sockex2_user.o | |||
18 | tracex1-objs := bpf_load.o libbpf.o tracex1_user.o | 19 | tracex1-objs := bpf_load.o libbpf.o tracex1_user.o |
19 | tracex2-objs := bpf_load.o libbpf.o tracex2_user.o | 20 | tracex2-objs := bpf_load.o libbpf.o tracex2_user.o |
20 | tracex3-objs := bpf_load.o libbpf.o tracex3_user.o | 21 | tracex3-objs := bpf_load.o libbpf.o tracex3_user.o |
22 | tracex4-objs := bpf_load.o libbpf.o tracex4_user.o | ||
21 | 23 | ||
22 | # Tell kbuild to always build the programs | 24 | # Tell kbuild to always build the programs |
23 | always := $(hostprogs-y) | 25 | always := $(hostprogs-y) |
@@ -26,6 +28,7 @@ always += sockex2_kern.o | |||
26 | always += tracex1_kern.o | 28 | always += tracex1_kern.o |
27 | always += tracex2_kern.o | 29 | always += tracex2_kern.o |
28 | always += tracex3_kern.o | 30 | always += tracex3_kern.o |
31 | always += tracex4_kern.o | ||
29 | 32 | ||
30 | HOSTCFLAGS += -I$(objtree)/usr/include | 33 | HOSTCFLAGS += -I$(objtree)/usr/include |
31 | 34 | ||
@@ -35,6 +38,7 @@ HOSTLOADLIBES_sockex2 += -lelf | |||
35 | HOSTLOADLIBES_tracex1 += -lelf | 38 | HOSTLOADLIBES_tracex1 += -lelf |
36 | HOSTLOADLIBES_tracex2 += -lelf | 39 | HOSTLOADLIBES_tracex2 += -lelf |
37 | HOSTLOADLIBES_tracex3 += -lelf | 40 | HOSTLOADLIBES_tracex3 += -lelf |
41 | HOSTLOADLIBES_tracex4 += -lelf -lrt | ||
38 | 42 | ||
39 | # point this to your LLVM backend with bpf support | 43 | # point this to your LLVM backend with bpf support |
40 | LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc | 44 | LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc |
diff --git a/samples/bpf/tracex4_kern.c b/samples/bpf/tracex4_kern.c new file mode 100644 index 000000000000..126b80512228 --- /dev/null +++ b/samples/bpf/tracex4_kern.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* Copyright (c) 2015 PLUMgrid, http://plumgrid.com | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of version 2 of the GNU General Public | ||
5 | * License as published by the Free Software Foundation. | ||
6 | */ | ||
7 | #include <linux/ptrace.h> | ||
8 | #include <linux/version.h> | ||
9 | #include <uapi/linux/bpf.h> | ||
10 | #include "bpf_helpers.h" | ||
11 | |||
12 | struct pair { | ||
13 | u64 val; | ||
14 | u64 ip; | ||
15 | }; | ||
16 | |||
17 | struct bpf_map_def SEC("maps") my_map = { | ||
18 | .type = BPF_MAP_TYPE_HASH, | ||
19 | .key_size = sizeof(long), | ||
20 | .value_size = sizeof(struct pair), | ||
21 | .max_entries = 1000000, | ||
22 | }; | ||
23 | |||
24 | /* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe | ||
25 | * example will no longer be meaningful | ||
26 | */ | ||
27 | SEC("kprobe/kmem_cache_free") | ||
28 | int bpf_prog1(struct pt_regs *ctx) | ||
29 | { | ||
30 | long ptr = ctx->si; | ||
31 | |||
32 | bpf_map_delete_elem(&my_map, &ptr); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | SEC("kretprobe/kmem_cache_alloc_node") | ||
37 | int bpf_prog2(struct pt_regs *ctx) | ||
38 | { | ||
39 | long ptr = ctx->ax; | ||
40 | long ip = 0; | ||
41 | |||
42 | /* get ip address of kmem_cache_alloc_node() caller */ | ||
43 | bpf_probe_read(&ip, sizeof(ip), (void *)(ctx->bp + sizeof(ip))); | ||
44 | |||
45 | struct pair v = { | ||
46 | .val = bpf_ktime_get_ns(), | ||
47 | .ip = ip, | ||
48 | }; | ||
49 | |||
50 | bpf_map_update_elem(&my_map, &ptr, &v, BPF_ANY); | ||
51 | return 0; | ||
52 | } | ||
53 | char _license[] SEC("license") = "GPL"; | ||
54 | u32 _version SEC("version") = LINUX_VERSION_CODE; | ||
diff --git a/samples/bpf/tracex4_user.c b/samples/bpf/tracex4_user.c new file mode 100644 index 000000000000..bc4a3bdea6ed --- /dev/null +++ b/samples/bpf/tracex4_user.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* Copyright (c) 2015 PLUMgrid, http://plumgrid.com | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of version 2 of the GNU General Public | ||
5 | * License as published by the Free Software Foundation. | ||
6 | */ | ||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <signal.h> | ||
10 | #include <unistd.h> | ||
11 | #include <stdbool.h> | ||
12 | #include <string.h> | ||
13 | #include <time.h> | ||
14 | #include <linux/bpf.h> | ||
15 | #include "libbpf.h" | ||
16 | #include "bpf_load.h" | ||
17 | |||
18 | struct pair { | ||
19 | long long val; | ||
20 | __u64 ip; | ||
21 | }; | ||
22 | |||
23 | static __u64 time_get_ns(void) | ||
24 | { | ||
25 | struct timespec ts; | ||
26 | |||
27 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
28 | return ts.tv_sec * 1000000000ull + ts.tv_nsec; | ||
29 | } | ||
30 | |||
31 | static void print_old_objects(int fd) | ||
32 | { | ||
33 | long long val = time_get_ns(); | ||
34 | __u64 key, next_key; | ||
35 | struct pair v; | ||
36 | |||
37 | key = write(1, "\e[1;1H\e[2J", 12); /* clear screen */ | ||
38 | |||
39 | key = -1; | ||
40 | while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) { | ||
41 | bpf_lookup_elem(map_fd[0], &next_key, &v); | ||
42 | key = next_key; | ||
43 | if (val - v.val < 1000000000ll) | ||
44 | /* object was allocated more then 1 sec ago */ | ||
45 | continue; | ||
46 | printf("obj 0x%llx is %2lldsec old was allocated at ip %llx\n", | ||
47 | next_key, (val - v.val) / 1000000000ll, v.ip); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | int main(int ac, char **argv) | ||
52 | { | ||
53 | char filename[256]; | ||
54 | int i; | ||
55 | |||
56 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | ||
57 | |||
58 | if (load_bpf_file(filename)) { | ||
59 | printf("%s", bpf_log_buf); | ||
60 | return 1; | ||
61 | } | ||
62 | |||
63 | for (i = 0; ; i++) { | ||
64 | print_old_objects(map_fd[1]); | ||
65 | sleep(1); | ||
66 | } | ||
67 | |||
68 | return 0; | ||
69 | } | ||