Skip to content

Commit 9d8b612

Browse files
4astdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e28e87e commit 9d8b612

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

samples/bpf/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ hostprogs-y += tracex6
1717
hostprogs-y += trace_output
1818
hostprogs-y += lathist
1919
hostprogs-y += offwaketime
20+
hostprogs-y += spintest
2021

2122
test_verifier-objs := test_verifier.o libbpf.o
2223
test_maps-objs := test_maps.o libbpf.o
@@ -34,6 +35,7 @@ tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
3435
trace_output-objs := bpf_load.o libbpf.o trace_output_user.o
3536
lathist-objs := bpf_load.o libbpf.o lathist_user.o
3637
offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o
38+
spintest-objs := bpf_load.o libbpf.o spintest_user.o
3739

3840
# Tell kbuild to always build the programs
3941
always := $(hostprogs-y)
@@ -50,6 +52,7 @@ always += trace_output_kern.o
5052
always += tcbpf1_kern.o
5153
always += lathist_kern.o
5254
always += offwaketime_kern.o
55+
always += spintest_kern.o
5356

5457
HOSTCFLAGS += -I$(objtree)/usr/include
5558

@@ -67,6 +70,7 @@ HOSTLOADLIBES_tracex6 += -lelf
6770
HOSTLOADLIBES_trace_output += -lelf -lrt
6871
HOSTLOADLIBES_lathist += -lelf
6972
HOSTLOADLIBES_offwaketime += -lelf
73+
HOSTLOADLIBES_spintest += -lelf
7074

7175
# point this to your LLVM backend with bpf support
7276
LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc

samples/bpf/spintest_kern.c

+59
Original file line numberDiff line numberDiff line change
@@ -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+
13+
struct 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+
};
19+
struct 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) \
27+
int 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 */
39+
SEC("kprobe/spin_unlock")PROG(p1)
40+
SEC("kprobe/spin_lock")PROG(p2)
41+
SEC("kprobe/mutex_spin_on_owner")PROG(p3)
42+
SEC("kprobe/rwsem_spin_on_owner")PROG(p4)
43+
SEC("kprobe/spin_unlock_irqrestore")PROG(p5)
44+
SEC("kprobe/_raw_spin_unlock_irqrestore")PROG(p6)
45+
SEC("kprobe/_raw_spin_unlock_bh")PROG(p7)
46+
SEC("kprobe/_raw_spin_unlock")PROG(p8)
47+
SEC("kprobe/_raw_spin_lock_irqsave")PROG(p9)
48+
SEC("kprobe/_raw_spin_trylock_bh")PROG(p10)
49+
SEC("kprobe/_raw_spin_lock_irq")PROG(p11)
50+
SEC("kprobe/_raw_spin_trylock")PROG(p12)
51+
SEC("kprobe/_raw_spin_lock")PROG(p13)
52+
SEC("kprobe/_raw_spin_lock_bh")PROG(p14)
53+
/* and to inner bpf helpers */
54+
SEC("kprobe/htab_map_update_elem")PROG(p15)
55+
SEC("kprobe/__htab_percpu_map_update_elem")PROG(p16)
56+
SEC("kprobe/htab_map_alloc")PROG(p17)
57+
58+
char _license[] SEC("license") = "GPL";
59+
u32 _version SEC("version") = LINUX_VERSION_CODE;

samples/bpf/spintest_user.c

+50
Original file line numberDiff line numberDiff line change
@@ -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+
10+
int 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+
}

0 commit comments

Comments
 (0)