From 0d7fd5f2b8ede776a8a395c1fd0427139ffa3219 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 22 Jul 2019 11:44:50 +0200 Subject: [PATCH] x86/IRQ: target online CPUs when binding guest IRQ MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Roger Pau Monné Acked-by: Andrew Cooper --- xen/arch/x86/irq.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 10a83efc8e..732ddd4efd 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -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); -- 2.30.2