Messages in this thread Patch in this message | | | Date | Sun, 26 Apr 1998 21:10:43 +0100 (WEST) | From | "Manuel J. Galan" <> | Subject | Re: 2.1.98 floppy lock up cured !! |
| |
-----BEGIN PGP SIGNED MESSAGE-----
On 26-Apr-98 Andy Higgins wrote: > > Somehow I missed that IO APIC patch for 2.1.98 could someone please repost > or re-email it. Thanks. >
here it goes... - ----------------------------------------------- On Sun, 26 Apr 1998, David Woodhouse wrote: > > Results with gcc-2.7.2.3 and a clean 2.1.98+irq.c were fairly weird. > > -------------------------- > > First attempt: Optimistically going into runlevel 5, and stupidly forgetting > to add "mem=64M" on the command line to avoid the uncached RAM. > > Lots of "eth0: Re-entering the interrupt handler" followed by > "Ugh at c0111acc" just after attempting to start xntpd, and then nothing more. > Hard lock. > > -------------------------- > > Second attempt: Try again in runlevel 2, which I thought didn't do NTP > > Again lots of whinging from eth0. Followed by an oops: > > (Yes, it says CPU 18. It's not a typo. Last time it said CPU 66513.)
Ok, looks like the stack got overwritten with crap. I know what's going on. You're getting recursive IO-APIC interrupts, because your interrupt handler enables interrupts again, and I should have been aware of this. Silly of me. It doesn't happen for everybody, because it requires a driver that enables interrupts to happen, so this also explains why it works for some people but not others.
Anyway, that does mean that we have to protect ourselves against nesting, and that in turn means we have to have some kind of way of not losing interrupts.
How about this version? The patch is against a clean 2.1.98, so you have to revert my previous patch, and I haven't tested it yet because all my machines I could test on are busy. It looks good, and has a similar kind of logic to it as the original io-apic stuff, but is simpler and doesn't imply a counter any more. In short, it _looks_ good, but caveat emptor.
Linus
- ----- - --- v2.1.98/linux/arch/i386/kernel/irq.c Sat Apr 25 18:13:10 1998 +++ linux/arch/i386/kernel/irq.c Sun Apr 26 11:21:46 1998 @@ -673,16 +673,6 @@ set_8259A_irq_mask(irq); } - -#ifdef __SMP__ - -static void disable_ioapic_irq(unsigned int irq) - -{ - - disabled_irq[irq] = 1; - - /* - - * We do not disable IO-APIC irqs in hardware ... - - */ - -} - -#endif - - void enable_8259A_irq (unsigned int irq) { unsigned long flags; @@ -693,30 +683,50 @@ } #ifdef __SMP__ + +/* + * In the SMP+IOAPIC case it might happen that there are an unspecified + * number of pending IRQ events unhandled. These cases are very rare, + * so we 'resend' these IRQs via IPIs, to the same CPU. It's much + * better to do it this way as thus we dont have to be aware of + * 'pending' interrupts in the IRQ path, except at this point. + * + * This code appears still badly broken on some machines, and is thus + * disabled. + */ +static inline void trigger_pending_irqs(unsigned int irq) +{ +#if 0 + if (irq_events[irq]) { + if (!ipi_pending[irq]) { + ipi_pending[irq] = 1; + irq_events[irq] = 0; + send_IPI(smp_processor_id(), IO_APIC_VECTOR(irq)); + } + } +#endif +} + void enable_ioapic_irq (unsigned int irq) { - - unsigned long flags, should_handle_irq; - - int cpu = smp_processor_id(); + unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); disabled_irq[irq] = 0; + trigger_pending_irqs(irq); + + spin_unlock_irqrestore(&irq_controller_lock, flags); +} + +static void disable_ioapic_irq(unsigned int irq) +{ + disabled_irq[irq] = 1; /* - - * In the SMP+IOAPIC case it might happen that there are an unspecified - - * number of pending IRQ events unhandled. These cases are very rare, - - * so we 'resend' these IRQs via IPIs, to the same CPU. It's much - - * better to do it this way as thus we dont have to be aware of - - * 'pending' interrupts in the IRQ path, except at this point. + * We do not disable IO-APIC irqs in hardware ... */ - - if (irq_events[irq]) { - - if (!ipi_pending[irq]) { - - ipi_pending[irq] = 1; - - --irq_events[irq]; - - send_IPI(cpu,IO_APIC_VECTOR(irq)); - - } - - } - - spin_unlock_irqrestore(&irq_controller_lock, flags); } + #endif void enable_irq(unsigned int irq) @@ -773,32 +783,38 @@ #ifdef __SMP__ static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs) { - - int should_handle_irq = 0; - - ack_APIC_irq(); spin_lock(&irq_controller_lock); - - if (ipi_pending[irq]) - - ipi_pending[irq] = 0; + ipi_pending[irq] = 0; - - if (!irq_events[irq]++ && !disabled_irq[irq]) - - should_handle_irq = 1; + /* If the irq is disabled, just set a flag and return */ + if (disabled_irq[irq]) { + irq_events[irq] = 1; + spin_unlock(&irq_controller_lock); + return; + } + + disabled_irq[irq] = 1; + irq_events[irq] = 0; hardirq_enter(cpu); spin_unlock(&irq_controller_lock); - - if (should_handle_irq) { - - while (test_bit(0,&global_irq_lock)) mb(); - -again: + while (test_bit(0,&global_irq_lock)) barrier(); + + for (;;) { + int pending; + handle_IRQ_event(irq, regs); spin_lock(&irq_controller_lock); - - should_handle_irq=0; - - if (--irq_events[irq] && !disabled_irq[irq]) - - should_handle_irq=1; + pending = irq_events[irq]; + irq_events[irq] = 0; + disabled_irq[irq] = pending; spin_unlock(&irq_controller_lock); - - if (should_handle_irq) - - goto again; + if (!pending) + break; } hardirq_exit(cpu);
- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu - ----------------------------------------------- - -- Manuel J. Galan manolow@step.es
-----BEGIN PGP SIGNATURE----- Version: PGPfreeware 5.0i for non-commercial use Comment: Using RSA Key Charset: noconv iQEVAwUBNUOUwWD+APAfXUYjAQG0uggAv57lZvAVnxNI7EGTcxuC02wrMKmis5XI x0JjLEsbxjlu6X92612MDEk9dx0iMAhYxHEoAaR/QBfjBlVfs0fe+U5mVOGO1wZp DQB1vWsqxTgA0z2puCm3DGHnbqCEMyxVa96CHHw1Bv1VG/EmqVMDmjrH3zf36aQP LHiae5Zw/aD3Z76Xr5bcxTAerKQUVtRRRa/uVEHdUUV6bah0nvYFX1LZeJGZ4BFE dtx/nwX+WziyJF1nqzNoT18wL/cvhWDxwrnOqdREI87Y6ywKcLUatFi5Zoj/25aU vEdqECI1blsdSDT0uErhiQ36m0n2aj2pTRZP5BmENAdjV0ymKkeJ+w== =IsYx -----END PGP SIGNATURE----- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |