1*4882a593Smuzhiyun /* Copyright (c) 2016 Facebook
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or
4*4882a593Smuzhiyun * modify it under the terms of version 2 of the GNU General Public
5*4882a593Smuzhiyun * License as published by the Free Software Foundation.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun #include <linux/skbuff.h>
8*4882a593Smuzhiyun #include <linux/netdevice.h>
9*4882a593Smuzhiyun #include <linux/version.h>
10*4882a593Smuzhiyun #include <uapi/linux/bpf.h>
11*4882a593Smuzhiyun #include <bpf/bpf_helpers.h>
12*4882a593Smuzhiyun #include <bpf/bpf_tracing.h>
13*4882a593Smuzhiyun #include <bpf/bpf_core_read.h>
14*4882a593Smuzhiyun #include "trace_common.h"
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define MAX_ENTRIES 1000
17*4882a593Smuzhiyun #define MAX_NR_CPUS 1024
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun struct {
20*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_HASH);
21*4882a593Smuzhiyun __type(key, u32);
22*4882a593Smuzhiyun __type(value, long);
23*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
24*4882a593Smuzhiyun } hash_map SEC(".maps");
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun struct {
27*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_LRU_HASH);
28*4882a593Smuzhiyun __type(key, u32);
29*4882a593Smuzhiyun __type(value, long);
30*4882a593Smuzhiyun __uint(max_entries, 10000);
31*4882a593Smuzhiyun } lru_hash_map SEC(".maps");
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun struct {
34*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_LRU_HASH);
35*4882a593Smuzhiyun __type(key, u32);
36*4882a593Smuzhiyun __type(value, long);
37*4882a593Smuzhiyun __uint(max_entries, 10000);
38*4882a593Smuzhiyun __uint(map_flags, BPF_F_NO_COMMON_LRU);
39*4882a593Smuzhiyun } nocommon_lru_hash_map SEC(".maps");
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun struct inner_lru {
42*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_LRU_HASH);
43*4882a593Smuzhiyun __type(key, u32);
44*4882a593Smuzhiyun __type(value, long);
45*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
46*4882a593Smuzhiyun __uint(map_flags, BPF_F_NUMA_NODE);
47*4882a593Smuzhiyun __uint(numa_node, 0);
48*4882a593Smuzhiyun } inner_lru_hash_map SEC(".maps");
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun struct {
51*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
52*4882a593Smuzhiyun __uint(max_entries, MAX_NR_CPUS);
53*4882a593Smuzhiyun __uint(key_size, sizeof(u32));
54*4882a593Smuzhiyun __array(values, struct inner_lru); /* use inner_lru as inner map */
55*4882a593Smuzhiyun } array_of_lru_hashs SEC(".maps") = {
56*4882a593Smuzhiyun /* statically initialize the first element */
57*4882a593Smuzhiyun .values = { &inner_lru_hash_map },
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun struct {
61*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_PERCPU_HASH);
62*4882a593Smuzhiyun __uint(key_size, sizeof(u32));
63*4882a593Smuzhiyun __uint(value_size, sizeof(long));
64*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
65*4882a593Smuzhiyun } percpu_hash_map SEC(".maps");
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun struct {
68*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_HASH);
69*4882a593Smuzhiyun __type(key, u32);
70*4882a593Smuzhiyun __type(value, long);
71*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
72*4882a593Smuzhiyun __uint(map_flags, BPF_F_NO_PREALLOC);
73*4882a593Smuzhiyun } hash_map_alloc SEC(".maps");
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun struct {
76*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_PERCPU_HASH);
77*4882a593Smuzhiyun __uint(key_size, sizeof(u32));
78*4882a593Smuzhiyun __uint(value_size, sizeof(long));
79*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
80*4882a593Smuzhiyun __uint(map_flags, BPF_F_NO_PREALLOC);
81*4882a593Smuzhiyun } percpu_hash_map_alloc SEC(".maps");
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun struct {
84*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_LPM_TRIE);
85*4882a593Smuzhiyun __uint(key_size, 8);
86*4882a593Smuzhiyun __uint(value_size, sizeof(long));
87*4882a593Smuzhiyun __uint(max_entries, 10000);
88*4882a593Smuzhiyun __uint(map_flags, BPF_F_NO_PREALLOC);
89*4882a593Smuzhiyun } lpm_trie_map_alloc SEC(".maps");
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun struct {
92*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_ARRAY);
93*4882a593Smuzhiyun __type(key, u32);
94*4882a593Smuzhiyun __type(value, long);
95*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
96*4882a593Smuzhiyun } array_map SEC(".maps");
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun struct {
99*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_LRU_HASH);
100*4882a593Smuzhiyun __type(key, u32);
101*4882a593Smuzhiyun __type(value, long);
102*4882a593Smuzhiyun __uint(max_entries, MAX_ENTRIES);
103*4882a593Smuzhiyun } lru_hash_lookup_map SEC(".maps");
104*4882a593Smuzhiyun
SYSCALL(sys_getuid)105*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_getuid))
106*4882a593Smuzhiyun int stress_hmap(struct pt_regs *ctx)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun u32 key = bpf_get_current_pid_tgid();
109*4882a593Smuzhiyun long init_val = 1;
110*4882a593Smuzhiyun long *value;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun bpf_map_update_elem(&hash_map, &key, &init_val, BPF_ANY);
113*4882a593Smuzhiyun value = bpf_map_lookup_elem(&hash_map, &key);
114*4882a593Smuzhiyun if (value)
115*4882a593Smuzhiyun bpf_map_delete_elem(&hash_map, &key);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun return 0;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
SYSCALL(sys_geteuid)120*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_geteuid))
121*4882a593Smuzhiyun int stress_percpu_hmap(struct pt_regs *ctx)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun u32 key = bpf_get_current_pid_tgid();
124*4882a593Smuzhiyun long init_val = 1;
125*4882a593Smuzhiyun long *value;
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun bpf_map_update_elem(&percpu_hash_map, &key, &init_val, BPF_ANY);
128*4882a593Smuzhiyun value = bpf_map_lookup_elem(&percpu_hash_map, &key);
129*4882a593Smuzhiyun if (value)
130*4882a593Smuzhiyun bpf_map_delete_elem(&percpu_hash_map, &key);
131*4882a593Smuzhiyun return 0;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
SYSCALL(sys_getgid)134*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_getgid))
135*4882a593Smuzhiyun int stress_hmap_alloc(struct pt_regs *ctx)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun u32 key = bpf_get_current_pid_tgid();
138*4882a593Smuzhiyun long init_val = 1;
139*4882a593Smuzhiyun long *value;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun bpf_map_update_elem(&hash_map_alloc, &key, &init_val, BPF_ANY);
142*4882a593Smuzhiyun value = bpf_map_lookup_elem(&hash_map_alloc, &key);
143*4882a593Smuzhiyun if (value)
144*4882a593Smuzhiyun bpf_map_delete_elem(&hash_map_alloc, &key);
145*4882a593Smuzhiyun return 0;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
SYSCALL(sys_getegid)148*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_getegid))
149*4882a593Smuzhiyun int stress_percpu_hmap_alloc(struct pt_regs *ctx)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun u32 key = bpf_get_current_pid_tgid();
152*4882a593Smuzhiyun long init_val = 1;
153*4882a593Smuzhiyun long *value;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun bpf_map_update_elem(&percpu_hash_map_alloc, &key, &init_val, BPF_ANY);
156*4882a593Smuzhiyun value = bpf_map_lookup_elem(&percpu_hash_map_alloc, &key);
157*4882a593Smuzhiyun if (value)
158*4882a593Smuzhiyun bpf_map_delete_elem(&percpu_hash_map_alloc, &key);
159*4882a593Smuzhiyun return 0;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
SYSCALL(sys_connect)162*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_connect))
163*4882a593Smuzhiyun int stress_lru_hmap_alloc(struct pt_regs *ctx)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1_CORE(ctx);
166*4882a593Smuzhiyun char fmt[] = "Failed at stress_lru_hmap_alloc. ret:%dn";
167*4882a593Smuzhiyun union {
168*4882a593Smuzhiyun u16 dst6[8];
169*4882a593Smuzhiyun struct {
170*4882a593Smuzhiyun u16 magic0;
171*4882a593Smuzhiyun u16 magic1;
172*4882a593Smuzhiyun u16 tcase;
173*4882a593Smuzhiyun u16 unused16;
174*4882a593Smuzhiyun u32 unused32;
175*4882a593Smuzhiyun u32 key;
176*4882a593Smuzhiyun };
177*4882a593Smuzhiyun } test_params;
178*4882a593Smuzhiyun struct sockaddr_in6 *in6;
179*4882a593Smuzhiyun u16 test_case;
180*4882a593Smuzhiyun int addrlen, ret;
181*4882a593Smuzhiyun long val = 1;
182*4882a593Smuzhiyun u32 key = 0;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun in6 = (struct sockaddr_in6 *)PT_REGS_PARM2_CORE(real_regs);
185*4882a593Smuzhiyun addrlen = (int)PT_REGS_PARM3_CORE(real_regs);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun if (addrlen != sizeof(*in6))
188*4882a593Smuzhiyun return 0;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun ret = bpf_probe_read_user(test_params.dst6, sizeof(test_params.dst6),
191*4882a593Smuzhiyun &in6->sin6_addr);
192*4882a593Smuzhiyun if (ret)
193*4882a593Smuzhiyun goto done;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun if (test_params.magic0 != 0xdead ||
196*4882a593Smuzhiyun test_params.magic1 != 0xbeef)
197*4882a593Smuzhiyun return 0;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun test_case = test_params.tcase;
200*4882a593Smuzhiyun if (test_case != 3)
201*4882a593Smuzhiyun key = bpf_get_prandom_u32();
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun if (test_case == 0) {
204*4882a593Smuzhiyun ret = bpf_map_update_elem(&lru_hash_map, &key, &val, BPF_ANY);
205*4882a593Smuzhiyun } else if (test_case == 1) {
206*4882a593Smuzhiyun ret = bpf_map_update_elem(&nocommon_lru_hash_map, &key, &val,
207*4882a593Smuzhiyun BPF_ANY);
208*4882a593Smuzhiyun } else if (test_case == 2) {
209*4882a593Smuzhiyun void *nolocal_lru_map;
210*4882a593Smuzhiyun int cpu = bpf_get_smp_processor_id();
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun nolocal_lru_map = bpf_map_lookup_elem(&array_of_lru_hashs,
213*4882a593Smuzhiyun &cpu);
214*4882a593Smuzhiyun if (!nolocal_lru_map) {
215*4882a593Smuzhiyun ret = -ENOENT;
216*4882a593Smuzhiyun goto done;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun ret = bpf_map_update_elem(nolocal_lru_map, &key, &val,
220*4882a593Smuzhiyun BPF_ANY);
221*4882a593Smuzhiyun } else if (test_case == 3) {
222*4882a593Smuzhiyun u32 i;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun key = test_params.key;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun #pragma clang loop unroll(full)
227*4882a593Smuzhiyun for (i = 0; i < 32; i++) {
228*4882a593Smuzhiyun bpf_map_lookup_elem(&lru_hash_lookup_map, &key);
229*4882a593Smuzhiyun key++;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun } else {
232*4882a593Smuzhiyun ret = -EINVAL;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun done:
236*4882a593Smuzhiyun if (ret)
237*4882a593Smuzhiyun bpf_trace_printk(fmt, sizeof(fmt), ret);
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun return 0;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
SYSCALL(sys_gettid)242*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_gettid))
243*4882a593Smuzhiyun int stress_lpm_trie_map_alloc(struct pt_regs *ctx)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun union {
246*4882a593Smuzhiyun u32 b32[2];
247*4882a593Smuzhiyun u8 b8[8];
248*4882a593Smuzhiyun } key;
249*4882a593Smuzhiyun unsigned int i;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun key.b32[0] = 32;
252*4882a593Smuzhiyun key.b8[4] = 192;
253*4882a593Smuzhiyun key.b8[5] = 168;
254*4882a593Smuzhiyun key.b8[6] = 0;
255*4882a593Smuzhiyun key.b8[7] = 1;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun #pragma clang loop unroll(full)
258*4882a593Smuzhiyun for (i = 0; i < 32; ++i)
259*4882a593Smuzhiyun bpf_map_lookup_elem(&lpm_trie_map_alloc, &key);
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun return 0;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun
SYSCALL(sys_getpgid)264*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_getpgid))
265*4882a593Smuzhiyun int stress_hash_map_lookup(struct pt_regs *ctx)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun u32 key = 1, i;
268*4882a593Smuzhiyun long *value;
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun #pragma clang loop unroll(full)
271*4882a593Smuzhiyun for (i = 0; i < 64; ++i)
272*4882a593Smuzhiyun value = bpf_map_lookup_elem(&hash_map, &key);
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun return 0;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
SYSCALL(sys_getppid)277*4882a593Smuzhiyun SEC("kprobe/" SYSCALL(sys_getppid))
278*4882a593Smuzhiyun int stress_array_map_lookup(struct pt_regs *ctx)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun u32 key = 1, i;
281*4882a593Smuzhiyun long *value;
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun #pragma clang loop unroll(full)
284*4882a593Smuzhiyun for (i = 0; i < 64; ++i)
285*4882a593Smuzhiyun value = bpf_map_lookup_elem(&array_map, &key);
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun return 0;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun char _license[] SEC("license") = "GPL";
291*4882a593Smuzhiyun u32 _version SEC("version") = LINUX_VERSION_CODE;
292