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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Ingo Molnar:
"A CPU hotplug related fix, plus two related sanity checks"

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs
genirq/cpuhotplug: Add sanity check for effective affinity mask
genirq: Warn when effective affinity is not updated

+45 -2
+1 -1
kernel/irq/chip.c
··· 265 265 irq_setup_affinity(desc); 266 266 break; 267 267 case IRQ_STARTUP_MANAGED: 268 + irq_do_set_affinity(d, aff, false); 268 269 ret = __irq_startup(desc); 269 - irq_set_affinity_locked(d, aff, false); 270 270 break; 271 271 case IRQ_STARTUP_ABORT: 272 272 return 0;
+27 -1
kernel/irq/cpuhotplug.c
··· 18 18 static inline bool irq_needs_fixup(struct irq_data *d) 19 19 { 20 20 const struct cpumask *m = irq_data_get_effective_affinity_mask(d); 21 + unsigned int cpu = smp_processor_id(); 21 22 22 - return cpumask_test_cpu(smp_processor_id(), m); 23 + #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK 24 + /* 25 + * The cpumask_empty() check is a workaround for interrupt chips, 26 + * which do not implement effective affinity, but the architecture has 27 + * enabled the config switch. Use the general affinity mask instead. 28 + */ 29 + if (cpumask_empty(m)) 30 + m = irq_data_get_affinity_mask(d); 31 + 32 + /* 33 + * Sanity check. If the mask is not empty when excluding the outgoing 34 + * CPU then it must contain at least one online CPU. The outgoing CPU 35 + * has been removed from the online mask already. 36 + */ 37 + if (cpumask_any_but(m, cpu) < nr_cpu_ids && 38 + cpumask_any_and(m, cpu_online_mask) >= nr_cpu_ids) { 39 + /* 40 + * If this happens then there was a missed IRQ fixup at some 41 + * point. Warn about it and enforce fixup. 42 + */ 43 + pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n", 44 + cpumask_pr_args(m), d->irq, cpu); 45 + return true; 46 + } 47 + #endif 48 + return cpumask_test_cpu(cpu, m); 23 49 } 24 50 25 51 static bool migrate_one_irq(struct irq_desc *desc)
+17
kernel/irq/manage.c
··· 168 168 set_bit(IRQTF_AFFINITY, &action->thread_flags); 169 169 } 170 170 171 + static void irq_validate_effective_affinity(struct irq_data *data) 172 + { 173 + #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK 174 + const struct cpumask *m = irq_data_get_effective_affinity_mask(data); 175 + struct irq_chip *chip = irq_data_get_irq_chip(data); 176 + 177 + if (!cpumask_empty(m)) 178 + return; 179 + pr_warn_once("irq_chip %s did not update eff. affinity mask of irq %u\n", 180 + chip->name, data->irq); 181 + #endif 182 + } 183 + 171 184 int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, 172 185 bool force) 173 186 { ··· 188 175 struct irq_chip *chip = irq_data_get_irq_chip(data); 189 176 int ret; 190 177 178 + if (!chip || !chip->irq_set_affinity) 179 + return -EINVAL; 180 + 191 181 ret = chip->irq_set_affinity(data, mask, force); 192 182 switch (ret) { 193 183 case IRQ_SET_MASK_OK: 194 184 case IRQ_SET_MASK_OK_DONE: 195 185 cpumask_copy(desc->irq_common_data.affinity, mask); 196 186 case IRQ_SET_MASK_OK_NOCOPY: 187 + irq_validate_effective_affinity(data); 197 188 irq_set_thread_affinity(desc); 198 189 ret = 0; 199 190 }