| 2427 | } |
| 2428 | |
| 2429 | void |
| 2430 | witness_assert(const struct lock_object *lock, int flags, const char *file, |
| 2431 | int line) |
| 2432 | { |
| 2433 | #ifdef INVARIANT_SUPPORT |
| 2434 | struct lock_instance *instance; |
| 2435 | struct lock_class *class; |
| 2436 | |
| 2437 | if (lock->lo_witness == NULL || witness_watch < 1 || KERNEL_PANICKED()) |
| 2438 | return; |
| 2439 | class = LOCK_CLASS(lock); |
| 2440 | if ((class->lc_flags & LC_SLEEPLOCK) != 0) |
| 2441 | instance = find_instance(curthread->td_sleeplocks, lock); |
| 2442 | else if ((class->lc_flags & LC_SPINLOCK) != 0) |
| 2443 | instance = find_instance(PCPU_GET(spinlocks), lock); |
| 2444 | else { |
| 2445 | kassert_panic("Lock (%s) %s is not sleep or spin!", |
| 2446 | class->lc_name, lock->lo_name); |
| 2447 | return; |
| 2448 | } |
| 2449 | switch (flags) { |
| 2450 | case LA_UNLOCKED: |
| 2451 | if (instance != NULL) |
| 2452 | kassert_panic("Lock (%s) %s locked @ %s:%d.", |
| 2453 | class->lc_name, lock->lo_name, |
| 2454 | fixup_filename(file), line); |
| 2455 | break; |
| 2456 | case LA_LOCKED: |
| 2457 | case LA_LOCKED | LA_RECURSED: |
| 2458 | case LA_LOCKED | LA_NOTRECURSED: |
| 2459 | case LA_SLOCKED: |
| 2460 | case LA_SLOCKED | LA_RECURSED: |
| 2461 | case LA_SLOCKED | LA_NOTRECURSED: |
| 2462 | case LA_XLOCKED: |
| 2463 | case LA_XLOCKED | LA_RECURSED: |
| 2464 | case LA_XLOCKED | LA_NOTRECURSED: |
| 2465 | if (instance == NULL) { |
| 2466 | kassert_panic("Lock (%s) %s not locked @ %s:%d.", |
| 2467 | class->lc_name, lock->lo_name, |
| 2468 | fixup_filename(file), line); |
| 2469 | break; |
| 2470 | } |
| 2471 | if ((flags & LA_XLOCKED) != 0 && |
| 2472 | (instance->li_flags & LI_EXCLUSIVE) == 0) |
| 2473 | kassert_panic( |
| 2474 | "Lock (%s) %s not exclusively locked @ %s:%d.", |
| 2475 | class->lc_name, lock->lo_name, |
| 2476 | fixup_filename(file), line); |
| 2477 | if ((flags & LA_SLOCKED) != 0 && |
| 2478 | (instance->li_flags & LI_EXCLUSIVE) != 0) |
| 2479 | kassert_panic( |
| 2480 | "Lock (%s) %s exclusively locked @ %s:%d.", |
| 2481 | class->lc_name, lock->lo_name, |
| 2482 | fixup_filename(file), line); |
| 2483 | if ((flags & LA_RECURSED) != 0 && |
| 2484 | (instance->li_flags & LI_RECURSEMASK) == 0) |
| 2485 | kassert_panic("Lock (%s) %s not recursed @ %s:%d.", |
| 2486 | class->lc_name, lock->lo_name, |
no test coverage detected