| 1605 | } |
| 1606 | |
| 1607 | void |
| 1608 | _lockmgr_disown(struct lock *lk, const char *file, int line) |
| 1609 | { |
| 1610 | uintptr_t tid, x; |
| 1611 | |
| 1612 | if (SCHEDULER_STOPPED()) |
| 1613 | return; |
| 1614 | |
| 1615 | tid = (uintptr_t)curthread; |
| 1616 | _lockmgr_assert(lk, KA_XLOCKED, file, line); |
| 1617 | |
| 1618 | /* |
| 1619 | * Panic if the lock is recursed. |
| 1620 | */ |
| 1621 | if (lockmgr_xlocked(lk) && lockmgr_recursed(lk)) |
| 1622 | panic("%s: disown a recursed lockmgr @ %s:%d\n", |
| 1623 | __func__, file, line); |
| 1624 | |
| 1625 | /* |
| 1626 | * If the owner is already LK_KERNPROC just skip the whole operation. |
| 1627 | */ |
| 1628 | if (LK_HOLDER(lk->lk_lock) != tid) |
| 1629 | return; |
| 1630 | lock_profile_release_lock(&lk->lock_object); |
| 1631 | LOCKSTAT_RECORD1(lockmgr__disown, lk, LOCKSTAT_WRITER); |
| 1632 | LOCK_LOG_LOCK("XDISOWN", &lk->lock_object, 0, 0, file, line); |
| 1633 | WITNESS_UNLOCK(&lk->lock_object, LOP_EXCLUSIVE, file, line); |
| 1634 | TD_LOCKS_DEC(curthread); |
| 1635 | STACK_SAVE(lk); |
| 1636 | |
| 1637 | /* |
| 1638 | * In order to preserve waiters flags, just spin. |
| 1639 | */ |
| 1640 | for (;;) { |
| 1641 | x = lockmgr_read_value(lk); |
| 1642 | MPASS((x & LK_EXCLUSIVE_SPINNERS) == 0); |
| 1643 | x &= LK_ALL_WAITERS; |
| 1644 | if (atomic_cmpset_rel_ptr(&lk->lk_lock, tid | x, |
| 1645 | LK_KERNPROC | x)) |
| 1646 | return; |
| 1647 | cpu_spinwait(); |
| 1648 | } |
| 1649 | } |
| 1650 | |
| 1651 | void |
| 1652 | lockmgr_printinfo(const struct lock *lk) |
nothing calls this directly
no test coverage detected