Re: QUESTION: Network hangs with BP6 and 2.4.x kernels, hardware

Manfred Spraul
2001-01-13T00:06:56Z

Alan Cox wrote:
>
> > Could you disable both bandaids? I disabled them, no problems so far.
> > Now back to the disable_irq_nosync().
>
> Ok so it looks like the disable_irq code is buggy. Unfortunately its not
> just used for these drivers they are just the heaviest users.
>
> Given that we can see the IRQ is still set on the APIC can we fake an IRQ in
> that condition ?

Switch to edge triggered, wait , switch back to level triggered - I've
added that to my sysrq commands, and it clears the IRR bit in the IO
APIC. Sometimes 2 or 3 attempts are required.

I tried several changes to the ioapic code, but without success.

I found:
* the io_apic_sync() in __mask_IO_APIC_irq() is probably wrong, I'd say
it should be _after_ the io_apic_modify, but currently it is before the
io_apic_modify(). 2.2 uses the same code, that doesn't explain the
problem.

* this comment in
http://oss.sgi.com/www.linux.sgi.com/intel/visws/visws.2210.28jul99.patch

+/* XXX ouch... is this really our only choice for masking this
interrupt? */
+/* XXX not fully safe for 2 reasons:
+ * 1) should not touch an apic entry while (whole) apic is enabled
+ * 2) careful about storing to IRR bit (unless we know this intr is
idle)
+ */
+static void disable_cobalt_irq(unsigned int irq) /* disable_irq()
*/
+{
+ int ent = is_co_apic(irq);
+ if (ent == -1) {
+ return; /* could actually be a panic */
+ }
+
+ /* Note: h/w nada like read-mod-write! Vec saved in
IRQ_VECTOR() */
+ co_apic_write(CO_APIC_LO(ent), CO_APIC_MASK);
+ (void)co_apic_read(CO_APIC_LO(ent)); /* sync cpu to cobalt apic
*/
+}
+
It's possible that the comment is about an cobalt specific problem, the
IRR bit is - according the Intel documentation - read only.

--
Manfred