]> xenbits.xensource.com Git - xen.git/commitdiff
x86/IRQ: bail early from irq_guest_eoi_timer_fn() when nothing is in flight
authorJan Beulich <jbeulich@suse.com>
Thu, 6 Jun 2019 14:04:53 +0000 (16:04 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 6 Jun 2019 14:04:53 +0000 (16:04 +0200)
There's no point entering the loop in the function in this case. Instead
there still being something in flight _after_ the loop would be an
actual problem: No timer would be running anymore for issuing the EOI
eventually, and hence this IRQ (and possibly lower priority ones) would
be blocked, perhaps indefinitely.

Issue a warning instead and prefer breaking some (presumably
misbehaving) guest over stalling perhaps the entire system.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/irq.c

index 335c8ffb67a902bc1e641655fdfe740041cd67cb..be486a6ce46d5baebd449b10b377873f0db6225c 100644 (file)
@@ -1118,10 +1118,10 @@ static void irq_guest_eoi_timer_fn(void *data)
     action = (irq_guest_action_t *)desc->action;
 
     /*
-     * Is another instance of this timer already running? Skip everything
-     * to avoid forcing an EOI early.
+     * Is no IRQ in flight at all, or another instance of this timer already
+     * running? Skip everything to avoid forcing an EOI early.
      */
-    if ( timer_is_active(&action->eoi_timer) )
+    if ( !action->in_flight || timer_is_active(&action->eoi_timer) )
         goto out;
 
     if ( action->ack_type != ACKTYPE_NONE )
@@ -1136,8 +1136,13 @@ static void irq_guest_eoi_timer_fn(void *data)
         }
     }
 
-    if ( action->in_flight != 0 )
-        goto out;
+    if ( action->in_flight )
+    {
+        printk(XENLOG_G_WARNING
+               "IRQ%u: %d/%d handler(s) still in flight at forced EOI\n",
+               irq, action->in_flight, action->nr_guests);
+        ASSERT_UNREACHABLE();
+    }
 
     switch ( action->ack_type )
     {