summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2004-01-13 22:55:46 +0000
committertruckman <truckman@FreeBSD.org>2004-01-13 22:55:46 +0000
commitb028f9e2688d87d96018f00c1d11e6e16cd4e111 (patch)
tree29f73b2d6b3136aed1f59ca68124354693ac85dd
parentdb0a9fc4de11e1379d9f2ca83f0208e6fa37e91d (diff)
downloadFreeBSD-src-b028f9e2688d87d96018f00c1d11e6e16cd4e111.zip
FreeBSD-src-b028f9e2688d87d96018f00c1d11e6e16cd4e111.tar.gz
If a device attach routine fails during boot and calls bus_teardown_intr(),
ithread_remove_handler() may fail to remove the interrupt handler if it decides to let the ithread do the removal. The problem is that during boot "cold" is set, which causes msleep() to return immediately. This will cause ithread_remove_handler() to fail to wait for the ithread to do the removal from the handler TAILQ before freeing the handler back to the heap. Bad things will happen when some other user of the TAILQ, such as ithread_add_handler() or the actual ithread attempts to use the freed handler. Fix the problem by forcing ithread_remove_handler() to do the actual removal itself if the "cold" flag is set. Reviewed by: jhb
-rw-r--r--sys/kern/kern_intr.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index e42cd10..e171da0 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -331,9 +331,13 @@ ok:
/*
* If the interrupt thread is already running, then just mark this
* handler as being dead and let the ithread do the actual removal.
+ *
+ * During a cold boot while cold is set, msleep() does not sleep,
+ * so we have to remove the handler here rather than letting the
+ * thread do it.
*/
mtx_lock_spin(&sched_lock);
- if (!TD_AWAITING_INTR(ithread->it_td)) {
+ if (!TD_AWAITING_INTR(ithread->it_td) && !cold) {
handler->ih_flags |= IH_DEAD;
/*
OpenPOWER on IntegriCloud