Re: 2.1.98 floppy lock up cured !!

Manuel J. Galan (manolow@step.es)
Sun, 26 Apr 1998 21:10:43 +0100 (WEST)


-----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