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

x86/vsmp: Ignore IOAPIC IRQ affinity if possible

vSMP can route interrupts more optimally based on internal
knowledge the OS does not have. In order to support this
optimization, all CPUs must be able to handle all possible
IOAPIC interrupts.

Fix this by setting the vector allocation domain for all CPUs
and by enabling this feature in vSMP.

Signed-off-by: Ravikiran Thirumalai <kiran.thirumalai@gmail.com>
Signed-off-by: Shai Fultheim <shai@scalemp.com>
[ Rebased, simplified, and reworded the commit message. ]
Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Ravikiran Thirumalai and committed by
Ingo Molnar
110c1e1f 7db971b2

+23 -4
+23 -4
arch/x86/kernel/vsmp_64.c
··· 16 16 #include <linux/pci_ids.h> 17 17 #include <linux/pci_regs.h> 18 18 #include <linux/smp.h> 19 + #include <linux/irq.h> 19 20 20 21 #include <asm/apic.h> 21 22 #include <asm/pci-direct.h> ··· 96 95 ctl = readl(address + 4); 97 96 printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n", 98 97 cap, ctl); 98 + 99 + /* If possible, let the vSMP foundation route the interrupt optimally */ 100 + #ifdef CONFIG_SMP 101 + if (cap & ctl & BIT(8)) { 102 + ctl &= ~BIT(8); 103 + no_irq_affinity = 1; 104 + } 105 + #endif 106 + 99 107 if (cap & ctl & (1 << 4)) { 100 108 /* Setup irq ops and turn on vSMP IRQ fastpath handling */ 101 109 pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); ··· 112 102 pv_irq_ops.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); 113 103 pv_irq_ops.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); 114 104 pv_init_ops.patch = vsmp_patch; 115 - 116 105 ctl &= ~(1 << 4); 117 - writel(ctl, address + 4); 118 - ctl = readl(address + 4); 119 - printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl); 120 106 } 107 + writel(ctl, address + 4); 108 + ctl = readl(address + 4); 109 + pr_info("vSMP CTL: control set to:0x%08x\n", ctl); 121 110 122 111 early_iounmap(address, 8); 123 112 } ··· 201 192 return hard_smp_processor_id() >> index_msb; 202 193 } 203 194 195 + /* 196 + * In vSMP, all cpus should be capable of handling interrupts, regardless of 197 + * the APIC used. 198 + */ 199 + static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask) 200 + { 201 + cpumask_setall(retmask); 202 + } 203 + 204 204 static void vsmp_apic_post_init(void) 205 205 { 206 206 /* need to update phys_pkg_id */ 207 207 apic->phys_pkg_id = apicid_phys_pkg_id; 208 + apic->vector_allocation_domain = fill_vector_allocation_domain; 208 209 } 209 210 210 211 void __init vsmp_init(void)