12cbc469aSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
22cbc469aSKumar Kartikeya Dwivedi #include <test_progs.h>
30ef6740eSKumar Kartikeya Dwivedi #include <network_helpers.h>
42cbc469aSKumar Kartikeya Dwivedi 
52cbc469aSKumar Kartikeya Dwivedi #include "map_kptr.skel.h"
604accf79SKumar Kartikeya Dwivedi #include "map_kptr_fail.skel.h"
7*85521e1eSKumar Kartikeya Dwivedi #include "rcu_tasks_trace_gp.skel.h"
82cbc469aSKumar Kartikeya Dwivedi 
test_map_kptr_success(bool test_run)90ef6740eSKumar Kartikeya Dwivedi static void test_map_kptr_success(bool test_run)
102cbc469aSKumar Kartikeya Dwivedi {
11*85521e1eSKumar Kartikeya Dwivedi 	LIBBPF_OPTS(bpf_test_run_opts, lopts);
120ef6740eSKumar Kartikeya Dwivedi 	LIBBPF_OPTS(bpf_test_run_opts, opts,
130ef6740eSKumar Kartikeya Dwivedi 		.data_in = &pkt_v4,
140ef6740eSKumar Kartikeya Dwivedi 		.data_size_in = sizeof(pkt_v4),
150ef6740eSKumar Kartikeya Dwivedi 		.repeat = 1,
160ef6740eSKumar Kartikeya Dwivedi 	);
17*85521e1eSKumar Kartikeya Dwivedi 	int key = 0, ret, cpu;
182cbc469aSKumar Kartikeya Dwivedi 	struct map_kptr *skel;
19*85521e1eSKumar Kartikeya Dwivedi 	char buf[16], *pbuf;
202cbc469aSKumar Kartikeya Dwivedi 
212cbc469aSKumar Kartikeya Dwivedi 	skel = map_kptr__open_and_load();
222cbc469aSKumar Kartikeya Dwivedi 	if (!ASSERT_OK_PTR(skel, "map_kptr__open_and_load"))
232cbc469aSKumar Kartikeya Dwivedi 		return;
242cbc469aSKumar Kartikeya Dwivedi 
25*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref1), &opts);
26*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref1 refcount");
27*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref1 retval");
280ef6740eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref2), &opts);
290ef6740eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref2 refcount");
300ef6740eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref2 retval");
310ef6740eSKumar Kartikeya Dwivedi 
32*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_ls_map_kptr_ref1), &lopts);
33*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_ls_map_kptr_ref1 refcount");
34*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(lopts.retval, "test_ls_map_kptr_ref1 retval");
35*85521e1eSKumar Kartikeya Dwivedi 
36*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_ls_map_kptr_ref2), &lopts);
37*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_ls_map_kptr_ref2 refcount");
38*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(lopts.retval, "test_ls_map_kptr_ref2 retval");
39*85521e1eSKumar Kartikeya Dwivedi 
400ef6740eSKumar Kartikeya Dwivedi 	if (test_run)
416e8280b9SXu Kuohai 		goto exit;
420ef6740eSKumar Kartikeya Dwivedi 
43*85521e1eSKumar Kartikeya Dwivedi 	cpu = libbpf_num_possible_cpus();
44*85521e1eSKumar Kartikeya Dwivedi 	if (!ASSERT_GT(cpu, 0, "libbpf_num_possible_cpus"))
45*85521e1eSKumar Kartikeya Dwivedi 		goto exit;
46*85521e1eSKumar Kartikeya Dwivedi 
47*85521e1eSKumar Kartikeya Dwivedi 	pbuf = calloc(cpu, sizeof(buf));
48*85521e1eSKumar Kartikeya Dwivedi 	if (!ASSERT_OK_PTR(pbuf, "calloc(pbuf)"))
49*85521e1eSKumar Kartikeya Dwivedi 		goto exit;
50*85521e1eSKumar Kartikeya Dwivedi 
51b2531d4bSAndrii Nakryiko 	ret = bpf_map__update_elem(skel->maps.array_map,
52b2531d4bSAndrii Nakryiko 				   &key, sizeof(key), buf, sizeof(buf), 0);
532cbc469aSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "array_map update");
54*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
55*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
56*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
57*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
582cbc469aSKumar Kartikeya Dwivedi 
59*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_map__update_elem(skel->maps.pcpu_array_map,
60*85521e1eSKumar Kartikeya Dwivedi 				   &key, sizeof(key), pbuf, cpu * sizeof(buf), 0);
61*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "pcpu_array_map update");
62*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
63*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
64*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
65*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
66*85521e1eSKumar Kartikeya Dwivedi 
67b2531d4bSAndrii Nakryiko 	ret = bpf_map__delete_elem(skel->maps.hash_map, &key, sizeof(key), 0);
682cbc469aSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "hash_map delete");
69*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
70*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
71*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
72*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
732cbc469aSKumar Kartikeya Dwivedi 
74*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_map__delete_elem(skel->maps.pcpu_hash_map, &key, sizeof(key), 0);
75*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "pcpu_hash_map delete");
76*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
77*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
78*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
79*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
80*85521e1eSKumar Kartikeya Dwivedi 
81b2531d4bSAndrii Nakryiko 	ret = bpf_map__delete_elem(skel->maps.hash_malloc_map, &key, sizeof(key), 0);
822cbc469aSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "hash_malloc_map delete");
83*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
84*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
85*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
86*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
872cbc469aSKumar Kartikeya Dwivedi 
88*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_map__delete_elem(skel->maps.pcpu_hash_malloc_map, &key, sizeof(key), 0);
89*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "pcpu_hash_malloc_map delete");
90*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
91*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
92*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
93*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
94*85521e1eSKumar Kartikeya Dwivedi 
95b2531d4bSAndrii Nakryiko 	ret = bpf_map__delete_elem(skel->maps.lru_hash_map, &key, sizeof(key), 0);
962cbc469aSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "lru_hash_map delete");
97*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
98*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
99*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
100*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
1012cbc469aSKumar Kartikeya Dwivedi 
102*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_map__delete_elem(skel->maps.lru_pcpu_hash_map, &key, sizeof(key), 0);
103*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "lru_pcpu_hash_map delete");
104*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
105*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref3), &opts);
106*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_map_kptr_ref3 refcount");
107*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(opts.retval, "test_map_kptr_ref3 retval");
108*85521e1eSKumar Kartikeya Dwivedi 
109*85521e1eSKumar Kartikeya Dwivedi 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_ls_map_kptr_ref_del), &lopts);
110*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(ret, "test_ls_map_kptr_ref_del delete");
111*85521e1eSKumar Kartikeya Dwivedi 	skel->data->ref--;
112*85521e1eSKumar Kartikeya Dwivedi 	ASSERT_OK(lopts.retval, "test_ls_map_kptr_ref_del retval");
113*85521e1eSKumar Kartikeya Dwivedi 
114*85521e1eSKumar Kartikeya Dwivedi 	free(pbuf);
1156e8280b9SXu Kuohai exit:
1162cbc469aSKumar Kartikeya Dwivedi 	map_kptr__destroy(skel);
1172cbc469aSKumar Kartikeya Dwivedi }
11804accf79SKumar Kartikeya Dwivedi 
kern_sync_rcu_tasks_trace(struct rcu_tasks_trace_gp * rcu)119*85521e1eSKumar Kartikeya Dwivedi static int kern_sync_rcu_tasks_trace(struct rcu_tasks_trace_gp *rcu)
12004accf79SKumar Kartikeya Dwivedi {
121*85521e1eSKumar Kartikeya Dwivedi 	long gp_seq = READ_ONCE(rcu->bss->gp_seq);
122*85521e1eSKumar Kartikeya Dwivedi 	LIBBPF_OPTS(bpf_test_run_opts, opts);
123*85521e1eSKumar Kartikeya Dwivedi 
124*85521e1eSKumar Kartikeya Dwivedi 	if (!ASSERT_OK(bpf_prog_test_run_opts(bpf_program__fd(rcu->progs.do_call_rcu_tasks_trace),
125*85521e1eSKumar Kartikeya Dwivedi 					      &opts), "do_call_rcu_tasks_trace"))
126*85521e1eSKumar Kartikeya Dwivedi 		return -EFAULT;
127*85521e1eSKumar Kartikeya Dwivedi 	if (!ASSERT_OK(opts.retval, "opts.retval == 0"))
128*85521e1eSKumar Kartikeya Dwivedi 		return -EFAULT;
129*85521e1eSKumar Kartikeya Dwivedi 	while (gp_seq == READ_ONCE(rcu->bss->gp_seq))
130*85521e1eSKumar Kartikeya Dwivedi 		sched_yield();
131*85521e1eSKumar Kartikeya Dwivedi 	return 0;
132*85521e1eSKumar Kartikeya Dwivedi }
133*85521e1eSKumar Kartikeya Dwivedi 
serial_test_map_kptr(void)134*85521e1eSKumar Kartikeya Dwivedi void serial_test_map_kptr(void)
135*85521e1eSKumar Kartikeya Dwivedi {
136*85521e1eSKumar Kartikeya Dwivedi 	struct rcu_tasks_trace_gp *skel;
137*85521e1eSKumar Kartikeya Dwivedi 
138*85521e1eSKumar Kartikeya Dwivedi 	RUN_TESTS(map_kptr_fail);
139*85521e1eSKumar Kartikeya Dwivedi 
140*85521e1eSKumar Kartikeya Dwivedi 	skel = rcu_tasks_trace_gp__open_and_load();
141*85521e1eSKumar Kartikeya Dwivedi 	if (!ASSERT_OK_PTR(skel, "rcu_tasks_trace_gp__open_and_load"))
142*85521e1eSKumar Kartikeya Dwivedi 		return;
143*85521e1eSKumar Kartikeya Dwivedi 	if (!ASSERT_OK(rcu_tasks_trace_gp__attach(skel), "rcu_tasks_trace_gp__attach"))
144*85521e1eSKumar Kartikeya Dwivedi 		goto end;
145*85521e1eSKumar Kartikeya Dwivedi 
146*85521e1eSKumar Kartikeya Dwivedi 	if (test__start_subtest("success-map")) {
147*85521e1eSKumar Kartikeya Dwivedi 		test_map_kptr_success(true);
148*85521e1eSKumar Kartikeya Dwivedi 
149*85521e1eSKumar Kartikeya Dwivedi 		ASSERT_OK(kern_sync_rcu_tasks_trace(skel), "sync rcu_tasks_trace");
150*85521e1eSKumar Kartikeya Dwivedi 		ASSERT_OK(kern_sync_rcu(), "sync rcu");
151*85521e1eSKumar Kartikeya Dwivedi 		/* Observe refcount dropping to 1 on bpf_map_free_deferred */
1520ef6740eSKumar Kartikeya Dwivedi 		test_map_kptr_success(false);
153*85521e1eSKumar Kartikeya Dwivedi 
154*85521e1eSKumar Kartikeya Dwivedi 		ASSERT_OK(kern_sync_rcu_tasks_trace(skel), "sync rcu_tasks_trace");
155*85521e1eSKumar Kartikeya Dwivedi 		ASSERT_OK(kern_sync_rcu(), "sync rcu");
156*85521e1eSKumar Kartikeya Dwivedi 		/* Observe refcount dropping to 1 on synchronous delete elem */
1570ef6740eSKumar Kartikeya Dwivedi 		test_map_kptr_success(true);
1580ef6740eSKumar Kartikeya Dwivedi 	}
15926c386ecSAndrii Nakryiko 
160*85521e1eSKumar Kartikeya Dwivedi end:
161*85521e1eSKumar Kartikeya Dwivedi 	rcu_tasks_trace_gp__destroy(skel);
162*85521e1eSKumar Kartikeya Dwivedi 	return;
16304accf79SKumar Kartikeya Dwivedi }
164