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