genirq: Respect NUMA node affinity in setup_irq_irq affinity()
authorPrarit Bhargava <prarit@redhat.com>
Mon, 26 Mar 2012 19:02:18 +0000 (15:02 -0400)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 29 Mar 2012 09:31:53 +0000 (11:31 +0200)
We respect node affinity of devices already in the irq descriptor
allocation, but we ignore it for the initial interrupt affinity
setup, so the interrupt might be routed to a different node.

Restrict the default affinity mask to the node on which the irq
descriptor is allocated.

[ tglx: Massaged changelog ]

Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Link: http://lkml.kernel.org/r/1332788538-17425-1-git-send-email-prarit@redhat.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/irq/manage.c

index bf606a5..89a3ea8 100644 (file)
@@ -282,7 +282,7 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
 {
        struct irq_chip *chip = irq_desc_get_chip(desc);
        struct cpumask *set = irq_default_affinity;
-       int ret;
+       int ret, node = desc->irq_data.node;
 
        /* Excludes PER_CPU and NO_BALANCE interrupts */
        if (!irq_can_set_affinity(irq))
@@ -301,6 +301,13 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
        }
 
        cpumask_and(mask, cpu_online_mask, set);
+       if (node != NUMA_NO_NODE) {
+               const struct cpumask *nodemask = cpumask_of_node(node);
+
+               /* make sure at least one of the cpus in nodemask is online */
+               if (cpumask_intersects(mask, nodemask))
+                       cpumask_and(mask, mask, nodemask);
+       }
        ret = chip->irq_set_affinity(&desc->irq_data, mask, false);
        switch (ret) {
        case IRQ_SET_MASK_OK: