aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/io_apic.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2009-12-01 18:31:15 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-02 04:11:00 -0500
commitca64c47cecd0321b2e0dcbd7aaff44b68ce20654 (patch)
tree74db4a6a204648e5f2d4887dbac195c3dab60da0 /arch/x86/kernel/apic/io_apic.c
parent918bc960dc630b1a79c0d2991a81985812ff69f5 (diff)
x86, io-apic: Move the effort of clearing remoteIRR explicitly before migrating the irq
When the level-triggered interrupt is seen as an edge interrupt, we try to clear the remoteIRR explicitly (using either an io-apic eoi register when present or through the idea of changing trigger mode of the io-apic RTE to edge and then back to level). But this explicit try also needs to happen before we try to migrate the irq. Otherwise irq migration attempt will fail anyhow, as it postpones the irq migration to a later attempt when it sees the remoteIRR in the io-apic RTE still set. Signed-off-by: "Maciej W. Rozycki" <macro@linux-mips.org> Reviewed-by: Suresh Siddha <suresh.b.siddha@intel.com> Cc: ebiederm@xmission.com Cc: garyhade@us.ibm.com LKML-Reference: <20091201233334.975416130@sbs-t61.sc.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r--arch/x86/kernel/apic/io_apic.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 085e60e303cf..b377b973899e 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2583,6 +2583,20 @@ static void ack_apic_level(unsigned int irq)
2583 */ 2583 */
2584 ack_APIC_irq(); 2584 ack_APIC_irq();
2585 2585
2586 /* Tail end of version 0x11 I/O APIC bug workaround */
2587 if (!(v & (1 << (i & 0x1f)))) {
2588 atomic_inc(&irq_mis_count);
2589
2590 if (use_eoi_reg)
2591 eoi_ioapic_irq(desc);
2592 else {
2593 spin_lock(&ioapic_lock);
2594 __mask_and_edge_IO_APIC_irq(cfg);
2595 __unmask_and_level_IO_APIC_irq(cfg);
2596 spin_unlock(&ioapic_lock);
2597 }
2598 }
2599
2586 /* Now we can move and renable the irq */ 2600 /* Now we can move and renable the irq */
2587 if (unlikely(do_unmask_irq)) { 2601 if (unlikely(do_unmask_irq)) {
2588 /* Only migrate the irq if the ack has been received. 2602 /* Only migrate the irq if the ack has been received.
@@ -2616,20 +2630,6 @@ static void ack_apic_level(unsigned int irq)
2616 move_masked_irq(irq); 2630 move_masked_irq(irq);
2617 unmask_IO_APIC_irq_desc(desc); 2631 unmask_IO_APIC_irq_desc(desc);
2618 } 2632 }
2619
2620 /* Tail end of version 0x11 I/O APIC bug workaround */
2621 if (!(v & (1 << (i & 0x1f)))) {
2622 atomic_inc(&irq_mis_count);
2623
2624 if (use_eoi_reg)
2625 eoi_ioapic_irq(desc);
2626 else {
2627 spin_lock(&ioapic_lock);
2628 __mask_and_edge_IO_APIC_irq(cfg);
2629 __unmask_and_level_IO_APIC_irq(cfg);
2630 spin_unlock(&ioapic_lock);
2631 }
2632 }
2633} 2633}
2634 2634
2635#ifdef CONFIG_INTR_REMAP 2635#ifdef CONFIG_INTR_REMAP