diff options
author | jhb <jhb@FreeBSD.org> | 2005-12-29 20:53:01 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2005-12-29 20:53:01 +0000 |
commit | e782568056d47ca9a4a92a91f85a894c56443095 (patch) | |
tree | 633e42f5f0180b5c2aa2ccbe8be3b3f173a894b9 | |
parent | 1d6dbee26a3e24d7433b35078ba5762d1661c597 (diff) | |
download | FreeBSD-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
-rw-r--r-- | sys/kern/subr_witness.c | 26 |
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); } |