diff options
-rw-r--r-- | arch/x86/kernel/irq.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index b10a5e1da06c..8a82728d47c1 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -281,7 +281,7 @@ EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | |||
281 | /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ | 281 | /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ |
282 | void fixup_irqs(void) | 282 | void fixup_irqs(void) |
283 | { | 283 | { |
284 | unsigned int irq; | 284 | unsigned int irq, vector; |
285 | static int warned; | 285 | static int warned; |
286 | struct irq_desc *desc; | 286 | struct irq_desc *desc; |
287 | 287 | ||
@@ -336,9 +336,33 @@ void fixup_irqs(void) | |||
336 | printk("Cannot set affinity for irq %i\n", irq); | 336 | printk("Cannot set affinity for irq %i\n", irq); |
337 | } | 337 | } |
338 | 338 | ||
339 | /* That doesn't seem sufficient. Give it 1ms. */ | 339 | /* |
340 | local_irq_enable(); | 340 | * We can remove mdelay() and then send spuriuous interrupts to |
341 | * new cpu targets for all the irqs that were handled previously by | ||
342 | * this cpu. While it works, I have seen spurious interrupt messages | ||
343 | * (nothing wrong but still...). | ||
344 | * | ||
345 | * So for now, retain mdelay(1) and check the IRR and then send those | ||
346 | * interrupts to new targets as this cpu is already offlined... | ||
347 | */ | ||
341 | mdelay(1); | 348 | mdelay(1); |
342 | local_irq_disable(); | 349 | |
350 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { | ||
351 | unsigned int irr; | ||
352 | |||
353 | if (__get_cpu_var(vector_irq)[vector] < 0) | ||
354 | continue; | ||
355 | |||
356 | irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); | ||
357 | if (irr & (1 << (vector % 32))) { | ||
358 | irq = __get_cpu_var(vector_irq)[vector]; | ||
359 | |||
360 | desc = irq_to_desc(irq); | ||
361 | spin_lock(&desc->lock); | ||
362 | if (desc->chip->retrigger) | ||
363 | desc->chip->retrigger(irq); | ||
364 | spin_unlock(&desc->lock); | ||
365 | } | ||
366 | } | ||
343 | } | 367 | } |
344 | #endif | 368 | #endif |