Date: Fri, 24 Aug 2001 10:39:12 -0700 (PDT) From: Warner Losh <imp@FreeBSD.org> To: cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org Subject: cvs commit: src/sys/i386/isa intr_machdep.c Message-ID: <200108241739.f7OHdDe84220@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
imp 2001/08/24 10:39:12 PDT
Modified files: (Branch: RELENG_4)
sys/i386/isa intr_machdep.c
Log:
Fix some spl masking issue. From the patch author:
> 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.
Submitted by: Ian Dowse
Revision Changes Path
1.29.2.3 +2 -8 src/sys/i386/isa/intr_machdep.c
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200108241739.f7OHdDe84220>
