]> xenbits.xensource.com Git - xen.git/commitdiff
x86/IRQ: target online CPUs when binding guest IRQ
authorJan Beulich <jbeulich@suse.com>
Mon, 22 Jul 2019 09:44:50 +0000 (11:44 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 22 Jul 2019 09:44:50 +0000 (11:44 +0200)
fixup_irqs() skips interrupts without action. Hence such interrupts can
retain affinity to just offline CPUs. With "noirqbalance" in effect,
pirq_guest_bind() so far would have left them alone, resulting in a non-
working interrupt.

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

index 10a83efc8e2ef1ee01f6a48ed6ffc5ca8065b8ee..732ddd4efdbc596d29bb5a3e17ffa9b31c329791 100644 (file)
@@ -1695,9 +1695,27 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 
         desc->status |= IRQ_GUEST;
 
-        /* Attempt to bind the interrupt target to the correct CPU. */
-        if ( !opt_noirqbalance && (desc->handler->set_affinity != NULL) )
-            desc->handler->set_affinity(desc, cpumask_of(v->processor));
+        /*
+         * Attempt to bind the interrupt target to the correct (or at least
+         * some online) CPU.
+         */
+        if ( desc->handler->set_affinity )
+        {
+            const cpumask_t *affinity = NULL;
+
+            if ( !opt_noirqbalance )
+                affinity = cpumask_of(v->processor);
+            else if ( !cpumask_intersects(desc->affinity, &cpu_online_map) )
+            {
+                cpumask_setall(desc->affinity);
+                affinity = &cpumask_all;
+            }
+            else if ( !cpumask_intersects(desc->arch.cpu_mask,
+                                          &cpu_online_map) )
+                affinity = desc->affinity;
+            if ( affinity )
+                desc->handler->set_affinity(desc, affinity);
+        }
 
         desc->status &= ~IRQ_DISABLED;
         desc->handler->startup(desc);