Do not add handler to event handlers list until ithread is created.

In rare event when fast and ithread interrupts share the same vector
and the fast handler was registered first, we can end up trying to
schedule the ithread that is not created yet. The kernel built with
INVARIANTS then triggers an assertion.

Change the order to create the ithread first and only then add the
handler that needs it to the interrupt event handlers list.

Reviewed by: jhb
This commit is contained in:
Alexander Kabaev 2012-08-06 16:37:43 +00:00
parent 17369272e4
commit c9516c94b4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=239095

View file

@ -545,17 +545,6 @@ intr_event_add_handler(struct intr_event *ie, const char *name,
}
}
/* Add the new handler to the event in priority order. */
TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
if (temp_ih->ih_pri > ih->ih_pri)
break;
}
if (temp_ih == NULL)
TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
else
TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
intr_event_update(ie);
/* Create a thread if we need one. */
while (ie->ie_thread == NULL && handler != NULL) {
if (ie->ie_flags & IE_ADDING_THREAD)
@ -572,6 +561,18 @@ intr_event_add_handler(struct intr_event *ie, const char *name,
wakeup(ie);
}
}
/* Add the new handler to the event in priority order. */
TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
if (temp_ih->ih_pri > ih->ih_pri)
break;
}
if (temp_ih == NULL)
TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
else
TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
intr_event_update(ie);
CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name,
ie->ie_name);
mtx_unlock(&ie->ie_lock);
@ -618,23 +619,12 @@ intr_event_add_handler(struct intr_event *ie, const char *name,
}
}
/* Add the new handler to the event in priority order. */
TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
if (temp_ih->ih_pri > ih->ih_pri)
break;
}
if (temp_ih == NULL)
TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
else
TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
intr_event_update(ie);
/* For filtered handlers, create a private ithread to run on. */
if (filter != NULL && handler != NULL) {
if (filter != NULL && handler != NULL) {
mtx_unlock(&ie->ie_lock);
it = ithread_create("intr: newborn", ih);
it = ithread_create("intr: newborn", ih);
mtx_lock(&ie->ie_lock);
it->it_event = ie;
it->it_event = ie;
ih->ih_thread = it;
ithread_update(it); /* XXX - do we really need this?!?!? */
} else { /* Create the global per-event thread if we need one. */
@ -654,6 +644,18 @@ intr_event_add_handler(struct intr_event *ie, const char *name,
}
}
}
/* Add the new handler to the event in priority order. */
TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
if (temp_ih->ih_pri > ih->ih_pri)
break;
}
if (temp_ih == NULL)
TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
else
TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
intr_event_update(ie);
CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name,
ie->ie_name);
mtx_unlock(&ie->ie_lock);