xref: /linux/lib/test_context-analysis.c (revision 056e065a6b6e01ab54bb9770c0d5a15350e571e2)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Compile-only tests for common patterns that should not generate false
4  * positive errors when compiled with Clang's context analysis.
5  */
6 
7 #include <linux/bit_spinlock.h>
8 #include <linux/build_bug.h>
9 #include <linux/local_lock.h>
10 #include <linux/mutex.h>
11 #include <linux/percpu.h>
12 #include <linux/rcupdate.h>
13 #include <linux/rwsem.h>
14 #include <linux/seqlock.h>
15 #include <linux/spinlock.h>
16 #include <linux/srcu.h>
17 #include <linux/ww_mutex.h>
18 
19 /*
20  * Test that helper macros work as expected.
21  */
22 static void __used test_common_helpers(void)
23 {
24 	BUILD_BUG_ON(context_unsafe(3) != 3); /* plain expression */
25 	BUILD_BUG_ON(context_unsafe((void)2; 3) != 3); /* does not swallow semi-colon */
26 	BUILD_BUG_ON(context_unsafe((void)2, 3) != 3); /* does not swallow commas */
27 	context_unsafe(do { } while (0)); /* works with void statements */
28 }
29 
30 #define TEST_SPINLOCK_COMMON(class, type, type_init, type_lock, type_unlock, type_trylock, op)	\
31 	struct test_##class##_data {								\
32 		type lock;									\
33 		int counter __guarded_by(&lock);						\
34 		int *pointer __pt_guarded_by(&lock);						\
35 	};											\
36 	static void __used test_##class##_init(struct test_##class##_data *d)			\
37 	{											\
38 		guard(type_init)(&d->lock);							\
39 		d->counter = 0;									\
40 	}											\
41 	static void __used test_##class(struct test_##class##_data *d)				\
42 	{											\
43 		unsigned long flags;								\
44 		d->pointer++;									\
45 		type_lock(&d->lock);								\
46 		op(d->counter);									\
47 		op(*d->pointer);								\
48 		type_unlock(&d->lock);								\
49 		type_lock##_irq(&d->lock);							\
50 		op(d->counter);									\
51 		op(*d->pointer);								\
52 		type_unlock##_irq(&d->lock);							\
53 		type_lock##_bh(&d->lock);							\
54 		op(d->counter);									\
55 		op(*d->pointer);								\
56 		type_unlock##_bh(&d->lock);							\
57 		type_lock##_irqsave(&d->lock, flags);						\
58 		op(d->counter);									\
59 		op(*d->pointer);								\
60 		type_unlock##_irqrestore(&d->lock, flags);					\
61 	}											\
62 	static void __used test_##class##_trylock(struct test_##class##_data *d)		\
63 	{											\
64 		if (type_trylock(&d->lock)) {							\
65 			op(d->counter);								\
66 			type_unlock(&d->lock);							\
67 		}										\
68 	}											\
69 	static void __used test_##class##_assert(struct test_##class##_data *d)			\
70 	{											\
71 		lockdep_assert_held(&d->lock);							\
72 		op(d->counter);									\
73 	}											\
74 	static void __used test_##class##_guard(struct test_##class##_data *d)			\
75 	{											\
76 		{ guard(class)(&d->lock);		op(d->counter); }			\
77 		{ guard(class##_irq)(&d->lock);		op(d->counter); }			\
78 		{ guard(class##_irqsave)(&d->lock);	op(d->counter); }			\
79 	}
80 
81 #define TEST_OP_RW(x) (x)++
82 #define TEST_OP_RO(x) ((void)(x))
83 
84 TEST_SPINLOCK_COMMON(raw_spinlock,
85 		     raw_spinlock_t,
86 		     raw_spinlock_init,
87 		     raw_spin_lock,
88 		     raw_spin_unlock,
89 		     raw_spin_trylock,
90 		     TEST_OP_RW);
91 static void __used test_raw_spinlock_trylock_extra(struct test_raw_spinlock_data *d)
92 {
93 	unsigned long flags;
94 
95 	data_race(d->counter++); /* no warning */
96 
97 	if (raw_spin_trylock_irq(&d->lock)) {
98 		d->counter++;
99 		raw_spin_unlock_irq(&d->lock);
100 	}
101 	if (raw_spin_trylock_irqsave(&d->lock, flags)) {
102 		d->counter++;
103 		raw_spin_unlock_irqrestore(&d->lock, flags);
104 	}
105 	scoped_cond_guard(raw_spinlock_try, return, &d->lock) {
106 		d->counter++;
107 	}
108 }
109 
110 TEST_SPINLOCK_COMMON(spinlock,
111 		     spinlock_t,
112 		     spinlock_init,
113 		     spin_lock,
114 		     spin_unlock,
115 		     spin_trylock,
116 		     TEST_OP_RW);
117 static void __used test_spinlock_trylock_extra(struct test_spinlock_data *d)
118 {
119 	unsigned long flags;
120 
121 	if (spin_trylock_irq(&d->lock)) {
122 		d->counter++;
123 		spin_unlock_irq(&d->lock);
124 	}
125 	if (spin_trylock_irqsave(&d->lock, flags)) {
126 		d->counter++;
127 		spin_unlock_irqrestore(&d->lock, flags);
128 	}
129 	scoped_cond_guard(spinlock_try, return, &d->lock) {
130 		d->counter++;
131 	}
132 }
133 
134 TEST_SPINLOCK_COMMON(write_lock,
135 		     rwlock_t,
136 		     rwlock_init,
137 		     write_lock,
138 		     write_unlock,
139 		     write_trylock,
140 		     TEST_OP_RW);
141 static void __used test_write_trylock_extra(struct test_write_lock_data *d)
142 {
143 	unsigned long flags;
144 
145 	if (write_trylock_irqsave(&d->lock, flags)) {
146 		d->counter++;
147 		write_unlock_irqrestore(&d->lock, flags);
148 	}
149 }
150 
151 TEST_SPINLOCK_COMMON(read_lock,
152 		     rwlock_t,
153 		     rwlock_init,
154 		     read_lock,
155 		     read_unlock,
156 		     read_trylock,
157 		     TEST_OP_RO);
158 
159 struct test_mutex_data {
160 	struct mutex mtx;
161 	int counter __guarded_by(&mtx);
162 
163 	struct mutex mtx2;
164 	int anyread __guarded_by(&mtx, &mtx2);
165 	int *anyptr __pt_guarded_by(&mtx, &mtx2);
166 };
167 
168 static void __used test_mutex_init(struct test_mutex_data *d)
169 {
170 	guard(mutex_init)(&d->mtx);
171 	d->counter = 0;
172 }
173 
174 static void __used test_mutex_lock(struct test_mutex_data *d)
175 {
176 	mutex_lock(&d->mtx);
177 	d->counter++;
178 	mutex_unlock(&d->mtx);
179 	mutex_lock_io(&d->mtx);
180 	d->counter++;
181 	mutex_unlock(&d->mtx);
182 }
183 
184 static void __used test_mutex_trylock(struct test_mutex_data *d, atomic_t *a)
185 {
186 	if (!mutex_lock_interruptible(&d->mtx)) {
187 		d->counter++;
188 		mutex_unlock(&d->mtx);
189 	}
190 	if (!mutex_lock_killable(&d->mtx)) {
191 		d->counter++;
192 		mutex_unlock(&d->mtx);
193 	}
194 	if (mutex_trylock(&d->mtx)) {
195 		d->counter++;
196 		mutex_unlock(&d->mtx);
197 	}
198 	if (atomic_dec_and_mutex_lock(a, &d->mtx)) {
199 		d->counter++;
200 		mutex_unlock(&d->mtx);
201 	}
202 }
203 
204 static void __used test_mutex_assert(struct test_mutex_data *d)
205 {
206 	lockdep_assert_held(&d->mtx);
207 	d->counter++;
208 }
209 
210 static void __used test_mutex_guard(struct test_mutex_data *d)
211 {
212 	guard(mutex)(&d->mtx);
213 	d->counter++;
214 }
215 
216 static void __used test_mutex_cond_guard(struct test_mutex_data *d)
217 {
218 	scoped_cond_guard(mutex_try, return, &d->mtx) {
219 		d->counter++;
220 	}
221 	scoped_cond_guard(mutex_intr, return, &d->mtx) {
222 		d->counter++;
223 	}
224 }
225 
226 static void __used test_mutex_multiguard(struct test_mutex_data *d)
227 {
228 	mutex_lock(&d->mtx);
229 	(void)d->anyread;
230 	(void)*d->anyptr;
231 	mutex_unlock(&d->mtx);
232 
233 	mutex_lock(&d->mtx2);
234 	(void)d->anyread;
235 	(void)*d->anyptr;
236 	mutex_unlock(&d->mtx2);
237 
238 	mutex_lock(&d->mtx);
239 	mutex_lock(&d->mtx2);
240 	d->anyread++;
241 	(*d->anyptr)++;
242 	mutex_unlock(&d->mtx2);
243 	mutex_unlock(&d->mtx);
244 }
245 
246 struct test_seqlock_data {
247 	seqlock_t sl;
248 	int counter __guarded_by(&sl);
249 };
250 
251 static void __used test_seqlock_init(struct test_seqlock_data *d)
252 {
253 	guard(seqlock_init)(&d->sl);
254 	d->counter = 0;
255 }
256 
257 static void __used test_seqlock_reader(struct test_seqlock_data *d)
258 {
259 	unsigned int seq;
260 
261 	do {
262 		seq = read_seqbegin(&d->sl);
263 		(void)d->counter;
264 	} while (read_seqretry(&d->sl, seq));
265 }
266 
267 static void __used test_seqlock_writer(struct test_seqlock_data *d)
268 {
269 	unsigned long flags;
270 
271 	write_seqlock(&d->sl);
272 	d->counter++;
273 	write_sequnlock(&d->sl);
274 
275 	write_seqlock_irq(&d->sl);
276 	d->counter++;
277 	write_sequnlock_irq(&d->sl);
278 
279 	write_seqlock_bh(&d->sl);
280 	d->counter++;
281 	write_sequnlock_bh(&d->sl);
282 
283 	write_seqlock_irqsave(&d->sl, flags);
284 	d->counter++;
285 	write_sequnlock_irqrestore(&d->sl, flags);
286 }
287 
288 static void __used test_seqlock_scoped(struct test_seqlock_data *d)
289 {
290 	scoped_seqlock_read (&d->sl, ss_lockless) {
291 		(void)d->counter;
292 	}
293 }
294 
295 struct test_rwsem_data {
296 	struct rw_semaphore sem;
297 	int counter __guarded_by(&sem);
298 };
299 
300 static void __used test_rwsem_init(struct test_rwsem_data *d)
301 {
302 	guard(rwsem_init)(&d->sem);
303 	d->counter = 0;
304 }
305 
306 static void __used test_rwsem_reader(struct test_rwsem_data *d)
307 {
308 	down_read(&d->sem);
309 	(void)d->counter;
310 	up_read(&d->sem);
311 
312 	if (down_read_trylock(&d->sem)) {
313 		(void)d->counter;
314 		up_read(&d->sem);
315 	}
316 }
317 
318 static void __used test_rwsem_writer(struct test_rwsem_data *d)
319 {
320 	down_write(&d->sem);
321 	d->counter++;
322 	up_write(&d->sem);
323 
324 	down_write(&d->sem);
325 	d->counter++;
326 	downgrade_write(&d->sem);
327 	(void)d->counter;
328 	up_read(&d->sem);
329 
330 	if (down_write_trylock(&d->sem)) {
331 		d->counter++;
332 		up_write(&d->sem);
333 	}
334 }
335 
336 static void __used test_rwsem_assert(struct test_rwsem_data *d)
337 {
338 	rwsem_assert_held_nolockdep(&d->sem);
339 	d->counter++;
340 }
341 
342 static void __used test_rwsem_guard(struct test_rwsem_data *d)
343 {
344 	{ guard(rwsem_read)(&d->sem); (void)d->counter; }
345 	{ guard(rwsem_write)(&d->sem); d->counter++; }
346 }
347 
348 static void __used test_rwsem_cond_guard(struct test_rwsem_data *d)
349 {
350 	scoped_cond_guard(rwsem_read_try, return, &d->sem) {
351 		(void)d->counter;
352 	}
353 	scoped_cond_guard(rwsem_write_try, return, &d->sem) {
354 		d->counter++;
355 	}
356 }
357 
358 struct test_bit_spinlock_data {
359 	unsigned long bits;
360 	int counter __guarded_by(__bitlock(3, &bits));
361 };
362 
363 static void __used test_bit_spin_lock(struct test_bit_spinlock_data *d)
364 {
365 	/*
366 	 * Note, the analysis seems to have false negatives, because it won't
367 	 * precisely recognize the bit of the fake __bitlock() token.
368 	 */
369 	bit_spin_lock(3, &d->bits);
370 	d->counter++;
371 	bit_spin_unlock(3, &d->bits);
372 
373 	bit_spin_lock(3, &d->bits);
374 	d->counter++;
375 	__bit_spin_unlock(3, &d->bits);
376 
377 	if (bit_spin_trylock(3, &d->bits)) {
378 		d->counter++;
379 		bit_spin_unlock(3, &d->bits);
380 	}
381 }
382 
383 /*
384  * Test that we can mark a variable guarded by RCU, and we can dereference and
385  * write to the pointer with RCU's primitives.
386  */
387 struct test_rcu_data {
388 	long __rcu_guarded *data;
389 };
390 
391 static void __used test_rcu_guarded_reader(struct test_rcu_data *d)
392 {
393 	rcu_read_lock();
394 	(void)rcu_dereference(d->data);
395 	rcu_read_unlock();
396 
397 	rcu_read_lock_bh();
398 	(void)rcu_dereference(d->data);
399 	rcu_read_unlock_bh();
400 
401 	rcu_read_lock_sched();
402 	(void)rcu_dereference(d->data);
403 	rcu_read_unlock_sched();
404 }
405 
406 static void __used test_rcu_guard(struct test_rcu_data *d)
407 {
408 	guard(rcu)();
409 	(void)rcu_dereference(d->data);
410 }
411 
412 static void __used test_rcu_guarded_updater(struct test_rcu_data *d)
413 {
414 	rcu_assign_pointer(d->data, NULL);
415 	RCU_INIT_POINTER(d->data, NULL);
416 	(void)unrcu_pointer(d->data);
417 }
418 
419 static void wants_rcu_held(void)	__must_hold_shared(RCU)       { }
420 static void wants_rcu_held_bh(void)	__must_hold_shared(RCU_BH)    { }
421 static void wants_rcu_held_sched(void)	__must_hold_shared(RCU_SCHED) { }
422 
423 static void __used test_rcu_lock_variants(void)
424 {
425 	rcu_read_lock();
426 	wants_rcu_held();
427 	rcu_read_unlock();
428 
429 	rcu_read_lock_bh();
430 	wants_rcu_held_bh();
431 	rcu_read_unlock_bh();
432 
433 	rcu_read_lock_sched();
434 	wants_rcu_held_sched();
435 	rcu_read_unlock_sched();
436 }
437 
438 static void __used test_rcu_lock_reentrant(void)
439 {
440 	rcu_read_lock();
441 	rcu_read_lock();
442 	rcu_read_lock_bh();
443 	rcu_read_lock_bh();
444 	rcu_read_lock_sched();
445 	rcu_read_lock_sched();
446 
447 	rcu_read_unlock_sched();
448 	rcu_read_unlock_sched();
449 	rcu_read_unlock_bh();
450 	rcu_read_unlock_bh();
451 	rcu_read_unlock();
452 	rcu_read_unlock();
453 }
454 
455 static void __used test_rcu_assert_variants(void)
456 {
457 	lockdep_assert_in_rcu_read_lock();
458 	wants_rcu_held();
459 
460 	lockdep_assert_in_rcu_read_lock_bh();
461 	wants_rcu_held_bh();
462 
463 	lockdep_assert_in_rcu_read_lock_sched();
464 	wants_rcu_held_sched();
465 }
466 
467 struct test_srcu_data {
468 	struct srcu_struct srcu;
469 	long __rcu_guarded *data;
470 };
471 
472 static void __used test_srcu(struct test_srcu_data *d)
473 {
474 	init_srcu_struct(&d->srcu);
475 
476 	int idx = srcu_read_lock(&d->srcu);
477 	long *data = srcu_dereference(d->data, &d->srcu);
478 	(void)data;
479 	srcu_read_unlock(&d->srcu, idx);
480 
481 	rcu_assign_pointer(d->data, NULL);
482 }
483 
484 static void __used test_srcu_guard(struct test_srcu_data *d)
485 {
486 	{ guard(srcu)(&d->srcu); (void)srcu_dereference(d->data, &d->srcu); }
487 	{ guard(srcu_fast)(&d->srcu); (void)srcu_dereference(d->data, &d->srcu); }
488 	{ guard(srcu_fast_notrace)(&d->srcu); (void)srcu_dereference(d->data, &d->srcu); }
489 }
490 
491 struct test_local_lock_data {
492 	local_lock_t lock;
493 	int counter __guarded_by(&lock);
494 };
495 
496 static DEFINE_PER_CPU(struct test_local_lock_data, test_local_lock_data) = {
497 	.lock = INIT_LOCAL_LOCK(lock),
498 };
499 
500 static void __used test_local_lock_init(struct test_local_lock_data *d)
501 {
502 	guard(local_lock_init)(&d->lock);
503 	d->counter = 0;
504 }
505 
506 static void __used test_local_lock(void)
507 {
508 	unsigned long flags;
509 
510 	local_lock(&test_local_lock_data.lock);
511 	this_cpu_add(test_local_lock_data.counter, 1);
512 	local_unlock(&test_local_lock_data.lock);
513 
514 	local_lock_irq(&test_local_lock_data.lock);
515 	this_cpu_add(test_local_lock_data.counter, 1);
516 	local_unlock_irq(&test_local_lock_data.lock);
517 
518 	local_lock_irqsave(&test_local_lock_data.lock, flags);
519 	this_cpu_add(test_local_lock_data.counter, 1);
520 	local_unlock_irqrestore(&test_local_lock_data.lock, flags);
521 
522 	local_lock_nested_bh(&test_local_lock_data.lock);
523 	this_cpu_add(test_local_lock_data.counter, 1);
524 	local_unlock_nested_bh(&test_local_lock_data.lock);
525 }
526 
527 static void __used test_local_lock_guard(void)
528 {
529 	{ guard(local_lock)(&test_local_lock_data.lock); this_cpu_add(test_local_lock_data.counter, 1); }
530 	{ guard(local_lock_irq)(&test_local_lock_data.lock); this_cpu_add(test_local_lock_data.counter, 1); }
531 	{ guard(local_lock_irqsave)(&test_local_lock_data.lock); this_cpu_add(test_local_lock_data.counter, 1); }
532 	{ guard(local_lock_nested_bh)(&test_local_lock_data.lock); this_cpu_add(test_local_lock_data.counter, 1); }
533 }
534 
535 struct test_local_trylock_data {
536 	local_trylock_t lock;
537 	int counter __guarded_by(&lock);
538 };
539 
540 static DEFINE_PER_CPU(struct test_local_trylock_data, test_local_trylock_data) = {
541 	.lock = INIT_LOCAL_TRYLOCK(lock),
542 };
543 
544 static void __used test_local_trylock_init(struct test_local_trylock_data *d)
545 {
546 	guard(local_trylock_init)(&d->lock);
547 	d->counter = 0;
548 }
549 
550 static void __used test_local_trylock(void)
551 {
552 	local_lock(&test_local_trylock_data.lock);
553 	this_cpu_add(test_local_trylock_data.counter, 1);
554 	local_unlock(&test_local_trylock_data.lock);
555 
556 	if (local_trylock(&test_local_trylock_data.lock)) {
557 		this_cpu_add(test_local_trylock_data.counter, 1);
558 		local_unlock(&test_local_trylock_data.lock);
559 	}
560 }
561 
562 static DEFINE_WD_CLASS(ww_class);
563 
564 struct test_ww_mutex_data {
565 	struct ww_mutex mtx;
566 	int counter __guarded_by(&mtx);
567 };
568 
569 static void __used test_ww_mutex_lock_noctx(struct test_ww_mutex_data *d)
570 {
571 	if (!ww_mutex_lock(&d->mtx, NULL)) {
572 		d->counter++;
573 		ww_mutex_unlock(&d->mtx);
574 	}
575 
576 	if (!ww_mutex_lock_interruptible(&d->mtx, NULL)) {
577 		d->counter++;
578 		ww_mutex_unlock(&d->mtx);
579 	}
580 
581 	if (ww_mutex_trylock(&d->mtx, NULL)) {
582 		d->counter++;
583 		ww_mutex_unlock(&d->mtx);
584 	}
585 
586 	ww_mutex_lock_slow(&d->mtx, NULL);
587 	d->counter++;
588 	ww_mutex_unlock(&d->mtx);
589 
590 	ww_mutex_destroy(&d->mtx);
591 }
592 
593 static void __used test_ww_mutex_lock_ctx(struct test_ww_mutex_data *d)
594 {
595 	struct ww_acquire_ctx ctx;
596 
597 	ww_acquire_init(&ctx, &ww_class);
598 
599 	if (!ww_mutex_lock(&d->mtx, &ctx)) {
600 		d->counter++;
601 		ww_mutex_unlock(&d->mtx);
602 	}
603 
604 	if (!ww_mutex_lock_interruptible(&d->mtx, &ctx)) {
605 		d->counter++;
606 		ww_mutex_unlock(&d->mtx);
607 	}
608 
609 	if (ww_mutex_trylock(&d->mtx, &ctx)) {
610 		d->counter++;
611 		ww_mutex_unlock(&d->mtx);
612 	}
613 
614 	ww_mutex_lock_slow(&d->mtx, &ctx);
615 	d->counter++;
616 	ww_mutex_unlock(&d->mtx);
617 
618 	ww_acquire_done(&ctx);
619 	ww_acquire_fini(&ctx);
620 
621 	ww_mutex_destroy(&d->mtx);
622 }
623 
624 static DEFINE_PER_CPU(raw_spinlock_t, test_per_cpu_lock);
625 
626 static void __used test_per_cpu(int cpu)
627 {
628 	raw_spin_lock(&per_cpu(test_per_cpu_lock, cpu));
629 	raw_spin_unlock(&per_cpu(test_per_cpu_lock, cpu));
630 
631 	raw_spin_lock(per_cpu_ptr(&test_per_cpu_lock, cpu));
632 	raw_spin_unlock(per_cpu_ptr(&test_per_cpu_lock, cpu));
633 }
634