From 5a19a59b738add4603b74d1ac5a067b8e6fef59b Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 21 Jul 2011 15:14:21 +0100 Subject: [PATCH] --- yaml --- r: 258203 b: refs/heads/master c: 78359cb86b8c4c8946f6732eac2757fa5e1d4de4 h: refs/heads/master i: 258201: d4eee4b304ddbf59fdb9eab44c736403d83538d9 258199: e0550d3ec5f14a9f46af833cacd868936184045d v: v3 --- [refs] | 2 +- trunk/arch/arm/kernel/irq.c | 39 ++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/[refs] b/[refs] index 08f7526f975d..c64e9cc14000 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ca15af19ac07908c8ca386f6d944a18aa343b868 +refs/heads/master: 78359cb86b8c4c8946f6732eac2757fa5e1d4de4 diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index ab63c05290e5..0f928a131af8 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -131,46 +131,63 @@ int __init arch_probe_nr_irqs(void) #ifdef CONFIG_HOTPLUG_CPU -static bool migrate_one_irq(struct irq_data *d) +static bool migrate_one_irq(struct irq_desc *desc) { + struct irq_data *d = irq_desc_get_irq_data(desc); const struct cpumask *affinity = d->affinity; + struct irq_chip *c; bool ret = false; + /* + * If this is a per-CPU interrupt, or the affinity does not + * include this CPU, then we have nothing to do. + */ + if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) + return false; + if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { - affinity cpu_online_mask; + affinity = cpu_online_mask; ret = true; } - d->chip->irq_set_affinity(d, affinity, true); + c = irq_data_get_irq_chip(d); + if (c->irq_set_affinity) + c->irq_set_affinity(d, affinity, true); + else + pr_debug("IRQ%u: unable to set affinity\n", d->irq); return ret; } /* - * The CPU has been marked offline. Migrate IRQs off this CPU. If - * the affinity settings do not allow other CPUs, force them onto any + * The current CPU has been marked offline. Migrate IRQs off this CPU. + * If the affinity settings do not allow other CPUs, force them onto any * available CPU. + * + * Note: we must iterate over all IRQs, whether they have an attached + * action structure or not, as we need to get chained interrupts too. */ void migrate_irqs(void) { - unsigned int i, cpu = smp_processor_id(); + unsigned int i; struct irq_desc *desc; unsigned long flags; local_irq_save(flags); for_each_irq_desc(i, desc) { - struct irq_data *d = &desc->irq_data; bool affinity_broken = false; + if (!desc) + continue; + raw_spin_lock(&desc->lock); - if (desc->action != NULL && - cpumask_test_cpu(smp_processor_id(), d->affinity)) - affinity_broken = migrate_one_irq(d); + affinity_broken = migrate_one_irq(desc); raw_spin_unlock(&desc->lock); if (affinity_broken && printk_ratelimit()) - pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu); + pr_warning("IRQ%u no longer affine to CPU%u\n", i, + smp_processor_id()); } local_irq_restore(flags);