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
This commit is contained in:
John Baldwin 2005-12-29 20:53:01 +00:00
parent ec5bf79869
commit 0a46ed7d56

View File

@ -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);
}