diff options
author | John Baldwin <jhb@FreeBSD.org> | 2005-12-13 23:14:35 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2005-12-13 23:14:35 +0000 |
commit | d272fe53a49fff21d1b3bf5e6f27f16676a1e07f (patch) | |
tree | e94aa8ca0732bb99e2dcaad4b3f1e7ef318a4d77 /sys/kern/kern_mutex.c | |
parent | 63ec04adea7c9903471ffeeb1bd61ab419c7314f (diff) | |
download | src-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.c | 75 |
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 |