Date: Thu, 23 Aug 2001 20:57:58 -0500 From: Stephen Montgomery-Smith <stephen@math.missouri.edu> To: stable@freebsd.org Subject: Re: Serious i386 interrupt mask bug in RELENG_4 (was Re: 4.4-RC NFS panic) Message-ID: <3B85B4A6.AFA7A19E@math.missouri.edu> References: <200108232134.aa49928@salmon.maths.tcd.ie>
next in thread | previous in thread | raw e-mail | index | archive | help
This patch certainly fixed all of my problems with the computer
freezing, etc, etc. Thanks.
(Posting it to STABLE because a lot of people there are also complaining
about this problem. Look at the bottom of the email for the patch.)
Ian Dowse wrote:
>
> In message <200108230228.f7N2SqW80434@harmony.village.org>, Warner Losh writes:
> >
> >I think that might be due to a bug in the shared interrupt code that
> >Ian Dowse sent me about earlier today.
>
> Just to add a few details - there is a bug in the update_masks()
> function in i386/isa/intr_machdep.c that can cause some interrupts
> to occur at times when they should be masked. The problem only
> occurs with certain configurations of shared interrupts and devices,
> and this code is only present in RELENG_4.
>
> The update_masks() function is called after an interrupt handler
> has been registered or removed. Its main function is to update the
> interrupt masks (tty_imask, net_imask etc) if necessary (e.g if
> IRQ11 is registered by a tty-type device, IRQ11 will be added to
> tty_imask so that future spltty()'s will mask IRQ11).
>
> A second function of update_masks() is to update the cached copy
> of the interrupt mask stored with each handler for a multiplexed
> interrupt. This is done via the call to update_mux_masks().
>
> The bug is that update_masks() returns without calling update_mux_masks()
> in some cases where it should call it. Specifically, if a newly-added
> multiplexed interrupt handler has the same maskptr as another
> handler on the same IRQ line, that new handler doesn't get it's
> cached mask set. For example if a single IRQ has a usb device and
> a modem (tty), the second device to register it's handler will get
> its idesc->mask set to 0 instead of the value of tty_imask because
> update_mux_masks() may never be called to set it. Of course, if
> update_masks() is called later for some other device it may correct
> the situation.
>
> Interrupt handlers are called with intr_mask[irq] or'd into the
> cpl to block further interrupts; for non-multiplexed interrupts
> intr_mask[irq] will set from one of the *_imask masks. However with
> multiplexed interrupts, only the IRQ itself (and SWI_CLOCK_MASK)
> are blocked, and the multiplex handler intr_mux() needs to raise
> the cpl further when necessary. It uses idesc->mask to control
> this.
>
> When this bug occurs, idesc->mask == 0, so the device interrupt
> handler gets called with only the IRQ and SWI_CLOCK_MASK masked,
> instead of the full *_mask that it requested. Not good.
>
> On my laptop, this bug causes hangs within minutes of starting to
> use a pccard modem, but as should be apparent from the above it
> could strike virtually anywhere that multiplexed interrupts are
> used. The patch below seems to solve the problem; it just causes
> update_masks() to unconditionally update the masks.
>
> Ian
>
> Index: intr_machdep.c
> ===================================================================
> RCS file: /home/iedowse/CVS/src/sys/i386/isa/intr_machdep.c,v
> retrieving revision 1.29.2.2
> diff -u -r1.29.2.2 intr_machdep.c
> --- intr_machdep.c 2000/08/16 05:35:34 1.29.2.2
> +++ intr_machdep.c 2001/08/23 20:24:17
> @@ -651,15 +651,9 @@
>
> if (find_idesc(maskptr, irq) == NULL) {
> /* no reference to this maskptr was found in this irq's chain */
> - if ((*maskptr & mask) == 0)
> - return;
> - /* the irq was included in the classes mask, remove it */
> *maskptr &= ~mask;
> } else {
> /* a reference to this maskptr was found in this irq's chain */
> - if ((*maskptr & mask) != 0)
> - return;
> - /* put the irq into the classes mask */
> *maskptr |= mask;
> }
> /* we need to update all values in the intr_mask[irq] array */
>
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-hackers" in the body of the message
--
Stephen Montgomery-Smith
stephen@math.missouri.edu
http://www.math.missouri.edu/~stephen
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3B85B4A6.AFA7A19E>
