Skip to content

Commit f1e5d53

Browse files
committed
BPF vmexit count example
1 parent c4cc091 commit f1e5d53

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

bpf/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@ TOOLS_PATH := $(BPF_SAMPLES_PATH)/../../tools
99

1010
# List of programs to build
1111
tprogs-y := demo
12+
tprogs-y += vmexit
1213

1314
# Libbpf dependencies
1415
LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
1516

1617
demo-objs := trace_helpers.o
1718
demo-objs += demo_user.o
1819

20+
vmexit-objs := trace_helpers.o
21+
vmexit-objs += vmexit_user.o
22+
1923
# Tell kbuild to always build the programs
2024
always-y := $(tprogs-y)
2125
always-y += demo_kern.o
26+
always-y += vmexit_kern.o
2227

2328
ifeq ($(ARCH), arm)
2429
# Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux

bpf/vmexit_kern.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <linux/ptrace.h>
2+
#include <linux/version.h>
3+
#include <uapi/linux/bpf.h>
4+
#include <uapi/linux/seccomp.h>
5+
#include <uapi/linux/unistd.h>
6+
#include <bpf/bpf_helpers.h>
7+
#include <bpf/bpf_tracing.h>
8+
9+
struct {
10+
__uint(type, BPF_MAP_TYPE_HASH);
11+
__type(key, int);
12+
__type(value, int);
13+
__uint(max_entries, 1000);
14+
} my_map SEC(".maps");
15+
16+
SEC("tracepoint/kvm/kvm_exit")
17+
int mybpfprog(struct pt_regs *ctx)
18+
{
19+
int *value;
20+
int exit_count = 0;
21+
char fmt[] = "pid: %d %d %d\n";
22+
int pid;
23+
24+
pid = bpf_get_current_pid_tgid();
25+
26+
value = bpf_map_lookup_elem(&my_map, &pid);
27+
if (value)
28+
{
29+
/* increse vmexit in each call */
30+
exit_count = ++(*value);
31+
bpf_trace_printk(fmt, sizeof(fmt), pid, exit_count, *value);
32+
}
33+
bpf_map_update_elem(&my_map, &pid, &exit_count, BPF_ANY);
34+
35+
return 0;
36+
}
37+
38+
char _license[] SEC("license") = "GPL";
39+
u32 _version SEC("version") = LINUX_VERSION_CODE;

bpf/vmexit_user.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <linux/filter.h>
5+
#include <linux/seccomp.h>
6+
#include <sys/prctl.h>
7+
#include <bpf/bpf.h>
8+
#include <bpf/libbpf.h>
9+
#include <sys/resource.h>
10+
#include "trace_helpers.h"
11+
12+
#define NR_VCPU 4
13+
14+
int main(int argc, char *argv[])
15+
{
16+
struct bpf_link *link = NULL;
17+
struct bpf_program *prog;
18+
struct bpf_object *obj;
19+
char filename[256];
20+
int i, fd;
21+
int cur, sum = 0, delta = 0;
22+
/*
23+
* pstree can print out each vcpu thread id
24+
* pstree -t -p `vminfo -n demo-3 -p`
25+
* qemu-system-x86(3286)─┬─{CPU 0/KVM}(3345)
26+
* ├─{CPU 1/KVM}(3355)
27+
* ├─{CPU 2/KVM}(3366)
28+
* ├─{CPU 3/KVM}(3373)
29+
*/
30+
int pids[NR_VCPU] = {3345, 3355, 3366, 3373};
31+
int prev[NR_VCPU] = {0, 0, 0, 0};
32+
33+
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
34+
obj = bpf_object__open_file(filename, NULL);
35+
if (libbpf_get_error(obj)) {
36+
fprintf(stderr, "ERROR: opening BPF object file failed\n");
37+
return 0;
38+
}
39+
40+
prog = bpf_object__find_program_by_name(obj, "mybpfprog");
41+
if (!prog) {
42+
printf("finding a prog in obj file failed\n");
43+
goto cleanup;
44+
}
45+
46+
/* load BPF program */
47+
if (bpf_object__load(obj)) {
48+
fprintf(stderr, "ERROR: loading BPF object file failed\n");
49+
goto cleanup;
50+
}
51+
52+
link = bpf_program__attach(prog);
53+
if (libbpf_get_error(link)) {
54+
fprintf(stderr, "ERROR: bpf_program__attach failed\n");
55+
link = NULL;
56+
goto cleanup;
57+
}
58+
59+
#if 1
60+
fd = bpf_object__find_map_fd_by_name(obj, "my_map");
61+
while (1)
62+
{
63+
for (i = 0; i < NR_VCPU; i++)
64+
{
65+
bpf_map_lookup_elem(fd, &pids[i], &cur);
66+
delta = cur - prev[i];
67+
sum += delta;
68+
prev[i] = cur;
69+
}
70+
71+
sleep(1);
72+
printf("vmexit total: %d\n", sum);
73+
sum = 0;
74+
}
75+
#else
76+
read_trace_pipe();
77+
#endif
78+
79+
cleanup:
80+
bpf_link__destroy(link);
81+
bpf_object__close(obj);
82+
return 0;
83+
}

0 commit comments

Comments
 (0)