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/bf073d01d483
branches: trunk
changeset: 1006637:bf073d01d483
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 59e96cd85128 -r bf073d01d483 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 59e96cd85128 -r bf073d01d483 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 59e96cd85128 -r bf073d01d483 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