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