summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-03-21 19:28:20 +0000
committerjhb <jhb@FreeBSD.org>2007-03-21 19:28:20 +0000
commit08da44e27516b630d6cbf52c35d4f1b35d08de38 (patch)
tree2fb38f6a510f332d49c81e60b0a249034b60b296 /sys/kern
parent46edec2346d7678769ef5afe43c12651dbe830aa (diff)
downloadFreeBSD-src-08da44e27516b630d6cbf52c35d4f1b35d08de38.zip
FreeBSD-src-08da44e27516b630d6cbf52c35d4f1b35d08de38.tar.gz
Handle the case when a thread is blocked on a lockmgr lock with LK_DRAIN
in DDB's 'show sleepchain'. MFC after: 3 days
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_lock.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 02254a4..3b67bfa 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -661,9 +661,22 @@ lockmgr_chain(struct thread *td, struct thread **ownerp)
lkp = td->td_wchan;
/* Simple test to see if wchan points to a lockmgr lock. */
- if (lkp->lk_wmesg != td->td_wmesg)
- return (0);
-
+ if (lkp->lk_wmesg == td->td_wmesg)
+ goto ok;
+
+ /*
+ * If this thread is doing a DRAIN, then it would be asleep on
+ * &lkp->lk_flags rather than lkp.
+ */
+ lkp = (struct lock *)((char *)td->td_wchan -
+ offsetof(struct lock, lk_flags));
+ if (lkp->lk_wmesg == td->td_wmesg && (lkp->lk_flags & LK_WAITDRAIN))
+ goto ok;
+
+ /* Doen't seem to be a lockmgr lock. */
+ return (0);
+
+ok:
/* Ok, we think we have a lockmgr lock, so output some details. */
db_printf("blocked on lk \"%s\" ", lkp->lk_wmesg);
if (lkp->lk_sharecount) {
OpenPOWER on IntegriCloud