]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/lookup_and_delete.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / lookup_and_delete.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <test_progs.h>
4 #include "test_lookup_and_delete.skel.h"
5
6 #define START_VALUE 1234
7 #define NEW_VALUE 4321
8 #define MAX_ENTRIES 2
9
10 static int duration;
11 static int nr_cpus;
12
13 static int fill_values(int map_fd)
14 {
15         __u64 key, value = START_VALUE;
16         int err;
17
18         for (key = 1; key < MAX_ENTRIES + 1; key++) {
19                 err = bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST);
20                 if (!ASSERT_OK(err, "bpf_map_update_elem"))
21                         return -1;
22         }
23
24         return 0;
25 }
26
27 static int fill_values_percpu(int map_fd)
28 {
29         __u64 key, value[nr_cpus];
30         int i, err;
31
32         for (i = 0; i < nr_cpus; i++)
33                 value[i] = START_VALUE;
34
35         for (key = 1; key < MAX_ENTRIES + 1; key++) {
36                 err = bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST);
37                 if (!ASSERT_OK(err, "bpf_map_update_elem"))
38                         return -1;
39         }
40
41         return 0;
42 }
43
44 static struct test_lookup_and_delete *setup_prog(enum bpf_map_type map_type,
45                                                  int *map_fd)
46 {
47         struct test_lookup_and_delete *skel;
48         int err;
49
50         skel = test_lookup_and_delete__open();
51         if (!ASSERT_OK_PTR(skel, "test_lookup_and_delete__open"))
52                 return NULL;
53
54         err = bpf_map__set_type(skel->maps.hash_map, map_type);
55         if (!ASSERT_OK(err, "bpf_map__set_type"))
56                 goto cleanup;
57
58         err = bpf_map__set_max_entries(skel->maps.hash_map, MAX_ENTRIES);
59         if (!ASSERT_OK(err, "bpf_map__set_max_entries"))
60                 goto cleanup;
61
62         err = test_lookup_and_delete__load(skel);
63         if (!ASSERT_OK(err, "test_lookup_and_delete__load"))
64                 goto cleanup;
65
66         *map_fd = bpf_map__fd(skel->maps.hash_map);
67         if (!ASSERT_GE(*map_fd, 0, "bpf_map__fd"))
68                 goto cleanup;
69
70         return skel;
71
72 cleanup:
73         test_lookup_and_delete__destroy(skel);
74         return NULL;
75 }
76
77 /* Triggers BPF program that updates map with given key and value */
78 static int trigger_tp(struct test_lookup_and_delete *skel, __u64 key,
79                       __u64 value)
80 {
81         int err;
82
83         skel->bss->set_pid = getpid();
84         skel->bss->set_key = key;
85         skel->bss->set_value = value;
86
87         err = test_lookup_and_delete__attach(skel);
88         if (!ASSERT_OK(err, "test_lookup_and_delete__attach"))
89                 return -1;
90
91         syscall(__NR_getpgid);
92
93         test_lookup_and_delete__detach(skel);
94
95         return 0;
96 }
97
98 static void test_lookup_and_delete_hash(void)
99 {
100         struct test_lookup_and_delete *skel;
101         __u64 key, value;
102         int map_fd, err;
103
104         /* Setup program and fill the map. */
105         skel = setup_prog(BPF_MAP_TYPE_HASH, &map_fd);
106         if (!ASSERT_OK_PTR(skel, "setup_prog"))
107                 return;
108
109         err = fill_values(map_fd);
110         if (!ASSERT_OK(err, "fill_values"))
111                 goto cleanup;
112
113         /* Lookup and delete element. */
114         key = 1;
115         err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,
116                                               &key, sizeof(key), &value, sizeof(value), 0);
117         if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))
118                 goto cleanup;
119
120         /* Fetched value should match the initially set value. */
121         if (CHECK(value != START_VALUE, "bpf_map_lookup_and_delete_elem",
122                   "unexpected value=%lld\n", value))
123                 goto cleanup;
124
125         /* Check that the entry is non existent. */
126         err = bpf_map_lookup_elem(map_fd, &key, &value);
127         if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))
128                 goto cleanup;
129
130 cleanup:
131         test_lookup_and_delete__destroy(skel);
132 }
133
134 static void test_lookup_and_delete_percpu_hash(void)
135 {
136         struct test_lookup_and_delete *skel;
137         __u64 key, val, value[nr_cpus];
138         int map_fd, err, i;
139
140         /* Setup program and fill the map. */
141         skel = setup_prog(BPF_MAP_TYPE_PERCPU_HASH, &map_fd);
142         if (!ASSERT_OK_PTR(skel, "setup_prog"))
143                 return;
144
145         err = fill_values_percpu(map_fd);
146         if (!ASSERT_OK(err, "fill_values_percpu"))
147                 goto cleanup;
148
149         /* Lookup and delete element. */
150         key = 1;
151         err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,
152                                               &key, sizeof(key), value, sizeof(value), 0);
153         if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))
154                 goto cleanup;
155
156         for (i = 0; i < nr_cpus; i++) {
157                 val = value[i];
158
159                 /* Fetched value should match the initially set value. */
160                 if (CHECK(val != START_VALUE, "map value",
161                           "unexpected for cpu %d: %lld\n", i, val))
162                         goto cleanup;
163         }
164
165         /* Check that the entry is non existent. */
166         err = bpf_map_lookup_elem(map_fd, &key, value);
167         if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))
168                 goto cleanup;
169
170 cleanup:
171         test_lookup_and_delete__destroy(skel);
172 }
173
174 static void test_lookup_and_delete_lru_hash(void)
175 {
176         struct test_lookup_and_delete *skel;
177         __u64 key, value;
178         int map_fd, err;
179
180         /* Setup program and fill the LRU map. */
181         skel = setup_prog(BPF_MAP_TYPE_LRU_HASH, &map_fd);
182         if (!ASSERT_OK_PTR(skel, "setup_prog"))
183                 return;
184
185         err = fill_values(map_fd);
186         if (!ASSERT_OK(err, "fill_values"))
187                 goto cleanup;
188
189         /* Insert new element at key=3, should reuse LRU element. */
190         key = 3;
191         err = trigger_tp(skel, key, NEW_VALUE);
192         if (!ASSERT_OK(err, "trigger_tp"))
193                 goto cleanup;
194
195         /* Lookup and delete element 3. */
196         err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,
197                                               &key, sizeof(key), &value, sizeof(value), 0);
198         if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))
199                 goto cleanup;
200
201         /* Value should match the new value. */
202         if (CHECK(value != NEW_VALUE, "bpf_map_lookup_and_delete_elem",
203                   "unexpected value=%lld\n", value))
204                 goto cleanup;
205
206         /* Check that entries 3 and 1 are non existent. */
207         err = bpf_map_lookup_elem(map_fd, &key, &value);
208         if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))
209                 goto cleanup;
210
211         key = 1;
212         err = bpf_map_lookup_elem(map_fd, &key, &value);
213         if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))
214                 goto cleanup;
215
216 cleanup:
217         test_lookup_and_delete__destroy(skel);
218 }
219
220 static void test_lookup_and_delete_lru_percpu_hash(void)
221 {
222         struct test_lookup_and_delete *skel;
223         __u64 key, val, value[nr_cpus];
224         int map_fd, err, i, cpucnt = 0;
225
226         /* Setup program and fill the LRU map. */
227         skel = setup_prog(BPF_MAP_TYPE_LRU_PERCPU_HASH, &map_fd);
228         if (!ASSERT_OK_PTR(skel, "setup_prog"))
229                 return;
230
231         err = fill_values_percpu(map_fd);
232         if (!ASSERT_OK(err, "fill_values_percpu"))
233                 goto cleanup;
234
235         /* Insert new element at key=3, should reuse LRU element 1. */
236         key = 3;
237         err = trigger_tp(skel, key, NEW_VALUE);
238         if (!ASSERT_OK(err, "trigger_tp"))
239                 goto cleanup;
240
241         /* Clean value. */
242         for (i = 0; i < nr_cpus; i++)
243                 value[i] = 0;
244
245         /* Lookup and delete element 3. */
246         err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,
247                                               &key, sizeof(key), value, sizeof(value), 0);
248         if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))
249                 goto cleanup;
250
251         /* Check if only one CPU has set the value. */
252         for (i = 0; i < nr_cpus; i++) {
253                 val = value[i];
254                 if (val) {
255                         if (CHECK(val != NEW_VALUE, "map value",
256                                   "unexpected for cpu %d: %lld\n", i, val))
257                                 goto cleanup;
258                         cpucnt++;
259                 }
260         }
261         if (CHECK(cpucnt != 1, "map value", "set for %d CPUs instead of 1!\n",
262                   cpucnt))
263                 goto cleanup;
264
265         /* Check that entries 3 and 1 are non existent. */
266         err = bpf_map_lookup_elem(map_fd, &key, &value);
267         if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))
268                 goto cleanup;
269
270         key = 1;
271         err = bpf_map_lookup_elem(map_fd, &key, &value);
272         if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))
273                 goto cleanup;
274
275 cleanup:
276         test_lookup_and_delete__destroy(skel);
277 }
278
279 void test_lookup_and_delete(void)
280 {
281         nr_cpus = bpf_num_possible_cpus();
282
283         if (test__start_subtest("lookup_and_delete"))
284                 test_lookup_and_delete_hash();
285         if (test__start_subtest("lookup_and_delete_percpu"))
286                 test_lookup_and_delete_percpu_hash();
287         if (test__start_subtest("lookup_and_delete_lru"))
288                 test_lookup_and_delete_lru_hash();
289         if (test__start_subtest("lookup_and_delete_lru_percpu"))
290                 test_lookup_and_delete_lru_percpu_hash();
291 }
This page took 0.044542 seconds and 4 git commands to generate.