Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/irq: Call irq_force_move_complete with irq descriptor

First of all there is no point in looking up the irq descriptor again, but we
also need the descriptor for the final cleanup race fix in the next
patch. Make that change seperate. No functional difference.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Borislav Petkov <bp@alien8.de>
Tested-by: Joe Lawrence <joe.lawrence@stratus.com>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Jeremiah Mahler <jmmahler@gmail.com>
Cc: andy.shevchenko@gmail.com
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: stable@vger.kernel.org #4.3+
Link: http://lkml.kernel.org/r/20151231160107.125211743@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

+11 -7
+3 -2
arch/x86/include/asm/irq.h
··· 23 23 24 24 #define __ARCH_HAS_DO_SOFTIRQ 25 25 26 + struct irq_desc; 27 + 26 28 #ifdef CONFIG_HOTPLUG_CPU 27 29 #include <linux/cpumask.h> 28 30 extern int check_irq_vectors_for_cpu_disable(void); 29 31 extern void fixup_irqs(void); 30 - extern void irq_force_complete_move(int); 32 + extern void irq_force_complete_move(struct irq_desc *desc); 31 33 #endif 32 34 33 35 #ifdef CONFIG_HAVE_KVM ··· 39 37 extern void (*x86_platform_ipi_callback)(void); 40 38 extern void native_init_IRQ(void); 41 39 42 - struct irq_desc; 43 40 extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); 44 41 45 42 extern __visible unsigned int do_IRQ(struct pt_regs *regs);
+7 -4
arch/x86/kernel/apic/vector.c
··· 630 630 __irq_complete_move(cfg, ~get_irq_regs()->orig_ax); 631 631 } 632 632 633 - void irq_force_complete_move(int irq) 633 + /* 634 + * Called with @desc->lock held and interrupts disabled. 635 + */ 636 + void irq_force_complete_move(struct irq_desc *desc) 634 637 { 635 - struct irq_cfg *cfg = irq_cfg(irq); 636 - struct apic_chip_data *data; 638 + struct irq_data *irqdata = irq_desc_get_irq_data(desc); 639 + struct apic_chip_data *data = apic_chip_data(irqdata); 640 + struct irq_cfg *cfg = data ? &data->cfg : NULL; 637 641 638 642 if (!cfg) 639 643 return; ··· 651 647 * the way out. 652 648 */ 653 649 raw_spin_lock(&vector_lock); 654 - data = container_of(cfg, struct apic_chip_data, cfg); 655 650 cpumask_clear_cpu(smp_processor_id(), data->old_domain); 656 651 raw_spin_unlock(&vector_lock); 657 652 }
+1 -1
arch/x86/kernel/irq.c
··· 462 462 * non intr-remapping case, we can't wait till this interrupt 463 463 * arrives at this cpu before completing the irq move. 464 464 */ 465 - irq_force_complete_move(irq); 465 + irq_force_complete_move(desc); 466 466 467 467 if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { 468 468 break_affinity = 1;