intr_event_handle never sends EOI if we fail to schedule ithread
John Baldwin
jhb at freebsd.org
Tue Feb 26 22:09:27 UTC 2013
On Thursday, February 21, 2013 5:10:44 pm Ryan Stone wrote:
> I recently saw an issue where all interrupts from a particular interrupt
> vector were never raised. After investigating it appears that I ran into
> the bug fixed in r239095[1], where an interrupt handler that uses an
> ithread was added to the list of interrupt handlers for a particular event
> before the ithread was allocated. If an interrupt for this event
> (presumably for a different device sharing the same interrupt line) comes
> in after the handler is added to the list but before the ithread has been
> allocated we hit the following code:
>
> if (thread) {
> if (ie->ie_pre_ithread != NULL)
> ie->ie_pre_ithread(ie->ie_source);
> } else {
> if (ie->ie_post_filter != NULL)
> ie->ie_post_filter(ie->ie_source);
> }
>
> /* Schedule the ithread if needed. */
> if (thread) {
> error = intr_event_schedule_thread(ie);
> #ifndef XEN
> KASSERT(error == 0, ("bad stray interrupt"));
> #else
> if (error != 0)
> log(LOG_WARNING, "bad stray interrupt");
> #endif
> }
>
> thread is true, so we will not run ie_post_filter (which would send the
> EOI). However because the ithread has not been allocated
> intr_event_schedule_thread will return an error. If INVARIANTS is not
> defined we skip the KASSERT and return.
>
> Now, r239095 fixes this scenario, but I think that we should call
> ie_post_filter whenever intr_event_schedule_thread fails to ensure that we
> don't block an interrupt vector indefinitely. Any comments?
Actually, I think you want to call post_ithread as you've already called
pre_ithread? Also, pre_ithread should already EOI the interrupt, the problem
is that it leaves it masked, and you need to invoke post_ithread to unmask it.
--
John Baldwin
More information about the freebsd-hackers
mailing list