summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@fb.com>2016-03-08 18:07:52 -0500
committerDavid S. Miller <davem@davemloft.net>2016-03-08 23:22:02 -0500
commit9d8b612d88e81c2cf7dbc0d4a827da6ca0d848e0 (patch)
tree224ffcb5af7fa6d63fc1e25abd718e59667b14f8 /samples
parente28e87ed474c5a0b378c66fb85efc8e487f4f63f (diff)
samples/bpf: add bpf map stress test
this test calls bpf programs from different contexts: from inside of slub, from rcu, from pretty much everywhere, since it kprobes all spin_lock functions. It stresses the bpf hash and percpu map pre-allocation, deallocation logic and call_rcu mechanisms. User space part adding more stress by walking and deleting map elements. Note that due to nature bpf_load.c the earlier kprobe+bpf programs are already active while loader loads new programs, creates new kprobes and attaches them. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/Makefile4
-rw-r--r--samples/bpf/spintest_kern.c59
-rw-r--r--samples/bpf/spintest_user.c50
3 files changed, 113 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index c4f8ae0c8afe..75a13e742ab4 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -17,6 +17,7 @@ hostprogs-y += tracex6
17hostprogs-y += trace_output 17hostprogs-y += trace_output
18hostprogs-y += lathist 18hostprogs-y += lathist
19hostprogs-y += offwaketime 19hostprogs-y += offwaketime
20hostprogs-y += spintest
20 21
21test_verifier-objs := test_verifier.o libbpf.o 22test_verifier-objs := test_verifier.o libbpf.o
22test_maps-objs := test_maps.o libbpf.o 23test_maps-objs := test_maps.o libbpf.o
@@ -34,6 +35,7 @@ tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
34trace_output-objs := bpf_load.o libbpf.o trace_output_user.o 35trace_output-objs := bpf_load.o libbpf.o trace_output_user.o
35lathist-objs := bpf_load.o libbpf.o lathist_user.o 36lathist-objs := bpf_load.o libbpf.o lathist_user.o
36offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o 37offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o
38spintest-objs := bpf_load.o libbpf.o spintest_user.o
37 39
38# Tell kbuild to always build the programs 40# Tell kbuild to always build the programs
39always := $(hostprogs-y) 41always := $(hostprogs-y)
@@ -50,6 +52,7 @@ always += trace_output_kern.o
50always += tcbpf1_kern.o 52always += tcbpf1_kern.o
51always += lathist_kern.o 53always += lathist_kern.o
52always += offwaketime_kern.o 54always += offwaketime_kern.o
55always += spintest_kern.o
53 56
54HOSTCFLAGS += -I$(objtree)/usr/include 57HOSTCFLAGS += -I$(objtree)/usr/include
55 58
@@ -67,6 +70,7 @@ HOSTLOADLIBES_tracex6 += -lelf
67HOSTLOADLIBES_trace_output += -lelf -lrt 70HOSTLOADLIBES_trace_output += -lelf -lrt
68HOSTLOADLIBES_lathist += -lelf 71HOSTLOADLIBES_lathist += -lelf
69HOSTLOADLIBES_offwaketime += -lelf 72HOSTLOADLIBES_offwaketime += -lelf
73HOSTLOADLIBES_spintest += -lelf
70 74
71# point this to your LLVM backend with bpf support 75# point this to your LLVM backend with bpf support
72LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc 76LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
diff --git a/samples/bpf/spintest_kern.c b/samples/bpf/spintest_kern.c
new file mode 100644
index 000000000000..ef8ac33bb2e9
--- /dev/null
+++ b/samples/bpf/spintest_kern.c
@@ -0,0 +1,59 @@
1/* Copyright (c) 2016, Facebook
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/skbuff.h>
8#include <linux/netdevice.h>
9#include <linux/version.h>
10#include <uapi/linux/bpf.h>
11#include "bpf_helpers.h"
12
13struct bpf_map_def SEC("maps") my_map = {
14 .type = BPF_MAP_TYPE_HASH,
15 .key_size = sizeof(long),
16 .value_size = sizeof(long),
17 .max_entries = 1024,
18};
19struct bpf_map_def SEC("maps") my_map2 = {
20 .type = BPF_MAP_TYPE_PERCPU_HASH,
21 .key_size = sizeof(long),
22 .value_size = sizeof(long),
23 .max_entries = 1024,
24};
25
26#define PROG(foo) \
27int foo(struct pt_regs *ctx) \
28{ \
29 long v = ctx->ip, *val; \
30\
31 val = bpf_map_lookup_elem(&my_map, &v); \
32 bpf_map_update_elem(&my_map, &v, &v, BPF_ANY); \
33 bpf_map_update_elem(&my_map2, &v, &v, BPF_ANY); \
34 bpf_map_delete_elem(&my_map2, &v); \
35 return 0; \
36}
37
38/* add kprobes to all possible *spin* functions */
39SEC("kprobe/spin_unlock")PROG(p1)
40SEC("kprobe/spin_lock")PROG(p2)
41SEC("kprobe/mutex_spin_on_owner")PROG(p3)
42SEC("kprobe/rwsem_spin_on_owner")PROG(p4)
43SEC("kprobe/spin_unlock_irqrestore")PROG(p5)
44SEC("kprobe/_raw_spin_unlock_irqrestore")PROG(p6)
45SEC("kprobe/_raw_spin_unlock_bh")PROG(p7)
46SEC("kprobe/_raw_spin_unlock")PROG(p8)
47SEC("kprobe/_raw_spin_lock_irqsave")PROG(p9)
48SEC("kprobe/_raw_spin_trylock_bh")PROG(p10)
49SEC("kprobe/_raw_spin_lock_irq")PROG(p11)
50SEC("kprobe/_raw_spin_trylock")PROG(p12)
51SEC("kprobe/_raw_spin_lock")PROG(p13)
52SEC("kprobe/_raw_spin_lock_bh")PROG(p14)
53/* and to inner bpf helpers */
54SEC("kprobe/htab_map_update_elem")PROG(p15)
55SEC("kprobe/__htab_percpu_map_update_elem")PROG(p16)
56SEC("kprobe/htab_map_alloc")PROG(p17)
57
58char _license[] SEC("license") = "GPL";
59u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/spintest_user.c b/samples/bpf/spintest_user.c
new file mode 100644
index 000000000000..311ede532230
--- /dev/null
+++ b/samples/bpf/spintest_user.c
@@ -0,0 +1,50 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <linux/bpf.h>
4#include <string.h>
5#include <assert.h>
6#include <sys/resource.h>
7#include "libbpf.h"
8#include "bpf_load.h"
9
10int main(int ac, char **argv)
11{
12 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
13 long key, next_key, value;
14 char filename[256];
15 struct ksym *sym;
16 int i;
17
18 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
19 setrlimit(RLIMIT_MEMLOCK, &r);
20
21 if (load_kallsyms()) {
22 printf("failed to process /proc/kallsyms\n");
23 return 2;
24 }
25
26 if (load_bpf_file(filename)) {
27 printf("%s", bpf_log_buf);
28 return 1;
29 }
30
31 for (i = 0; i < 5; i++) {
32 key = 0;
33 printf("kprobing funcs:");
34 while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
35 bpf_lookup_elem(map_fd[0], &next_key, &value);
36 assert(next_key == value);
37 sym = ksym_search(value);
38 printf(" %s", sym->name);
39 key = next_key;
40 }
41 if (key)
42 printf("\n");
43 key = 0;
44 while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0)
45 bpf_delete_elem(map_fd[0], &next_key);
46 sleep(1);
47 }
48
49 return 0;
50}