From 3c419d3521b66c78e22da14fcf287b586e5df4b7 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 13 Dec 2011 11:38:57 +0100 Subject: VT-d: bind IRQs to CPUs local to the node the IOMMU is on This extends create_irq() to take a node parameter, allowing the resulting IRQ to have its destination set to a CPU on that node right away, which is more natural than having to post-adjust this (and get e.g. a new IRQ vector assigned despite a fresh one was just obtained). All other callers of create_irq() pass NUMA_NO_NODE for the time being. Signed-off-by: Jan Beulich Acked-by: Keir Fraser --- xen/arch/x86/irq.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'xen/arch/x86/irq.c') diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index b1c5d421f3..e75c06a3b6 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -151,7 +151,7 @@ int __init bind_irq_vector(int irq, int vector, const cpumask_t *cpu_mask) /* * Dynamic irq allocate and deallocation for MSI */ -int create_irq(void) +int create_irq(int node) { int irq, ret; struct irq_desc *desc; @@ -168,7 +168,17 @@ int create_irq(void) ret = init_one_irq_desc(desc); if (!ret) - ret = assign_irq_vector(irq); + { + cpumask_t *mask = NULL; + + if (node != NUMA_NO_NODE && node >= 0) + { + mask = &node_to_cpumask(node); + if (cpumask_empty(mask)) + mask = NULL; + } + ret = assign_irq_vector(irq, mask); + } if (ret < 0) { desc->arch.used = IRQ_UNUSED; @@ -514,7 +524,7 @@ next: return err; } -int assign_irq_vector(int irq) +int assign_irq_vector(int irq, const cpumask_t *mask) { int ret; unsigned long flags; @@ -523,7 +533,7 @@ int assign_irq_vector(int irq) BUG_ON(irq >= nr_irqs || irq <0); spin_lock_irqsave(&vector_lock, flags); - ret = __assign_irq_vector(irq, desc, TARGET_CPUS); + ret = __assign_irq_vector(irq, desc, mask ?: TARGET_CPUS); if (!ret) { ret = desc->arch.vector; cpumask_copy(desc->affinity, desc->arch.cpu_mask); -- cgit v1.2.3