summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_mutex.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-02-09 15:19:41 +0000
committerjhb <jhb@FreeBSD.org>2001-02-09 15:19:41 +0000
commit67e1fedd42a4aa128403f62f31e11810d595614e (patch)
treefaad9666023d46e2779b14528aeba5484b67f40f /sys/kern/kern_mutex.c
parent168396f1022b9e37c07ae7a1ee11d4818118c1c8 (diff)
downloadFreeBSD-src-67e1fedd42a4aa128403f62f31e11810d595614e.zip
FreeBSD-src-67e1fedd42a4aa128403f62f31e11810d595614e.tar.gz
- Change the 'witness_list' ddb command to 'show mutexes'. Note that this
will only display sleep mutexes held by the current process. - Clean up some nits in the witness_display() function and add a ddb command 'show witness' that dumps the hierarchy and order lists to the console. - Use queue(3) macros where appropriate. - Resort the spin lock order list so that "com" is before "sched_lock". Also, add appropriate #ifdef's around SMP and i386-specific mutexes. - Add two new mutexes used to protect the ithread lists and tables to the order list. Requested by: bde (1)
Diffstat (limited to 'sys/kern/kern_mutex.c')
-rw-r--r--sys/kern/kern_mutex.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index 64d3972..2c53137 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -945,7 +945,13 @@ static char *ignore_list[] = {
};
static char *spin_order_list[] = {
+#if defined(__i386__) && defined (SMP)
+ "com",
+#endif
"sio",
+#ifdef __i386__
+ "cy",
+#endif
"sched lock",
#ifdef __i386__
"clk",
@@ -954,12 +960,15 @@ static char *spin_order_list[] = {
/*
* leaf locks
*/
+ "ithread table lock",
+ "ithread list lock",
+#ifdef SMP
#ifdef __i386__
"ap boot",
"imen",
#endif
- "com",
"smp rendezvous",
+#endif
NULL
};
@@ -999,8 +1008,7 @@ witness_destroy(struct mtx *m)
struct mtx *m1;
struct proc *p;
p = CURPROC;
- for ((m1 = LIST_FIRST(&p->p_heldmtx)); m1 != NULL;
- m1 = LIST_NEXT(m1, mtx_held)) {
+ LIST_FOREACH(m1, &p->p_heldmtx, mtx_held) {
if (m1 == m) {
LIST_REMOVE(m, mtx_held);
break;
@@ -1014,12 +1022,18 @@ static void
witness_display(void(*prnt)(const char *fmt, ...))
{
struct witness *w, *w1;
+ int level, found;
KASSERT(!witness_cold, ("%s: witness_cold\n", __FUNCTION__));
witness_levelall();
+ /*
+ * First, handle sleep mutexes which have been acquired at least
+ * once.
+ */
+ prnt("Sleep mutexes:\n");
for (w = w_all; w; w = w->w_next) {
- if (w->w_file == NULL)
+ if (w->w_file == NULL || w->w_spin)
continue;
for (w1 = w_all; w1; w1 = w1->w_next) {
if (isitmychild(w1, w))
@@ -1032,7 +1046,31 @@ witness_display(void(*prnt)(const char *fmt, ...))
*/
witness_displaydescendants(prnt, w);
}
- prnt("\nMutex which were never acquired\n");
+
+ /*
+ * Now do spin mutexes which have been acquired at least once.
+ */
+ prnt("\nSpin mutexes:\n");
+ level = 0;
+ while (level < sizeof(spin_order_list) / sizeof(char *)) {
+ found = 0;
+ for (w = w_all; w; w = w->w_next) {
+ if (w->w_file == NULL || !w->w_spin)
+ continue;
+ if (w->w_level == 1 << level) {
+ witness_displaydescendants(prnt, w);
+ level++;
+ found = 1;
+ }
+ }
+ if (found == 0)
+ level++;
+ }
+
+ /*
+ * Finally, any mutexes which have not been acquired yet.
+ */
+ prnt("\nMutexes which were never acquired:\n");
for (w = w_all; w; w = w->w_next) {
if (w->w_file != NULL)
continue;
@@ -1298,13 +1336,14 @@ witness_sleep(int check_only, struct mtx *mtx, const char *file, int line)
KASSERT(!witness_cold, ("%s: witness_cold\n", __FUNCTION__));
p = CURPROC;
- for ((m = LIST_FIRST(&p->p_heldmtx)); m != NULL;
- m = LIST_NEXT(m, mtx_held)) {
+ LIST_FOREACH(m, &p->p_heldmtx, mtx_held) {
if (m == mtx)
continue;
for (sleep = sleep_list; *sleep!= NULL; sleep++)
if (strcmp(m->mtx_description, *sleep) == 0)
goto next;
+ if (n == 0)
+ printf("Whee!\n");
printf("%s:%d: %s with \"%s\" locked from %s:%d\n",
file, line, check_only ? "could sleep" : "sleeping",
m->mtx_description,
@@ -1528,7 +1567,9 @@ witness_displaydescendants(void(*prnt)(const char *fmt, ...),
{
struct witness *w;
int i;
- int level = parent->w_level;
+ int level;
+
+ level = parent->w_spin ? ffs(parent->w_level) : parent->w_level;
prnt("%d", level);
if (level < 10)
@@ -1536,13 +1577,9 @@ witness_displaydescendants(void(*prnt)(const char *fmt, ...),
for (i = 0; i < level; i++)
prnt(" ");
prnt("%s", parent->w_description);
- if (parent->w_file != NULL) {
- prnt(" -- last acquired @ %s", parent->w_file);
-#ifndef W_USE_WHERE
- prnt(":%d", parent->w_line);
-#endif
- prnt("\n");
- }
+ if (parent->w_file != NULL)
+ prnt(" -- last acquired @ %s:%d\n", parent->w_file,
+ parent->w_line);
for (w = parent; w != NULL; w = w->w_morechildren)
for (i = 0; i < w->w_childcnt; i++)
@@ -1611,8 +1648,7 @@ witness_list(struct proc *p)
KASSERT(!witness_cold, ("%s: witness_cold\n", __FUNCTION__));
nheld = 0;
- for ((m = LIST_FIRST(&p->p_heldmtx)); m != NULL;
- m = LIST_NEXT(m, mtx_held)) {
+ LIST_FOREACH(m, &p->p_heldmtx, mtx_held) {
printf("\t\"%s\" (%p) locked at %s:%d\n",
m->mtx_description, m,
m->mtx_witness->w_file, m->mtx_witness->w_line);
@@ -1624,12 +1660,17 @@ witness_list(struct proc *p)
#ifdef DDB
-DB_COMMAND(witness_list, db_witness_list)
+DB_SHOW_COMMAND(mutexes, db_witness_list)
{
witness_list(CURPROC);
}
+DB_SHOW_COMMAND(witness, db_witness_display)
+{
+
+ witness_display(db_printf);
+}
#endif
void
OpenPOWER on IntegriCloud