aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_mutex.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2005-12-13 23:14:35 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2005-12-13 23:14:35 +0000
commitd272fe53a49fff21d1b3bf5e6f27f16676a1e07f (patch)
treee94aa8ca0732bb99e2dcaad4b3f1e7ef318a4d77 /sys/kern/kern_mutex.c
parent63ec04adea7c9903471ffeeb1bd61ab419c7314f (diff)
downloadsrc-d272fe53a49fff21d1b3bf5e6f27f16676a1e07f.tar.gz
src-d272fe53a49fff21d1b3bf5e6f27f16676a1e07f.zip
Add a new 'show lock' command to ddb. If the argument has a valid lock
class, then it displays various information about the lock and calls a new function pointer in lock_class (lc_ddb_show) to dump class-specific information about the lock as well (such as the owner of a mutex or xlock'ed sx lock). This is easier than staring at hex dumps of locks to figure out who owns the lock, etc. Note that extending lock_class doesn't affect the ABI for any kernel modules as the only code that deals with lock_class structures directly is kern_mutex.c, kern_sx.c, and witness. MFC after: 1 week
Notes
Notes: svn path=/head/; revision=153395
Diffstat (limited to 'sys/kern/kern_mutex.c')
-rw-r--r--sys/kern/kern_mutex.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index 874540de96a2..9f79ab40d507 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -89,16 +89,26 @@ __FBSDID("$FreeBSD$");
#define mtx_owner(m) (mtx_unowned((m)) ? NULL \
: (struct thread *)((m)->mtx_lock & MTX_FLAGMASK))
+#ifdef DDB
+static void db_show_mtx(struct lock_object *lock);
+#endif
+
/*
* Lock classes for sleep and spin mutexes.
*/
struct lock_class lock_class_mtx_sleep = {
"sleep mutex",
- LC_SLEEPLOCK | LC_RECURSABLE
+ LC_SLEEPLOCK | LC_RECURSABLE,
+#ifdef DDB
+ db_show_mtx
+#endif
};
struct lock_class lock_class_mtx_spin = {
"spin mutex",
- LC_SPINLOCK | LC_RECURSABLE
+ LC_SPINLOCK | LC_RECURSABLE,
+#ifdef DDB
+ db_show_mtx
+#endif
};
/*
@@ -905,3 +915,64 @@ mutex_init(void)
mtx_init(&devmtx, "cdev", NULL, MTX_DEF);
mtx_lock(&Giant);
}
+
+#ifdef DDB
+/* XXX: This function is not mutex-specific. */
+DB_SHOW_COMMAND(lock, db_show_lock)
+{
+ struct lock_object *lock;
+
+ if (!have_addr)
+ return;
+ lock = (struct lock_object *)addr;
+ if (lock->lo_class != &lock_class_mtx_sleep &&
+ lock->lo_class != &lock_class_mtx_spin &&
+ lock->lo_class != &lock_class_sx) {
+ db_printf("Unknown lock class\n");
+ return;
+ }
+ db_printf(" class: %s\n", lock->lo_class->lc_name);
+ db_printf(" name: %s\n", lock->lo_name);
+ if (lock->lo_type && lock->lo_type != lock->lo_name)
+ db_printf(" type: %s\n", lock->lo_type);
+ lock->lo_class->lc_ddb_show(lock);
+}
+
+void
+db_show_mtx(struct lock_object *lock)
+{
+ struct thread *td;
+ struct mtx *m;
+
+ m = (struct mtx *)lock;
+
+ db_printf(" flags: {");
+ if (m->mtx_object.lo_class == &lock_class_mtx_spin)
+ db_printf("SPIN");
+ else
+ db_printf("DEF");
+ if (m->mtx_object.lo_flags & LO_RECURSABLE)
+ db_printf(", RECURSE");
+ if (m->mtx_object.lo_flags & LO_DUPOK)
+ db_printf(", DUPOK");
+ db_printf("}\n");
+ db_printf(" state: {");
+ if (mtx_unowned(m))
+ db_printf("UNOWNED");
+ else {
+ db_printf("OWNED");
+ if (m->mtx_lock & MTX_CONTESTED)
+ db_printf(", CONTESTED");
+ if (m->mtx_lock & MTX_RECURSED)
+ db_printf(", RECURSED");
+ }
+ db_printf("}\n");
+ if (!mtx_unowned(m)) {
+ td = mtx_owner(m);
+ db_printf(" owner: %p (tid %d, pid %d, \"%s\")\n", td,
+ td->td_tid, td->td_proc->p_pid, td->td_proc->p_comm);
+ if (mtx_recursed(m))
+ db_printf(" recursed: %d\n", m->mtx_recurse);
+ }
+}
+#endif