- if ((lkp->lk_flags & LK_DRAINED) &&
- (((flags & LK_TYPE_MASK) != LK_RELEASE) ||
- lkp->lk_lockholder != pid))
- panic("lockmgr: using decommissioned lock");
+#ifdef DIAGNOSTIC
+ /*
+ * Once a lock has drained, the LK_DRAINING flag is set and an
+ * exclusive lock is returned. The only valid operation thereafter
+ * is a single release of that exclusive lock. This final release
+ * clears the LK_DRAINING flag and sets the LK_DRAINED flag. Any
+ * further requests of any sort will result in a panic. The bits
+ * selected for these two flags are chosen so that they will be set
+ * in memory that is freed (freed memory is filled with 0xdeadbeef).
+ */
+ if (lkp->lk_flags & (LK_DRAINING|LK_DRAINED)) {
+ if (lkp->lk_flags & LK_DRAINED)
+ panic("lockmgr: using decommissioned lock");
+ if ((flags & LK_TYPE_MASK) != LK_RELEASE ||
+ lkp->lk_lockholder != pid)
+ panic("lockmgr: non-release on draining lock: %d\n",
+ flags & LK_TYPE_MASK);
+ lkp->lk_flags &= ~LK_DRAINING;
+ lkp->lk_flags |= LK_DRAINED;
+ }
+#endif DIAGNOSTIC