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:
parent
ec5bf79869
commit
0a46ed7d56
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user