From: Andi Kleen Suggested by Ingo Molnar. Drop APIC level workaround for old IO-APICs on x86-64 because it is a significant part of interrupt handling time. x86-64 only runs on modern chipsets that probably don't have this bug. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/arch/x86_64/kernel/io_apic.c | 62 ----------------------------------- 1 files changed, 62 deletions(-) diff -puN arch/x86_64/kernel/io_apic.c~drop-old-apic-workaround-on-x86-64 arch/x86_64/kernel/io_apic.c --- 25/arch/x86_64/kernel/io_apic.c~drop-old-apic-workaround-on-x86-64 Tue Oct 5 14:13:13 2004 +++ 25-akpm/arch/x86_64/kernel/io_apic.c Tue Oct 5 14:13:13 2004 @@ -41,10 +41,6 @@ int sis_apic_bug; /* not actually supported, dummy for compile */ -#undef APIC_LOCKUP_DEBUG - -#define APIC_LOCKUP_DEBUG - static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED; /* @@ -131,10 +127,6 @@ DO_ACTION( __mask, 0, |= 0x0 /* mask = 1 */ DO_ACTION( __unmask, 0, &= 0xfffeffff, ) /* mask = 0 */ -DO_ACTION( __mask_and_edge, 0, = (reg & 0xffff7fff) | 0x00010000, ) - /* mask = 1, trigger = 0 */ -DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, ) - /* mask = 0, trigger = 1 */ static void mask_IO_APIC_irq (unsigned int irq) { @@ -1343,61 +1335,7 @@ static unsigned int startup_level_ioapic static void end_level_ioapic_irq (unsigned int irq) { - unsigned long v; - int i; - -/* - * It appears there is an erratum which affects at least version 0x11 - * of I/O APIC (that's the 82093AA and cores integrated into various - * chipsets). Under certain conditions a level-triggered interrupt is - * erroneously delivered as edge-triggered one but the respective IRR - * bit gets set nevertheless. As a result the I/O unit expects an EOI - * message but it will never arrive and further interrupts are blocked - * from the source. The exact reason is so far unknown, but the - * phenomenon was observed when two consecutive interrupt requests - * from a given source get delivered to the same CPU and the source is - * temporarily disabled in between. - * - * A workaround is to simulate an EOI message manually. We achieve it - * by setting the trigger mode to edge and then to level when the edge - * trigger mode gets detected in the TMR of a local APIC for a - * level-triggered interrupt. We mask the source for the time of the - * operation to prevent an edge-triggered interrupt escaping meanwhile. - * The idea is from Manfred Spraul. --macro - */ - i = IO_APIC_VECTOR(irq); - v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); - ack_APIC_irq(); - - if (!(v & (1 << (i & 0x1f)))) { -#ifdef APIC_LOCKUP_DEBUG - struct irq_pin_list *entry; -#endif - -#ifdef APIC_MISMATCH_DEBUG - atomic_inc(&irq_mis_count); -#endif - spin_lock(&ioapic_lock); - __mask_and_edge_IO_APIC_irq(irq); -#ifdef APIC_LOCKUP_DEBUG - for (entry = irq_2_pin + irq;;) { - unsigned int reg; - - if (entry->pin == -1) - break; - reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2); - if (reg & 0x00004000) - printk(KERN_CRIT "Aieee!!! Remote IRR" - " still set after unlock!\n"); - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } -#endif - __unmask_and_level_IO_APIC_irq(irq); - spin_unlock(&ioapic_lock); - } } static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) _