x86: handling unregistered IRQs
authorBarret Rhoden <brho@cs.berkeley.edu>
Sun, 28 Sep 2014 23:37:00 +0000 (16:37 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 29 Sep 2014 01:42:53 +0000 (18:42 -0700)
If we receive an IRQ for a vector with no handler, then we don't know
how to send an EOI.  Before this commit, if you sent an I_TESTING, we
would just do nothing.  Since we don't send an EOI, we'd never receive
another interrupt.

In general, we probably shouldn't be receiving interrupts that we don't
have handlers registered for, but who knows.  For testing, at least, I
can imagine receiving more IRQs.

Note the bit about POKE too - those are racy and since poke doesn't go
through the main IRQ handling, it won't deal with the halt race
(abort_halt()).

kern/arch/x86/trap.c
kern/src/schedule.c

index d86f15c..8446b71 100644 (file)
@@ -502,7 +502,16 @@ void handle_irq(struct hw_trapframe *hw_tf)
                       core_id());
        /* TODO: RCU read lock */
        irq_h = irq_handlers[hw_tf->tf_trapno];
-       if (!irq_h || irq_h->check_spurious(hw_tf->tf_trapno))
+       if (!irq_h) {
+               warn_once("Received IRQ %d, had no handler registered!",
+                         hw_tf->tf_trapno);
+               /* If we don't have an IRQ handler, we don't know how to EOI.  Odds are,
+                * it's a LAPIC IRQ, such as I_TESTING */
+               if (!lapic_check_spurious(hw_tf->tf_trapno))
+                       lapic_send_eoi(hw_tf->tf_trapno);
+               goto out_no_eoi;
+       }
+       if (irq_h->check_spurious(hw_tf->tf_trapno))
                goto out_no_eoi;
        /* Can now be interrupted/nested by higher priority IRQs, but not by our
         * current IRQ vector, til we EOI. */
index e80f321..bbda959 100644 (file)
@@ -310,6 +310,10 @@ void __sched_scp_wakeup(struct proc *p)
        if (!management_core()) {
                /* TODO: pick a better core and only send if halted.
                 *
+                * FYI, a POKE on x86 might lose a rare race with halt code, since the
+                * poke handler does not abort halts.  if this happens, the next timer
+                * IRQ would wake up the core.
+                *
                 * ideally, we'd know if a specific mgmt core is sleeping and wake it
                 * up.  o/w, we could interrupt an already-running mgmt core that won't
                 * get to our new proc anytime soon.  also, by poking core 0, a