--- /usr/src/sys/kern/kern_lock.c 2008-02-06 14:26:01.000000000 +0100 +++ sys/kern/kern_lock.c 2008-02-08 13:01:40.000000000 +0100 @@ -205,6 +205,15 @@ error = 0; td = curthread; +#ifdef INVARIANTS + if (lkp->lk_flags & LK_DESTROYED) { + if (flags & LK_INTERLOCK) + mtx_unlock(interlkp); + if (panicstr != NULL) + return (0); + panic("%s: %p lockmgr is destroyed", __func__, lkp); + } +#endif if ((flags & LK_INTERNAL) == 0) mtx_lock(lkp->lk_interlock); CTR6(KTR_LOCK, @@ -562,6 +571,10 @@ CTR2(KTR_LOCK, "lockdestroy(): lkp == %p (lk_wmesg == \"%s\")", lkp, lkp->lk_wmesg); + KASSERT((lkp->lk_flags & (LK_HAVE_EXCL | LK_SHARE_NONZERO)) == 0, + ("lockmgr still held")); + KASSERT(lkp->lk_exclusivecount == 0, ("lockmgr still recursed")); + lkp->lk_flags = LK_DESTROYED; lock_destroy(&lkp->lk_object); } @@ -574,6 +587,8 @@ struct thread *td; td = curthread; + KASSERT(panicstr != NULL || (lkp->lk_flags & LK_DESTROYED) == 0, + ("%s: %p lockmgr is destroyed", __func__, lkp)); KASSERT(panicstr != NULL || lkp->lk_exclusivecount, ("%s: %p lockmgr must be exclusively locked", __func__, lkp)); KASSERT(panicstr != NULL || lkp->lk_lockholder == td || @@ -608,6 +623,8 @@ KASSERT(td == NULL || td == curthread, ("%s: thread passed argument (%p) is not valid", __func__, td)); + KASSERT((lkp->lk_flags & LK_DESTROYED) == 0, + ("%s: %p lockmgr is destroyed", __func__, lkp)); if (!kdb_active) { interlocked = 1; @@ -635,6 +652,8 @@ { int count; + KASSERT((lkp->lk_flags & LK_DESTROYED) == 0, + ("%s: %p lockmgr is destroyed", __func__, lkp)); mtx_lock(lkp->lk_interlock); count = lkp->lk_waitcount; mtx_unlock(lkp->lk_interlock); --- /usr/src/sys/sys/lockmgr.h 2008-02-06 01:37:14.000000000 +0100 +++ sys/sys/lockmgr.h 2008-02-08 12:43:00.000000000 +0100 @@ -137,7 +137,8 @@ #define LK_HAVE_EXCL 0x00040000 /* exclusive lock obtained */ #define LK_WAITDRAIN 0x00080000 /* process waiting for lock to drain */ #define LK_DRAINING 0x00100000 /* lock is being drained */ -#define LK_INTERNAL 0x00200000/* The internal lock is already held */ +#define LK_INTERNAL 0x00200000 /* The internal lock is already held */ +#define LK_DESTROYED 0x00400000 /* lock is destroyed */ /* * Internal state flags corresponding to lk_sharecount, and lk_waitcount */