xref: /linux/tools/testing/selftests/bpf/prog_tests/linked_list.c (revision 90b83efa6701656e02c86e7df2cb1765ea602d07)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <bpf/btf.h>
3 #include <test_btf.h>
4 #include <linux/btf.h>
5 #include <test_progs.h>
6 #include <network_helpers.h>
7 
8 #include "linked_list.skel.h"
9 #include "linked_list_fail.skel.h"
10 #include "linked_list_peek.skel.h"
11 
12 static char log_buf[1024 * 1024];
13 
14 static struct {
15 	const char *prog_name;
16 	const char *err_msg;
17 } linked_list_fail_tests[] = {
18 #define TEST(test, off) \
19 	{ #test "_missing_lock_push_front", \
20 	  "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \
21 	{ #test "_missing_lock_push_back", \
22 	  "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \
23 	{ #test "_missing_lock_pop_front", \
24 	  "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \
25 	{ #test "_missing_lock_pop_back", \
26 	  "bpf_spin_lock at off=" #off " must be held for bpf_list_head" },
27 	TEST(kptr, 40)
28 	TEST(global, 16)
29 	TEST(map, 0)
30 	TEST(inner_map, 0)
31 #undef TEST
32 #define TEST(test, op) \
33 	{ #test "_kptr_incorrect_lock_" #op, \
34 	  "held lock and object are not in the same allocation\n" \
35 	  "bpf_spin_lock at off=40 must be held for bpf_list_head" }, \
36 	{ #test "_global_incorrect_lock_" #op, \
37 	  "held lock and object are not in the same allocation\n" \
38 	  "bpf_spin_lock at off=16 must be held for bpf_list_head" }, \
39 	{ #test "_map_incorrect_lock_" #op, \
40 	  "held lock and object are not in the same allocation\n" \
41 	  "bpf_spin_lock at off=0 must be held for bpf_list_head" }, \
42 	{ #test "_inner_map_incorrect_lock_" #op, \
43 	  "held lock and object are not in the same allocation\n" \
44 	  "bpf_spin_lock at off=0 must be held for bpf_list_head" },
45 	TEST(kptr, push_front)
46 	TEST(kptr, push_back)
47 	TEST(kptr, pop_front)
48 	TEST(kptr, pop_back)
49 	TEST(global, push_front)
50 	TEST(global, push_back)
51 	TEST(global, pop_front)
52 	TEST(global, pop_back)
53 	TEST(map, push_front)
54 	TEST(map, push_back)
55 	TEST(map, pop_front)
56 	TEST(map, pop_back)
57 	TEST(inner_map, push_front)
58 	TEST(inner_map, push_back)
59 	TEST(inner_map, pop_front)
60 	TEST(inner_map, pop_back)
61 #undef TEST
62 	{ "map_compat_kprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
63 	{ "map_compat_kretprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
64 	{ "map_compat_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
65 	{ "map_compat_perf", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
66 	{ "map_compat_raw_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
67 	{ "map_compat_raw_tp_w", "tracing progs cannot use bpf_{list_head,rb_root} yet" },
68 	{ "obj_type_id_oor", "local type ID argument must be in range [0, U32_MAX]" },
69 	{ "obj_new_no_composite", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" },
70 	{ "obj_new_no_struct", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" },
71 	{ "obj_drop_non_zero_off", "R1 must have zero offset when passed to release func" },
72 	{ "new_null_ret", "R0 invalid mem access 'ptr_or_null_'" },
73 	{ "obj_new_acq", "Unreleased reference id=" },
74 	{ "use_after_drop", "invalid mem access 'scalar'" },
75 	{ "ptr_walk_scalar", "type=scalar expected=percpu_ptr_" },
76 	{ "direct_read_lock", "direct access to bpf_spin_lock is disallowed" },
77 	{ "direct_write_lock", "direct access to bpf_spin_lock is disallowed" },
78 	{ "direct_read_head", "direct access to bpf_list_head is disallowed" },
79 	{ "direct_write_head", "direct access to bpf_list_head is disallowed" },
80 	{ "direct_read_node", "direct access to bpf_list_node is disallowed" },
81 	{ "direct_write_node", "direct access to bpf_list_node is disallowed" },
82 	{ "use_after_unlock_push_front", "invalid mem access 'scalar'" },
83 	{ "use_after_unlock_push_back", "invalid mem access 'scalar'" },
84 	{ "double_push_front", "arg#1 expected pointer to allocated object" },
85 	{ "double_push_back", "arg#1 expected pointer to allocated object" },
86 	{ "no_node_value_type", "bpf_list_node not found at offset=0" },
87 	{ "incorrect_value_type",
88 	  "operation on bpf_list_head expects arg#1 bpf_list_node at offset=48 in struct foo, "
89 	  "but arg is at offset=0 in struct bar" },
90 	{ "incorrect_node_var_off", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },
91 	{ "incorrect_node_off1", "bpf_list_node not found at offset=49" },
92 	{ "incorrect_node_off2", "arg#1 offset=0, but expected bpf_list_node at offset=48 in struct foo" },
93 	{ "no_head_type", "bpf_list_head not found at offset=0" },
94 	{ "incorrect_head_var_off1", "R1 doesn't have constant offset" },
95 	{ "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },
96 	{ "incorrect_head_off1", "bpf_list_head not found at offset=25" },
97 	{ "incorrect_head_off2", "bpf_list_head not found at offset=1" },
98 	{ "pop_front_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" },
99 	{ "pop_back_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" },
100 };
101 
102 static void test_linked_list_fail_prog(const char *prog_name, const char *err_msg)
103 {
104 	LIBBPF_OPTS(bpf_object_open_opts, opts, .kernel_log_buf = log_buf,
105 						.kernel_log_size = sizeof(log_buf),
106 						.kernel_log_level = 1);
107 	struct linked_list_fail *skel;
108 	struct bpf_program *prog;
109 	int ret;
110 
111 	skel = linked_list_fail__open_opts(&opts);
112 	if (!ASSERT_OK_PTR(skel, "linked_list_fail__open_opts"))
113 		return;
114 
115 	prog = bpf_object__find_program_by_name(skel->obj, prog_name);
116 	if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
117 		goto end;
118 
119 	bpf_program__set_autoload(prog, true);
120 
121 	ret = linked_list_fail__load(skel);
122 	if (!ASSERT_ERR(ret, "linked_list_fail__load must fail"))
123 		goto end;
124 
125 	if (!ASSERT_OK_PTR(strstr(log_buf, err_msg), "expected error message")) {
126 		fprintf(stderr, "Expected: %s\n", err_msg);
127 		fprintf(stderr, "Verifier: %s\n", log_buf);
128 	}
129 
130 end:
131 	linked_list_fail__destroy(skel);
132 }
133 
134 static void clear_fields(struct bpf_map *map)
135 {
136 	char buf[24];
137 	int key = 0;
138 
139 	memset(buf, 0xff, sizeof(buf));
140 	ASSERT_OK(bpf_map__update_elem(map, &key, sizeof(key), buf, sizeof(buf), 0), "check_and_free_fields");
141 }
142 
143 enum {
144 	TEST_ALL,
145 	PUSH_POP,
146 	PUSH_POP_MULT,
147 	LIST_IN_LIST,
148 };
149 
150 static void test_linked_list_success(int mode, bool leave_in_map)
151 {
152 	LIBBPF_OPTS(bpf_test_run_opts, opts,
153 		.data_in = &pkt_v4,
154 		.data_size_in = sizeof(pkt_v4),
155 		.repeat = 1,
156 	);
157 	struct linked_list *skel;
158 	int ret;
159 
160 	skel = linked_list__open_and_load();
161 	if (!ASSERT_OK_PTR(skel, "linked_list__open_and_load"))
162 		return;
163 
164 	if (mode == LIST_IN_LIST)
165 		goto lil;
166 	if (mode == PUSH_POP_MULT)
167 		goto ppm;
168 
169 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_push_pop), &opts);
170 	ASSERT_OK(ret, "map_list_push_pop");
171 	ASSERT_OK(opts.retval, "map_list_push_pop retval");
172 	if (!leave_in_map)
173 		clear_fields(skel->maps.array_map);
174 
175 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_push_pop), &opts);
176 	ASSERT_OK(ret, "inner_map_list_push_pop");
177 	ASSERT_OK(opts.retval, "inner_map_list_push_pop retval");
178 	if (!leave_in_map)
179 		clear_fields(skel->maps.inner_map);
180 
181 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop), &opts);
182 	ASSERT_OK(ret, "global_list_push_pop");
183 	ASSERT_OK(opts.retval, "global_list_push_pop retval");
184 	if (!leave_in_map)
185 		clear_fields(skel->maps.bss_A);
186 
187 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop_nested), &opts);
188 	ASSERT_OK(ret, "global_list_push_pop_nested");
189 	ASSERT_OK(opts.retval, "global_list_push_pop_nested retval");
190 	if (!leave_in_map)
191 		clear_fields(skel->maps.bss_A);
192 
193 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_array_push_pop), &opts);
194 	ASSERT_OK(ret, "global_list_array_push_pop");
195 	ASSERT_OK(opts.retval, "global_list_array_push_pop retval");
196 	if (!leave_in_map)
197 		clear_fields(skel->maps.bss_A);
198 
199 	if (mode == PUSH_POP)
200 		goto end;
201 
202 ppm:
203 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_push_pop_multiple), &opts);
204 	ASSERT_OK(ret, "map_list_push_pop_multiple");
205 	ASSERT_OK(opts.retval, "map_list_push_pop_multiple retval");
206 	if (!leave_in_map)
207 		clear_fields(skel->maps.array_map);
208 
209 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_push_pop_multiple), &opts);
210 	ASSERT_OK(ret, "inner_map_list_push_pop_multiple");
211 	ASSERT_OK(opts.retval, "inner_map_list_push_pop_multiple retval");
212 	if (!leave_in_map)
213 		clear_fields(skel->maps.inner_map);
214 
215 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop_multiple), &opts);
216 	ASSERT_OK(ret, "global_list_push_pop_multiple");
217 	ASSERT_OK(opts.retval, "global_list_push_pop_multiple retval");
218 	if (!leave_in_map)
219 		clear_fields(skel->maps.bss_A);
220 
221 	if (mode == PUSH_POP_MULT)
222 		goto end;
223 
224 lil:
225 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_in_list), &opts);
226 	ASSERT_OK(ret, "map_list_in_list");
227 	ASSERT_OK(opts.retval, "map_list_in_list retval");
228 	if (!leave_in_map)
229 		clear_fields(skel->maps.array_map);
230 
231 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_in_list), &opts);
232 	ASSERT_OK(ret, "inner_map_list_in_list");
233 	ASSERT_OK(opts.retval, "inner_map_list_in_list retval");
234 	if (!leave_in_map)
235 		clear_fields(skel->maps.inner_map);
236 
237 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_in_list), &opts);
238 	ASSERT_OK(ret, "global_list_in_list");
239 	ASSERT_OK(opts.retval, "global_list_in_list retval");
240 	if (!leave_in_map)
241 		clear_fields(skel->maps.bss_A);
242 end:
243 	linked_list__destroy(skel);
244 }
245 
246 #define SPIN_LOCK 2
247 #define LIST_HEAD 3
248 #define LIST_NODE 4
249 
250 static struct btf *init_btf(void)
251 {
252 	int id, lid, hid, nid;
253 	struct btf *btf;
254 
255 	btf = btf__new_empty();
256 	if (!ASSERT_OK_PTR(btf, "btf__new_empty"))
257 		return NULL;
258 	id = btf__add_int(btf, "int", 4, BTF_INT_SIGNED);
259 	if (!ASSERT_EQ(id, 1, "btf__add_int"))
260 		goto end;
261 	lid = btf__add_struct(btf, "bpf_spin_lock", 4);
262 	if (!ASSERT_EQ(lid, SPIN_LOCK, "btf__add_struct bpf_spin_lock"))
263 		goto end;
264 	hid = btf__add_struct(btf, "bpf_list_head", 16);
265 	if (!ASSERT_EQ(hid, LIST_HEAD, "btf__add_struct bpf_list_head"))
266 		goto end;
267 	nid = btf__add_struct(btf, "bpf_list_node", 24);
268 	if (!ASSERT_EQ(nid, LIST_NODE, "btf__add_struct bpf_list_node"))
269 		goto end;
270 	return btf;
271 end:
272 	btf__free(btf);
273 	return NULL;
274 }
275 
276 static void list_and_rb_node_same_struct(bool refcount_field)
277 {
278 	int bpf_rb_node_btf_id, bpf_refcount_btf_id = 0, foo_btf_id;
279 	struct btf *btf;
280 	int id, err;
281 
282 	btf = init_btf();
283 	if (!ASSERT_OK_PTR(btf, "init_btf"))
284 		return;
285 
286 	bpf_rb_node_btf_id = btf__add_struct(btf, "bpf_rb_node", 32);
287 	if (!ASSERT_GT(bpf_rb_node_btf_id, 0, "btf__add_struct bpf_rb_node"))
288 		return;
289 
290 	if (refcount_field) {
291 		bpf_refcount_btf_id = btf__add_struct(btf, "bpf_refcount", 4);
292 		if (!ASSERT_GT(bpf_refcount_btf_id, 0, "btf__add_struct bpf_refcount"))
293 			return;
294 	}
295 
296 	id = btf__add_struct(btf, "bar", refcount_field ? 60 : 56);
297 	if (!ASSERT_GT(id, 0, "btf__add_struct bar"))
298 		return;
299 	err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
300 	if (!ASSERT_OK(err, "btf__add_field bar::a"))
301 		return;
302 	err = btf__add_field(btf, "c", bpf_rb_node_btf_id, 192, 0);
303 	if (!ASSERT_OK(err, "btf__add_field bar::c"))
304 		return;
305 	if (refcount_field) {
306 		err = btf__add_field(btf, "ref", bpf_refcount_btf_id, 448, 0);
307 		if (!ASSERT_OK(err, "btf__add_field bar::ref"))
308 			return;
309 	}
310 
311 	foo_btf_id = btf__add_struct(btf, "foo", 20);
312 	if (!ASSERT_GT(foo_btf_id, 0, "btf__add_struct foo"))
313 		return;
314 	err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
315 	if (!ASSERT_OK(err, "btf__add_field foo::a"))
316 		return;
317 	err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);
318 	if (!ASSERT_OK(err, "btf__add_field foo::b"))
319 		return;
320 	id = btf__add_decl_tag(btf, "contains:bar:a", foo_btf_id, 0);
321 	if (!ASSERT_GT(id, 0, "btf__add_decl_tag contains:bar:a"))
322 		return;
323 
324 	err = btf__load_into_kernel(btf);
325 	ASSERT_EQ(err, refcount_field ? 0 : -EINVAL, "check btf");
326 	btf__free(btf);
327 }
328 
329 static void test_btf(void)
330 {
331 	struct btf *btf = NULL;
332 	int id, err;
333 
334 	while (test__start_subtest("btf: too many locks")) {
335 		btf = init_btf();
336 		if (!ASSERT_OK_PTR(btf, "init_btf"))
337 			break;
338 		id = btf__add_struct(btf, "foo", 24);
339 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
340 			break;
341 		err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0);
342 		if (!ASSERT_OK(err, "btf__add_struct foo::a"))
343 			break;
344 		err = btf__add_field(btf, "b", SPIN_LOCK, 32, 0);
345 		if (!ASSERT_OK(err, "btf__add_struct foo::a"))
346 			break;
347 		err = btf__add_field(btf, "c", LIST_HEAD, 64, 0);
348 		if (!ASSERT_OK(err, "btf__add_struct foo::a"))
349 			break;
350 
351 		err = btf__load_into_kernel(btf);
352 		ASSERT_EQ(err, -E2BIG, "check btf");
353 		btf__free(btf);
354 		break;
355 	}
356 
357 	while (test__start_subtest("btf: missing lock")) {
358 		btf = init_btf();
359 		if (!ASSERT_OK_PTR(btf, "init_btf"))
360 			break;
361 		id = btf__add_struct(btf, "foo", 16);
362 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
363 			break;
364 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
365 		if (!ASSERT_OK(err, "btf__add_struct foo::a"))
366 			break;
367 		id = btf__add_decl_tag(btf, "contains:baz:a", 5, 0);
368 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:baz:a"))
369 			break;
370 		id = btf__add_struct(btf, "baz", 16);
371 		if (!ASSERT_EQ(id, 7, "btf__add_struct baz"))
372 			break;
373 		err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
374 		if (!ASSERT_OK(err, "btf__add_field baz::a"))
375 			break;
376 
377 		err = btf__load_into_kernel(btf);
378 		ASSERT_EQ(err, -EINVAL, "check btf");
379 		btf__free(btf);
380 		break;
381 	}
382 
383 	while (test__start_subtest("btf: bad offset")) {
384 		btf = init_btf();
385 		if (!ASSERT_OK_PTR(btf, "init_btf"))
386 			break;
387 		id = btf__add_struct(btf, "foo", 36);
388 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
389 			break;
390 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
391 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
392 			break;
393 		err = btf__add_field(btf, "b", LIST_NODE, 0, 0);
394 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
395 			break;
396 		err = btf__add_field(btf, "c", SPIN_LOCK, 0, 0);
397 		if (!ASSERT_OK(err, "btf__add_field foo::c"))
398 			break;
399 		id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0);
400 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b"))
401 			break;
402 
403 		err = btf__load_into_kernel(btf);
404 		ASSERT_EQ(err, -EEXIST, "check btf");
405 		btf__free(btf);
406 		break;
407 	}
408 
409 	while (test__start_subtest("btf: missing contains:")) {
410 		btf = init_btf();
411 		if (!ASSERT_OK_PTR(btf, "init_btf"))
412 			break;
413 		id = btf__add_struct(btf, "foo", 24);
414 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
415 			break;
416 		err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0);
417 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
418 			break;
419 		err = btf__add_field(btf, "b", LIST_HEAD, 64, 0);
420 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
421 			break;
422 
423 		err = btf__load_into_kernel(btf);
424 		ASSERT_EQ(err, -EINVAL, "check btf");
425 		btf__free(btf);
426 		break;
427 	}
428 
429 	while (test__start_subtest("btf: missing struct")) {
430 		btf = init_btf();
431 		if (!ASSERT_OK_PTR(btf, "init_btf"))
432 			break;
433 		id = btf__add_struct(btf, "foo", 24);
434 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
435 			break;
436 		err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0);
437 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
438 			break;
439 		err = btf__add_field(btf, "b", LIST_HEAD, 64, 0);
440 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
441 			break;
442 		id = btf__add_decl_tag(btf, "contains:bar:bar", 5, 1);
443 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:bar"))
444 			break;
445 
446 		err = btf__load_into_kernel(btf);
447 		ASSERT_EQ(err, -ENOENT, "check btf");
448 		btf__free(btf);
449 		break;
450 	}
451 
452 	while (test__start_subtest("btf: missing node")) {
453 		btf = init_btf();
454 		if (!ASSERT_OK_PTR(btf, "init_btf"))
455 			break;
456 		id = btf__add_struct(btf, "foo", 24);
457 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
458 			break;
459 		err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0);
460 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
461 			break;
462 		err = btf__add_field(btf, "b", LIST_HEAD, 64, 0);
463 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
464 			break;
465 		id = btf__add_decl_tag(btf, "contains:foo:c", 5, 1);
466 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:c"))
467 			break;
468 
469 		err = btf__load_into_kernel(btf);
470 		btf__free(btf);
471 		ASSERT_EQ(err, -ENOENT, "check btf");
472 		break;
473 	}
474 
475 	while (test__start_subtest("btf: node incorrect type")) {
476 		btf = init_btf();
477 		if (!ASSERT_OK_PTR(btf, "init_btf"))
478 			break;
479 		id = btf__add_struct(btf, "foo", 20);
480 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
481 			break;
482 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
483 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
484 			break;
485 		err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);
486 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
487 			break;
488 		id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0);
489 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a"))
490 			break;
491 		id = btf__add_struct(btf, "bar", 4);
492 		if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
493 			break;
494 		err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0);
495 		if (!ASSERT_OK(err, "btf__add_field bar::a"))
496 			break;
497 
498 		err = btf__load_into_kernel(btf);
499 		ASSERT_EQ(err, -EINVAL, "check btf");
500 		btf__free(btf);
501 		break;
502 	}
503 
504 	while (test__start_subtest("btf: multiple bpf_list_node with name b")) {
505 		btf = init_btf();
506 		if (!ASSERT_OK_PTR(btf, "init_btf"))
507 			break;
508 		id = btf__add_struct(btf, "foo", 52);
509 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
510 			break;
511 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
512 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
513 			break;
514 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
515 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
516 			break;
517 		err = btf__add_field(btf, "b", LIST_NODE, 256, 0);
518 		if (!ASSERT_OK(err, "btf__add_field foo::c"))
519 			break;
520 		err = btf__add_field(btf, "d", SPIN_LOCK, 384, 0);
521 		if (!ASSERT_OK(err, "btf__add_field foo::d"))
522 			break;
523 		id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0);
524 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b"))
525 			break;
526 
527 		err = btf__load_into_kernel(btf);
528 		ASSERT_EQ(err, -EINVAL, "check btf");
529 		btf__free(btf);
530 		break;
531 	}
532 
533 	while (test__start_subtest("btf: owning | owned AA cycle")) {
534 		btf = init_btf();
535 		if (!ASSERT_OK_PTR(btf, "init_btf"))
536 			break;
537 		id = btf__add_struct(btf, "foo", 44);
538 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
539 			break;
540 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
541 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
542 			break;
543 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
544 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
545 			break;
546 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
547 		if (!ASSERT_OK(err, "btf__add_field foo::c"))
548 			break;
549 		id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0);
550 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b"))
551 			break;
552 
553 		err = btf__load_into_kernel(btf);
554 		ASSERT_EQ(err, -ELOOP, "check btf");
555 		btf__free(btf);
556 		break;
557 	}
558 
559 	while (test__start_subtest("btf: owning | owned ABA cycle")) {
560 		btf = init_btf();
561 		if (!ASSERT_OK_PTR(btf, "init_btf"))
562 			break;
563 		id = btf__add_struct(btf, "foo", 44);
564 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
565 			break;
566 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
567 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
568 			break;
569 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
570 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
571 			break;
572 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
573 		if (!ASSERT_OK(err, "btf__add_field foo::c"))
574 			break;
575 		id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
576 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
577 			break;
578 		id = btf__add_struct(btf, "bar", 44);
579 		if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
580 			break;
581 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
582 		if (!ASSERT_OK(err, "btf__add_field bar::a"))
583 			break;
584 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
585 		if (!ASSERT_OK(err, "btf__add_field bar::b"))
586 			break;
587 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
588 		if (!ASSERT_OK(err, "btf__add_field bar::c"))
589 			break;
590 		id = btf__add_decl_tag(btf, "contains:foo:b", 7, 0);
591 		if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:foo:b"))
592 			break;
593 
594 		err = btf__load_into_kernel(btf);
595 		ASSERT_EQ(err, -ELOOP, "check btf");
596 		btf__free(btf);
597 		break;
598 	}
599 
600 	while (test__start_subtest("btf: owning -> owned")) {
601 		btf = init_btf();
602 		if (!ASSERT_OK_PTR(btf, "init_btf"))
603 			break;
604 		id = btf__add_struct(btf, "foo", 28);
605 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
606 			break;
607 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
608 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
609 			break;
610 		err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0);
611 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
612 			break;
613 		id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0);
614 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a"))
615 			break;
616 		id = btf__add_struct(btf, "bar", 24);
617 		if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
618 			break;
619 		err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
620 		if (!ASSERT_OK(err, "btf__add_field bar::a"))
621 			break;
622 
623 		err = btf__load_into_kernel(btf);
624 		ASSERT_EQ(err, 0, "check btf");
625 		btf__free(btf);
626 		break;
627 	}
628 
629 	while (test__start_subtest("btf: owning -> owning | owned -> owned")) {
630 		btf = init_btf();
631 		if (!ASSERT_OK_PTR(btf, "init_btf"))
632 			break;
633 		id = btf__add_struct(btf, "foo", 28);
634 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
635 			break;
636 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
637 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
638 			break;
639 		err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0);
640 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
641 			break;
642 		id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
643 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
644 			break;
645 		id = btf__add_struct(btf, "bar", 44);
646 		if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
647 			break;
648 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
649 		if (!ASSERT_OK(err, "btf__add_field bar::a"))
650 			break;
651 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
652 		if (!ASSERT_OK(err, "btf__add_field bar::b"))
653 			break;
654 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
655 		if (!ASSERT_OK(err, "btf__add_field bar::c"))
656 			break;
657 		id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);
658 		if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))
659 			break;
660 		id = btf__add_struct(btf, "baz", 24);
661 		if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
662 			break;
663 		err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
664 		if (!ASSERT_OK(err, "btf__add_field baz:a"))
665 			break;
666 
667 		err = btf__load_into_kernel(btf);
668 		ASSERT_EQ(err, 0, "check btf");
669 		btf__free(btf);
670 		break;
671 	}
672 
673 	while (test__start_subtest("btf: owning | owned -> owning | owned -> owned")) {
674 		btf = init_btf();
675 		if (!ASSERT_OK_PTR(btf, "init_btf"))
676 			break;
677 		id = btf__add_struct(btf, "foo", 44);
678 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
679 			break;
680 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
681 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
682 			break;
683 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
684 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
685 			break;
686 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
687 		if (!ASSERT_OK(err, "btf__add_field foo::c"))
688 			break;
689 		id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
690 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
691 			break;
692 		id = btf__add_struct(btf, "bar", 44);
693 		if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
694 			break;
695 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
696 		if (!ASSERT_OK(err, "btf__add_field bar:a"))
697 			break;
698 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
699 		if (!ASSERT_OK(err, "btf__add_field bar:b"))
700 			break;
701 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
702 		if (!ASSERT_OK(err, "btf__add_field bar:c"))
703 			break;
704 		id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);
705 		if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))
706 			break;
707 		id = btf__add_struct(btf, "baz", 24);
708 		if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
709 			break;
710 		err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
711 		if (!ASSERT_OK(err, "btf__add_field baz:a"))
712 			break;
713 
714 		err = btf__load_into_kernel(btf);
715 		ASSERT_EQ(err, -ELOOP, "check btf");
716 		btf__free(btf);
717 		break;
718 	}
719 
720 	while (test__start_subtest("btf: owning -> owning | owned -> owning | owned -> owned")) {
721 		btf = init_btf();
722 		if (!ASSERT_OK_PTR(btf, "init_btf"))
723 			break;
724 		id = btf__add_struct(btf, "foo", 20);
725 		if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
726 			break;
727 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
728 		if (!ASSERT_OK(err, "btf__add_field foo::a"))
729 			break;
730 		err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);
731 		if (!ASSERT_OK(err, "btf__add_field foo::b"))
732 			break;
733 		id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
734 		if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
735 			break;
736 		id = btf__add_struct(btf, "bar", 44);
737 		if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
738 			break;
739 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
740 		if (!ASSERT_OK(err, "btf__add_field bar::a"))
741 			break;
742 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
743 		if (!ASSERT_OK(err, "btf__add_field bar::b"))
744 			break;
745 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
746 		if (!ASSERT_OK(err, "btf__add_field bar::c"))
747 			break;
748 		id = btf__add_decl_tag(btf, "contains:baz:b", 7, 0);
749 		if (!ASSERT_EQ(id, 8, "btf__add_decl_tag"))
750 			break;
751 		id = btf__add_struct(btf, "baz", 44);
752 		if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
753 			break;
754 		err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
755 		if (!ASSERT_OK(err, "btf__add_field bar::a"))
756 			break;
757 		err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
758 		if (!ASSERT_OK(err, "btf__add_field bar::b"))
759 			break;
760 		err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
761 		if (!ASSERT_OK(err, "btf__add_field bar::c"))
762 			break;
763 		id = btf__add_decl_tag(btf, "contains:bam:a", 9, 0);
764 		if (!ASSERT_EQ(id, 10, "btf__add_decl_tag contains:bam:a"))
765 			break;
766 		id = btf__add_struct(btf, "bam", 24);
767 		if (!ASSERT_EQ(id, 11, "btf__add_struct bam"))
768 			break;
769 		err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
770 		if (!ASSERT_OK(err, "btf__add_field bam::a"))
771 			break;
772 
773 		err = btf__load_into_kernel(btf);
774 		ASSERT_EQ(err, -ELOOP, "check btf");
775 		btf__free(btf);
776 		break;
777 	}
778 
779 	while (test__start_subtest("btf: list_node and rb_node in same struct")) {
780 		list_and_rb_node_same_struct(true);
781 		break;
782 	}
783 
784 	while (test__start_subtest("btf: list_node and rb_node in same struct, no bpf_refcount")) {
785 		list_and_rb_node_same_struct(false);
786 		break;
787 	}
788 }
789 
790 void test_linked_list(void)
791 {
792 	int i;
793 
794 	for (i = 0; i < ARRAY_SIZE(linked_list_fail_tests); i++) {
795 		if (!test__start_subtest(linked_list_fail_tests[i].prog_name))
796 			continue;
797 		test_linked_list_fail_prog(linked_list_fail_tests[i].prog_name,
798 					   linked_list_fail_tests[i].err_msg);
799 	}
800 	test_btf();
801 	test_linked_list_success(PUSH_POP, false);
802 	test_linked_list_success(PUSH_POP, true);
803 	test_linked_list_success(PUSH_POP_MULT, false);
804 	test_linked_list_success(PUSH_POP_MULT, true);
805 	test_linked_list_success(LIST_IN_LIST, false);
806 	test_linked_list_success(LIST_IN_LIST, true);
807 	test_linked_list_success(TEST_ALL, false);
808 }
809 
810 void test_linked_list_peek(void)
811 {
812 	RUN_TESTS(linked_list_peek);
813 }
814