xref: /linux/tools/testing/selftests/bpf/progs/preempted_bpf_ma_op.c (revision 5f60d5f6bbc12e782fac78110b0ee62698f3b576)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2023. Huawei Technologies Co., Ltd */
3 #include <vmlinux.h>
4 #include <bpf/bpf_tracing.h>
5 #include <bpf/bpf_helpers.h>
6 
7 #include "bpf_experimental.h"
8 
9 struct bin_data {
10 	char data[256];
11 	struct bpf_spin_lock lock;
12 };
13 
14 struct map_value {
15 	struct bin_data __kptr * data;
16 };
17 
18 struct {
19 	__uint(type, BPF_MAP_TYPE_ARRAY);
20 	__type(key, int);
21 	__type(value, struct map_value);
22 	__uint(max_entries, 2048);
23 } array SEC(".maps");
24 
25 char _license[] SEC("license") = "GPL";
26 
27 bool nomem_err = false;
28 
29 static int del_array(unsigned int i, int *from)
30 {
31 	struct map_value *value;
32 	struct bin_data *old;
33 
34 	value = bpf_map_lookup_elem(&array, from);
35 	if (!value)
36 		return 1;
37 
38 	old = bpf_kptr_xchg(&value->data, NULL);
39 	if (old)
40 		bpf_obj_drop(old);
41 
42 	(*from)++;
43 	return 0;
44 }
45 
46 static int add_array(unsigned int i, int *from)
47 {
48 	struct bin_data *old, *new;
49 	struct map_value *value;
50 
51 	value = bpf_map_lookup_elem(&array, from);
52 	if (!value)
53 		return 1;
54 
55 	new = bpf_obj_new(typeof(*new));
56 	if (!new) {
57 		nomem_err = true;
58 		return 1;
59 	}
60 
61 	old = bpf_kptr_xchg(&value->data, new);
62 	if (old)
63 		bpf_obj_drop(old);
64 
65 	(*from)++;
66 	return 0;
67 }
68 
69 static void del_then_add_array(int from)
70 {
71 	int i;
72 
73 	i = from;
74 	bpf_loop(512, del_array, &i, 0);
75 
76 	i = from;
77 	bpf_loop(512, add_array, &i, 0);
78 }
79 
80 SEC("fentry/bpf_fentry_test1")
81 int BPF_PROG2(test0, int, a)
82 {
83 	del_then_add_array(0);
84 	return 0;
85 }
86 
87 SEC("fentry/bpf_fentry_test2")
88 int BPF_PROG2(test1, int, a, u64, b)
89 {
90 	del_then_add_array(512);
91 	return 0;
92 }
93 
94 SEC("fentry/bpf_fentry_test3")
95 int BPF_PROG2(test2, char, a, int, b, u64, c)
96 {
97 	del_then_add_array(1024);
98 	return 0;
99 }
100 
101 SEC("fentry/bpf_fentry_test4")
102 int BPF_PROG2(test3, void *, a, char, b, int, c, u64, d)
103 {
104 	del_then_add_array(1536);
105 	return 0;
106 }
107