]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/irq/manage.c
genirq: Always force thread affinity
[karo-tx-linux.git] / kernel / irq / manage.c
index 1cbd572f6ad8d474ccf4859a4f9a7b677773a2ea..35c70c9e24d8f2ec6011800217e3bcd1880d6ca6 100644 (file)
@@ -732,6 +732,7 @@ static void
 irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
 {
        cpumask_var_t mask;
+       bool valid = true;
 
        if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags))
                return;
@@ -746,10 +747,18 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
        }
 
        raw_spin_lock_irq(&desc->lock);
-       cpumask_copy(mask, desc->irq_data.affinity);
+       /*
+        * This code is triggered unconditionally. Check the affinity
+        * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
+        */
+       if (desc->irq_data.affinity)
+               cpumask_copy(mask, desc->irq_data.affinity);
+       else
+               valid = false;
        raw_spin_unlock_irq(&desc->lock);
 
-       set_cpus_allowed_ptr(current, mask);
+       if (valid)
+               set_cpus_allowed_ptr(current, mask);
        free_cpumask_var(mask);
 }
 #else
@@ -954,6 +963,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                 */
                get_task_struct(t);
                new->thread = t;
+               /*
+                * Tell the thread to set its affinity. This is
+                * important for shared interrupt handlers as we do
+                * not invoke setup_affinity() for the secondary
+                * handlers as everything is already set up. Even for
+                * interrupts marked with IRQF_NO_BALANCE this is
+                * correct as we want the thread to move to the cpu(s)
+                * on which the requesting code placed the interrupt.
+                */
+               set_bit(IRQTF_AFFINITY, &new->thread_flags);
        }
 
        if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {