1*c48748aeSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
2*c48748aeSKumar Kartikeya Dwivedi #include <vmlinux.h>
3*c48748aeSKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h>
4*c48748aeSKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h>
5*c48748aeSKumar Kartikeya Dwivedi #include "bpf_experimental.h"
6*c48748aeSKumar Kartikeya Dwivedi 
7*c48748aeSKumar Kartikeya Dwivedi struct foo {
8*c48748aeSKumar Kartikeya Dwivedi 	struct bpf_spin_lock lock;
9*c48748aeSKumar Kartikeya Dwivedi 	int data;
10*c48748aeSKumar Kartikeya Dwivedi };
11*c48748aeSKumar Kartikeya Dwivedi 
12*c48748aeSKumar Kartikeya Dwivedi struct array_map {
13*c48748aeSKumar Kartikeya Dwivedi 	__uint(type, BPF_MAP_TYPE_ARRAY);
14*c48748aeSKumar Kartikeya Dwivedi 	__type(key, int);
15*c48748aeSKumar Kartikeya Dwivedi 	__type(value, struct foo);
16*c48748aeSKumar Kartikeya Dwivedi 	__uint(max_entries, 1);
17*c48748aeSKumar Kartikeya Dwivedi } array_map SEC(".maps");
18*c48748aeSKumar Kartikeya Dwivedi 
19*c48748aeSKumar Kartikeya Dwivedi struct {
20*c48748aeSKumar Kartikeya Dwivedi 	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
21*c48748aeSKumar Kartikeya Dwivedi 	__uint(max_entries, 1);
22*c48748aeSKumar Kartikeya Dwivedi 	__type(key, int);
23*c48748aeSKumar Kartikeya Dwivedi 	__type(value, int);
24*c48748aeSKumar Kartikeya Dwivedi 	__array(values, struct array_map);
25*c48748aeSKumar Kartikeya Dwivedi } map_of_maps SEC(".maps") = {
26*c48748aeSKumar Kartikeya Dwivedi 	.values = {
27*c48748aeSKumar Kartikeya Dwivedi 		[0] = &array_map,
28*c48748aeSKumar Kartikeya Dwivedi 	},
29*c48748aeSKumar Kartikeya Dwivedi };
30*c48748aeSKumar Kartikeya Dwivedi 
31*c48748aeSKumar Kartikeya Dwivedi SEC(".data.A") struct bpf_spin_lock lockA;
32*c48748aeSKumar Kartikeya Dwivedi SEC(".data.B") struct bpf_spin_lock lockB;
33*c48748aeSKumar Kartikeya Dwivedi 
34*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_kptr_preserve(void * ctx)35*c48748aeSKumar Kartikeya Dwivedi int lock_id_kptr_preserve(void *ctx)
36*c48748aeSKumar Kartikeya Dwivedi {
37*c48748aeSKumar Kartikeya Dwivedi 	struct foo *f;
38*c48748aeSKumar Kartikeya Dwivedi 
39*c48748aeSKumar Kartikeya Dwivedi 	f = bpf_obj_new(typeof(*f));
40*c48748aeSKumar Kartikeya Dwivedi 	if (!f)
41*c48748aeSKumar Kartikeya Dwivedi 		return 0;
42*c48748aeSKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(f);
43*c48748aeSKumar Kartikeya Dwivedi 	return 0;
44*c48748aeSKumar Kartikeya Dwivedi }
45*c48748aeSKumar Kartikeya Dwivedi 
46*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_global_zero(void * ctx)47*c48748aeSKumar Kartikeya Dwivedi int lock_id_global_zero(void *ctx)
48*c48748aeSKumar Kartikeya Dwivedi {
49*c48748aeSKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(&lockA);
50*c48748aeSKumar Kartikeya Dwivedi 	return 0;
51*c48748aeSKumar Kartikeya Dwivedi }
52*c48748aeSKumar Kartikeya Dwivedi 
53*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_mapval_preserve(void * ctx)54*c48748aeSKumar Kartikeya Dwivedi int lock_id_mapval_preserve(void *ctx)
55*c48748aeSKumar Kartikeya Dwivedi {
56*c48748aeSKumar Kartikeya Dwivedi 	struct foo *f;
57*c48748aeSKumar Kartikeya Dwivedi 	int key = 0;
58*c48748aeSKumar Kartikeya Dwivedi 
59*c48748aeSKumar Kartikeya Dwivedi 	f = bpf_map_lookup_elem(&array_map, &key);
60*c48748aeSKumar Kartikeya Dwivedi 	if (!f)
61*c48748aeSKumar Kartikeya Dwivedi 		return 0;
62*c48748aeSKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(f);
63*c48748aeSKumar Kartikeya Dwivedi 	return 0;
64*c48748aeSKumar Kartikeya Dwivedi }
65*c48748aeSKumar Kartikeya Dwivedi 
66*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_innermapval_preserve(void * ctx)67*c48748aeSKumar Kartikeya Dwivedi int lock_id_innermapval_preserve(void *ctx)
68*c48748aeSKumar Kartikeya Dwivedi {
69*c48748aeSKumar Kartikeya Dwivedi 	struct foo *f;
70*c48748aeSKumar Kartikeya Dwivedi 	int key = 0;
71*c48748aeSKumar Kartikeya Dwivedi 	void *map;
72*c48748aeSKumar Kartikeya Dwivedi 
73*c48748aeSKumar Kartikeya Dwivedi 	map = bpf_map_lookup_elem(&map_of_maps, &key);
74*c48748aeSKumar Kartikeya Dwivedi 	if (!map)
75*c48748aeSKumar Kartikeya Dwivedi 		return 0;
76*c48748aeSKumar Kartikeya Dwivedi 	f = bpf_map_lookup_elem(map, &key);
77*c48748aeSKumar Kartikeya Dwivedi 	if (!f)
78*c48748aeSKumar Kartikeya Dwivedi 		return 0;
79*c48748aeSKumar Kartikeya Dwivedi 	bpf_this_cpu_ptr(f);
80*c48748aeSKumar Kartikeya Dwivedi 	return 0;
81*c48748aeSKumar Kartikeya Dwivedi }
82*c48748aeSKumar Kartikeya Dwivedi 
83*c48748aeSKumar Kartikeya Dwivedi #define CHECK(test, A, B)                                      \
84*c48748aeSKumar Kartikeya Dwivedi 	SEC("?tc")                                             \
85*c48748aeSKumar Kartikeya Dwivedi 	int lock_id_mismatch_##test(void *ctx)                 \
86*c48748aeSKumar Kartikeya Dwivedi 	{                                                      \
87*c48748aeSKumar Kartikeya Dwivedi 		struct foo *f1, *f2, *v, *iv;                  \
88*c48748aeSKumar Kartikeya Dwivedi 		int key = 0;                                   \
89*c48748aeSKumar Kartikeya Dwivedi 		void *map;                                     \
90*c48748aeSKumar Kartikeya Dwivedi                                                                \
91*c48748aeSKumar Kartikeya Dwivedi 		map = bpf_map_lookup_elem(&map_of_maps, &key); \
92*c48748aeSKumar Kartikeya Dwivedi 		if (!map)                                      \
93*c48748aeSKumar Kartikeya Dwivedi 			return 0;                              \
94*c48748aeSKumar Kartikeya Dwivedi 		iv = bpf_map_lookup_elem(map, &key);           \
95*c48748aeSKumar Kartikeya Dwivedi 		if (!iv)                                       \
96*c48748aeSKumar Kartikeya Dwivedi 			return 0;                              \
97*c48748aeSKumar Kartikeya Dwivedi 		v = bpf_map_lookup_elem(&array_map, &key);     \
98*c48748aeSKumar Kartikeya Dwivedi 		if (!v)                                        \
99*c48748aeSKumar Kartikeya Dwivedi 			return 0;                              \
100*c48748aeSKumar Kartikeya Dwivedi 		f1 = bpf_obj_new(typeof(*f1));                 \
101*c48748aeSKumar Kartikeya Dwivedi 		if (!f1)                                       \
102*c48748aeSKumar Kartikeya Dwivedi 			return 0;                              \
103*c48748aeSKumar Kartikeya Dwivedi 		f2 = bpf_obj_new(typeof(*f2));                 \
104*c48748aeSKumar Kartikeya Dwivedi 		if (!f2) {                                     \
105*c48748aeSKumar Kartikeya Dwivedi 			bpf_obj_drop(f1);                      \
106*c48748aeSKumar Kartikeya Dwivedi 			return 0;                              \
107*c48748aeSKumar Kartikeya Dwivedi 		}                                              \
108*c48748aeSKumar Kartikeya Dwivedi 		bpf_spin_lock(A);                              \
109*c48748aeSKumar Kartikeya Dwivedi 		bpf_spin_unlock(B);                            \
110*c48748aeSKumar Kartikeya Dwivedi 		return 0;                                      \
111*c48748aeSKumar Kartikeya Dwivedi 	}
112*c48748aeSKumar Kartikeya Dwivedi 
113*c48748aeSKumar Kartikeya Dwivedi CHECK(kptr_kptr, &f1->lock, &f2->lock);
114*c48748aeSKumar Kartikeya Dwivedi CHECK(kptr_global, &f1->lock, &lockA);
115*c48748aeSKumar Kartikeya Dwivedi CHECK(kptr_mapval, &f1->lock, &v->lock);
116*c48748aeSKumar Kartikeya Dwivedi CHECK(kptr_innermapval, &f1->lock, &iv->lock);
117*c48748aeSKumar Kartikeya Dwivedi 
118*c48748aeSKumar Kartikeya Dwivedi CHECK(global_global, &lockA, &lockB);
119*c48748aeSKumar Kartikeya Dwivedi CHECK(global_kptr, &lockA, &f1->lock);
120*c48748aeSKumar Kartikeya Dwivedi CHECK(global_mapval, &lockA, &v->lock);
121*c48748aeSKumar Kartikeya Dwivedi CHECK(global_innermapval, &lockA, &iv->lock);
122*c48748aeSKumar Kartikeya Dwivedi 
123*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_mismatch_mapval_mapval(void * ctx)124*c48748aeSKumar Kartikeya Dwivedi int lock_id_mismatch_mapval_mapval(void *ctx)
125*c48748aeSKumar Kartikeya Dwivedi {
126*c48748aeSKumar Kartikeya Dwivedi 	struct foo *f1, *f2;
127*c48748aeSKumar Kartikeya Dwivedi 	int key = 0;
128*c48748aeSKumar Kartikeya Dwivedi 
129*c48748aeSKumar Kartikeya Dwivedi 	f1 = bpf_map_lookup_elem(&array_map, &key);
130*c48748aeSKumar Kartikeya Dwivedi 	if (!f1)
131*c48748aeSKumar Kartikeya Dwivedi 		return 0;
132*c48748aeSKumar Kartikeya Dwivedi 	f2 = bpf_map_lookup_elem(&array_map, &key);
133*c48748aeSKumar Kartikeya Dwivedi 	if (!f2)
134*c48748aeSKumar Kartikeya Dwivedi 		return 0;
135*c48748aeSKumar Kartikeya Dwivedi 
136*c48748aeSKumar Kartikeya Dwivedi 	bpf_spin_lock(&f1->lock);
137*c48748aeSKumar Kartikeya Dwivedi 	f1->data = 42;
138*c48748aeSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&f2->lock);
139*c48748aeSKumar Kartikeya Dwivedi 
140*c48748aeSKumar Kartikeya Dwivedi 	return 0;
141*c48748aeSKumar Kartikeya Dwivedi }
142*c48748aeSKumar Kartikeya Dwivedi 
143*c48748aeSKumar Kartikeya Dwivedi CHECK(mapval_kptr, &v->lock, &f1->lock);
144*c48748aeSKumar Kartikeya Dwivedi CHECK(mapval_global, &v->lock, &lockB);
145*c48748aeSKumar Kartikeya Dwivedi CHECK(mapval_innermapval, &v->lock, &iv->lock);
146*c48748aeSKumar Kartikeya Dwivedi 
147*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_mismatch_innermapval_innermapval1(void * ctx)148*c48748aeSKumar Kartikeya Dwivedi int lock_id_mismatch_innermapval_innermapval1(void *ctx)
149*c48748aeSKumar Kartikeya Dwivedi {
150*c48748aeSKumar Kartikeya Dwivedi 	struct foo *f1, *f2;
151*c48748aeSKumar Kartikeya Dwivedi 	int key = 0;
152*c48748aeSKumar Kartikeya Dwivedi 	void *map;
153*c48748aeSKumar Kartikeya Dwivedi 
154*c48748aeSKumar Kartikeya Dwivedi 	map = bpf_map_lookup_elem(&map_of_maps, &key);
155*c48748aeSKumar Kartikeya Dwivedi 	if (!map)
156*c48748aeSKumar Kartikeya Dwivedi 		return 0;
157*c48748aeSKumar Kartikeya Dwivedi 	f1 = bpf_map_lookup_elem(map, &key);
158*c48748aeSKumar Kartikeya Dwivedi 	if (!f1)
159*c48748aeSKumar Kartikeya Dwivedi 		return 0;
160*c48748aeSKumar Kartikeya Dwivedi 	f2 = bpf_map_lookup_elem(map, &key);
161*c48748aeSKumar Kartikeya Dwivedi 	if (!f2)
162*c48748aeSKumar Kartikeya Dwivedi 		return 0;
163*c48748aeSKumar Kartikeya Dwivedi 
164*c48748aeSKumar Kartikeya Dwivedi 	bpf_spin_lock(&f1->lock);
165*c48748aeSKumar Kartikeya Dwivedi 	f1->data = 42;
166*c48748aeSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&f2->lock);
167*c48748aeSKumar Kartikeya Dwivedi 
168*c48748aeSKumar Kartikeya Dwivedi 	return 0;
169*c48748aeSKumar Kartikeya Dwivedi }
170*c48748aeSKumar Kartikeya Dwivedi 
171*c48748aeSKumar Kartikeya Dwivedi SEC("?tc")
lock_id_mismatch_innermapval_innermapval2(void * ctx)172*c48748aeSKumar Kartikeya Dwivedi int lock_id_mismatch_innermapval_innermapval2(void *ctx)
173*c48748aeSKumar Kartikeya Dwivedi {
174*c48748aeSKumar Kartikeya Dwivedi 	struct foo *f1, *f2;
175*c48748aeSKumar Kartikeya Dwivedi 	int key = 0;
176*c48748aeSKumar Kartikeya Dwivedi 	void *map;
177*c48748aeSKumar Kartikeya Dwivedi 
178*c48748aeSKumar Kartikeya Dwivedi 	map = bpf_map_lookup_elem(&map_of_maps, &key);
179*c48748aeSKumar Kartikeya Dwivedi 	if (!map)
180*c48748aeSKumar Kartikeya Dwivedi 		return 0;
181*c48748aeSKumar Kartikeya Dwivedi 	f1 = bpf_map_lookup_elem(map, &key);
182*c48748aeSKumar Kartikeya Dwivedi 	if (!f1)
183*c48748aeSKumar Kartikeya Dwivedi 		return 0;
184*c48748aeSKumar Kartikeya Dwivedi 	map = bpf_map_lookup_elem(&map_of_maps, &key);
185*c48748aeSKumar Kartikeya Dwivedi 	if (!map)
186*c48748aeSKumar Kartikeya Dwivedi 		return 0;
187*c48748aeSKumar Kartikeya Dwivedi 	f2 = bpf_map_lookup_elem(map, &key);
188*c48748aeSKumar Kartikeya Dwivedi 	if (!f2)
189*c48748aeSKumar Kartikeya Dwivedi 		return 0;
190*c48748aeSKumar Kartikeya Dwivedi 
191*c48748aeSKumar Kartikeya Dwivedi 	bpf_spin_lock(&f1->lock);
192*c48748aeSKumar Kartikeya Dwivedi 	f1->data = 42;
193*c48748aeSKumar Kartikeya Dwivedi 	bpf_spin_unlock(&f2->lock);
194*c48748aeSKumar Kartikeya Dwivedi 
195*c48748aeSKumar Kartikeya Dwivedi 	return 0;
196*c48748aeSKumar Kartikeya Dwivedi }
197*c48748aeSKumar Kartikeya Dwivedi 
198*c48748aeSKumar Kartikeya Dwivedi CHECK(innermapval_kptr, &iv->lock, &f1->lock);
199*c48748aeSKumar Kartikeya Dwivedi CHECK(innermapval_global, &iv->lock, &lockA);
200*c48748aeSKumar Kartikeya Dwivedi CHECK(innermapval_mapval, &iv->lock, &v->lock);
201*c48748aeSKumar Kartikeya Dwivedi 
202*c48748aeSKumar Kartikeya Dwivedi #undef CHECK
203*c48748aeSKumar Kartikeya Dwivedi 
204*c48748aeSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL";
205