genirq: Respect NUMA node affinity in setup_irq_irq affinity()
[platform/adaptation/renesas_rcar/renesas_kernel.git] / kernel / irq / manage.c
index b0ccd1a..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:
@@ -645,7 +652,7 @@ static int irq_wait_for_interrupt(struct irqaction *action)
  * is marked MASKED.
  */
 static void irq_finalize_oneshot(struct irq_desc *desc,
-                                struct irqaction *action, bool force)
+                                struct irqaction *action)
 {
        if (!(desc->istate & IRQS_ONESHOT))
                return;
@@ -679,7 +686,7 @@ again:
         * we would clear the threads_oneshot bit of this thread which
         * was just set.
         */
-       if (!force && test_bit(IRQTF_RUNTHREAD, &action->thread_flags))
+       if (test_bit(IRQTF_RUNTHREAD, &action->thread_flags))
                goto out_unlock;
 
        desc->threads_oneshot &= ~action->thread_mask;
@@ -739,7 +746,7 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
 
        local_bh_disable();
        ret = action->thread_fn(action->irq, action->dev_id);
-       irq_finalize_oneshot(desc, action, false);
+       irq_finalize_oneshot(desc, action);
        local_bh_enable();
        return ret;
 }
@@ -755,7 +762,7 @@ static irqreturn_t irq_thread_fn(struct irq_desc *desc,
        irqreturn_t ret;
 
        ret = action->thread_fn(action->irq, action->dev_id);
-       irq_finalize_oneshot(desc, action, false);
+       irq_finalize_oneshot(desc, action);
        return ret;
 }
 
@@ -844,7 +851,7 @@ void exit_irq_thread(void)
                wake_threads_waitq(desc);
 
        /* Prevent a stale desc->threads_oneshot */
-       irq_finalize_oneshot(desc, action, true);
+       irq_finalize_oneshot(desc, action);
 }
 
 static void irq_setup_forced_threading(struct irqaction *new)