summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-12-29 20:53:01 +0000
committerjhb <jhb@FreeBSD.org>2005-12-29 20:53:01 +0000
commite782568056d47ca9a4a92a91f85a894c56443095 (patch)
tree633e42f5f0180b5c2aa2ccbe8be3b3f173a894b9 /sys
parent1d6dbee26a3e24d7433b35078ba5762d1661c597 (diff)
downloadFreeBSD-src-e782568056d47ca9a4a92a91f85a894c56443095.zip
FreeBSD-src-e782568056d47ca9a4a92a91f85a894c56443095.tar.gz
Fix a deadlock I introduced with the recently added printf to warn about
spin locks that are not in the static order list. It is not safe to call printf while holding the witness spin mutex since the console drivers that back printf may need to use their own spin locks which would try to talk to witness when they were locked. Given this, it is possible for one CPU to lock a console driver lock (such as sio) which then tries to lock the witness lock while another CPU is doing the printf while holding the witness lock. Fix this by moving the printf outside of the witness lock. All other printf's in witness are already correct. MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_witness.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index bd52611..12e64f1 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -1409,18 +1409,8 @@ enroll(const char *description, struct lock_class *lock_class)
return (w);
}
}
- /*
- * We issue a warning for any spin locks not defined in the static
- * order list as a way to discourage their use (folks should really
- * be using non-spin mutexes most of the time). However, several
- * 3rd part device drivers use spin locks because that is all they
- * have available on Windows and Linux and they think that normal
- * mutexes are insufficient.
- */
- if ((lock_class->lc_flags & LC_SPINLOCK) && witness_spin_warn)
- printf("WITNESS: spin lock %s not in order list", description);
if ((w = witness_get()) == NULL)
- return (NULL);
+ goto out;
w->w_name = description;
w->w_class = lock_class;
w->w_refcount = 1;
@@ -1437,6 +1427,18 @@ enroll(const char *description, struct lock_class *lock_class)
lock_class->lc_name);
}
mtx_unlock_spin(&w_mtx);
+out:
+ /*
+ * We issue a warning for any spin locks not defined in the static
+ * order list as a way to discourage their use (folks should really
+ * be using non-spin mutexes most of the time). However, several
+ * 3rd part device drivers use spin locks because that is all they
+ * have available on Windows and Linux and they think that normal
+ * mutexes are insufficient.
+ */
+ if ((lock_class->lc_flags & LC_SPINLOCK) && witness_spin_warn)
+ printf("WITNESS: spin lock %s not in order list\n",
+ description);
return (w);
}
@@ -1978,7 +1980,7 @@ DB_SHOW_COMMAND(alllocks, db_witness_list_all)
FOREACH_THREAD_IN_PROC(p, td) {
if (!witness_thread_has_locks(td))
continue;
- printf("Process %d (%s) thread %p (%d)\n", p->p_pid,
+ db_printf("Process %d (%s) thread %p (%d)\n", p->p_pid,
p->p_comm, td, td->td_tid);
witness_list(td);
}
OpenPOWER on IntegriCloud