Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys ddb's "show all locks":



details:   https://anonhg.NetBSD.org/src/rev/423308320110
branches:  trunk
changeset: 848236:423308320110
user:      ad <ad%NetBSD.org@localhost>
date:      Tue Jan 21 20:31:57 2020 +0000

description:
ddb's "show all locks":

- Make the output easier to scan quickly.

- Show every LWP that is blocked on a lock, and the details of the lock.

diffstat:

 sys/kern/kern_turnstile.c |  12 ++----
 sys/kern/subr_lockdebug.c |  80 +++++++++++++++++++++++++++++++---------------
 sys/sys/lwp.h             |   3 +-
 3 files changed, 59 insertions(+), 36 deletions(-)

diffs (262 lines):

diff -r 3cc48c2de449 -r 423308320110 sys/kern/kern_turnstile.c
--- a/sys/kern/kern_turnstile.c Tue Jan 21 20:29:51 2020 +0000
+++ b/sys/kern/kern_turnstile.c Tue Jan 21 20:31:57 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_turnstile.c,v 1.35 2019/12/16 19:22:15 ad Exp $   */
+/*     $NetBSD: kern_turnstile.c,v 1.36 2020/01/21 20:31:57 ad Exp $   */
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2009, 2019 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.35 2019/12/16 19:22:15 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.36 2020/01/21 20:31:57 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/lockdebug.h>
@@ -536,29 +536,25 @@
        turnstile_t *ts;
        tschain_t *tc;
        sleepq_t *rsq, *wsq;
-       kmutex_t *lock;
        u_int hash;
        lwp_t *l;
 
        hash = TS_HASH(obj);
        tc = &turnstile_chains[hash];
-       lock = &turnstile_locks[hash].lock;
 
        LIST_FOREACH(ts, tc, ts_chain)
                if (ts->ts_obj == obj)
                        break;
 
-       (*pr)("Turnstile chain at %p with mutex %p.\n", tc, lock);
        if (ts == NULL) {
-               (*pr)("=> No active turnstile for this lock.\n");
+               (*pr)("Turnstile: no active turnstile for this lock.\n");
                return;
        }
 
        rsq = &ts->ts_sleepq[TS_READER_Q];
        wsq = &ts->ts_sleepq[TS_WRITER_Q];
 
-       (*pr)("=> Turnstile at %p (wrq=%p, rdq=%p).\n", ts, rsq, wsq);
-
+       (*pr)("Turnstile:\n");
        (*pr)("=> %d waiting readers:", TS_WAITERS(ts, TS_READER_Q));
        TAILQ_FOREACH(l, rsq, l_sleepchain) {
                (*pr)(" %p", l);
diff -r 3cc48c2de449 -r 423308320110 sys/kern/subr_lockdebug.c
--- a/sys/kern/subr_lockdebug.c Tue Jan 21 20:29:51 2020 +0000
+++ b/sys/kern/subr_lockdebug.c Tue Jan 21 20:31:57 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: subr_lockdebug.c,v 1.73 2020/01/08 16:21:34 ad Exp $   */
+/*     $NetBSD: subr_lockdebug.c,v 1.74 2020/01/21 20:31:57 ad Exp $   */
 
 /*-
  * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_lockdebug.c,v 1.73 2020/01/08 16:21:34 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_lockdebug.c,v 1.74 2020/01/21 20:31:57 ad Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -108,7 +108,8 @@
     const char *, bool);
 static int     lockdebug_more(int);
 static void    lockdebug_init(void);
-static void    lockdebug_dump(lockdebug_t *, void (*)(const char *, ...)
+static void    lockdebug_dump(lwp_t *, lockdebug_t *,
+    void (*)(const char *, ...)
     __printflike(1, 2));
 
 static signed int
@@ -468,6 +469,9 @@
                    true);
                return;
        }
+       if (l->l_ld_wanted == NULL) {
+               l->l_ld_wanted = ld;
+       }
        __cpu_simple_unlock(&ld->ld_spinlock);
        splx(s);
 }
@@ -529,6 +533,9 @@
        ld->ld_cpu = (uint16_t)cpu_index(curcpu());
        ld->ld_lwp = l;
        __cpu_simple_unlock(&ld->ld_spinlock);
+       if (l->l_ld_wanted == ld) {
+               l->l_ld_wanted = NULL;
+       }
        splx(s);
 }
 
@@ -692,7 +699,7 @@
                        if (ld->ld_lockops->lo_type == LOCKOPS_CV)
                                continue;
                        if (ld->ld_lwp == l)
-                               lockdebug_dump(ld, printf);
+                               lockdebug_dump(l, ld, printf);
                }
                panic("%s,%zu: holding %d shared locks", func, line,
                    l->l_shlocks);
@@ -744,7 +751,7 @@
  *     Dump information about a lock on panic, or for DDB.
  */
 static void
-lockdebug_dump(lockdebug_t *ld, void (*pr)(const char *, ...)
+lockdebug_dump(lwp_t *l, lockdebug_t *ld, void (*pr)(const char *, ...)
     __printflike(1, 2))
 {
        int sleeper = (ld->ld_flags & LD_SLEEPER);
@@ -761,13 +768,13 @@
                (*pr)("\n"
                    "shared holds : %18u exclusive: %18u\n"
                    "shares wanted: %18u exclusive: %18u\n"
-                   "current cpu  : %18u last held: %18u\n"
-                   "current lwp  : %#018lx last held: %#018lx\n"
+                   "relevant cpu : %18u last held: %18u\n"
+                   "relevant lwp : %#018lx last held: %#018lx\n"
                    "last locked%c : %#018lx unlocked%c: %#018lx\n",
                    (unsigned)ld->ld_shares, ((ld->ld_flags & LD_LOCKED) != 0),
                    (unsigned)ld->ld_shwant, (unsigned)ld->ld_exwant,
-                   (unsigned)cpu_index(curcpu()), (unsigned)ld->ld_cpu,
-                   (long)curlwp, (long)ld->ld_lwp,
+                   (unsigned)cpu_index(l->l_cpu), (unsigned)ld->ld_cpu,
+                   (long)l, (long)ld->ld_lwp,
                    ((ld->ld_flags & LD_LOCKED) ? '*' : ' '),
                    (long)ld->ld_locked,
                    ((ld->ld_flags & LD_LOCKED) ? ' ' : '*'),
@@ -778,7 +785,6 @@
                (*ld->ld_lockops->lo_dump)(ld->ld_lock, pr);
 
        if (sleeper) {
-               (*pr)("\n");
                turnstile_print(ld->ld_lock, pr);
        }
 }
@@ -806,7 +812,7 @@
 
        printf_nolog("%s error: %s,%zu: %s\n\n", ld->ld_lockops->lo_name,
            func, line, msg);
-       lockdebug_dump(ld, printf_nolog);
+       lockdebug_dump(curlwp, ld, printf_nolog);
        __cpu_simple_unlock(&ld->ld_spinlock);
        splx(s);
        printf_nolog("\n");
@@ -837,7 +843,7 @@
                if (ld->ld_lock == NULL)
                        continue;
                if (addr == NULL || ld->ld_lock == addr) {
-                       lockdebug_dump(ld, pr);
+                       lockdebug_dump(curlwp, ld, pr);
                        if (addr != NULL)
                                return;
                }
@@ -853,15 +859,15 @@
 
 #ifdef LOCKDEBUG
 static void
-lockdebug_show_one(lockdebug_t *ld, int i,
+lockdebug_show_one(lwp_t *l, lockdebug_t *ld, int i,
     void (*pr)(const char *, ...) __printflike(1, 2))
 {
        const char *sym;
 
        ksyms_getname(NULL, &sym, (vaddr_t)ld->ld_initaddr,
            KSYMS_CLOSEST|KSYMS_PROC|KSYMS_ANY);
-       (*pr)("Lock %d (initialized at %s)\n", i++, sym);
-       lockdebug_dump(ld, pr);
+       (*pr)("* Lock %d (initialized at %s)\n", i++, sym);
+       lockdebug_dump(l, ld, pr);
 }
 
 static void
@@ -882,16 +888,34 @@
                LIST_FOREACH(l, &p->p_lwps, l_sibling) {
                        lockdebug_t *ld;
                        int i = 0;
-                       if (TAILQ_EMPTY(&l->l_ld_locks))
-                               continue;
-                       (*pr)("Locks held by an LWP (%s):\n",
-                           l->l_name ? l->l_name : p->p_comm);
-                       TAILQ_FOREACH(ld, &l->l_ld_locks, ld_chain) {
-                               lockdebug_show_one(ld, i++, pr);
+                       if (TAILQ_EMPTY(&l->l_ld_locks) &&
+                           l->l_ld_wanted == NULL) {
+                               continue;
                        }
-                       if (show_trace)
+                       (*pr)("\n****** LWP %d.%d (%s) @ %p, l_stat=%d\n",
+                           p->p_pid, l->l_lid,
+                           l->l_name ? l->l_name : p->p_comm, l, l->l_stat);
+                       if (!TAILQ_EMPTY(&l->l_ld_locks)) {
+                               (*pr)("\n*** Locks held: \n");
+                               TAILQ_FOREACH(ld, &l->l_ld_locks, ld_chain) {
+                                       (*pr)("\n");
+                                       lockdebug_show_one(l, ld, i++, pr);
+                               }
+                       } else {
+                               (*pr)("\n*** Locks held: none\n");
+                       }
+
+                       if (l->l_ld_wanted != NULL) {
+                               (*pr)("\n*** Locks wanted: \n\n");
+                               lockdebug_show_one(l, l->l_ld_wanted, 0, pr);
+                       } else {
+                               (*pr)("\n*** Locks wanted: none\n");
+                       }
+                       if (show_trace) {
+                               (*pr)("\n*** Traceback: \n\n");
                                lockdebug_show_trace(l, pr);
-                       (*pr)("\n");
+                               (*pr)("\n");
+                       }
                }
        }
 }
@@ -908,16 +932,18 @@
                int i = 0;
                if (TAILQ_EMPTY(&ci->ci_data.cpu_ld_locks))
                        continue;
-               (*pr)("Locks held on CPU %u:\n", ci->ci_index);
+               (*pr)("\n******* Locks held on %s:\n", cpu_name(ci));
                TAILQ_FOREACH(ld, &ci->ci_data.cpu_ld_locks, ld_chain) {
-                       lockdebug_show_one(ld, i++, pr);
+                       (*pr)("\n");
+#ifdef MULTIPROCESSOR
+                       lockdebug_show_one(ci->ci_curlwp, ld, i++, pr);
                        if (show_trace)
-#ifdef MULTIPROCESSOR
                                lockdebug_show_trace(ci->ci_curlwp, pr);
 #else
+                       lockdebug_show_one(curlwp, ld, i++, pr);
+                       if (show_trace)
                                lockdebug_show_trace(curlwp, pr);
 #endif
-                       (*pr)("\n");
                }
        }
 }
diff -r 3cc48c2de449 -r 423308320110 sys/sys/lwp.h
--- a/sys/sys/lwp.h     Tue Jan 21 20:29:51 2020 +0000
+++ b/sys/sys/lwp.h     Tue Jan 21 20:31:57 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lwp.h,v 1.196 2020/01/12 22:03:23 ad Exp $     */
+/*     $NetBSD: lwp.h,v 1.197 2020/01/21 20:31:57 ad Exp $     */
 
 /*
  * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019
@@ -196,6 +196,7 @@
        uintptr_t       l_pfailaddr;    /* !: for kernel preemption */
        uintptr_t       l_pfaillock;    /* !: for kernel preemption */
        _TAILQ_HEAD(,struct lockdebug,volatile) l_ld_locks;/* !: locks held by LWP */
+       volatile void   *l_ld_wanted;   /* !: lock currently wanted by LWP */
        uintptr_t       l_rwcallsite;   /* !: rwlock actual callsite */
        int             l_tcgen;        /* !: for timecounter removal */
 



Home | Main Index | Thread Index | Old Index