Subject: Re: what blocks splserial?
To: Daniel Brewer <danielb@cat.co.za>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 08/19/2003 12:26:22
On Tue, Aug 19, 2003 at 09:51:30AM +0200, Daniel Brewer wrote:
> The PCI card itself gets a signal from the add-on card when an interrupt on
> the serial ports occur. The PCI card generates the pci interrupt when this
> is the case. The serial com driver should respond first, as that has an
> interrupt priority of IPL_SERIAL. The four serial ports on the add-on card
> are mapped onto com2-com5. The com driver will access the registers of the
> 16550 USART devices on the add-on card through the subregion of the PCI
> card's pci_mapreg_map space. The driver for the PCI card should respond to
> the interrupt after the com driver, as the PCI card driver's interrupt
> priority is IPL_TTY. Am I correct in this assumption? The PCI card driver
> will clear the interrupt. The PCI card can also do a whole lot of other
> stuff that isn't being used in the test.

Ok, so there is only one interrupt for all the stuffs the PCI card can
do, including the serial ports. From what I understand, this interrupt
routine is registered to the kernel with IPL_TTY, right ?

From what you describe, it's the pci driver for you card which then does the
interrupt dispatch to the various drivers attached to this driver.
If it is registered with IPL_TTY, then all things at or above IPL_TTY (which
includes IPL_AUDIO and IPL_CLOCK) will block it. Note that IPL_TTY is also
IPL_IMP (memory allocations), which I guess is the culprit here: memory
management can sometimes take a long time.

I guess the way to solve it is to register your interrupt at IPL_SERIAL
in the PCI driver. Then your PCI interrupt routine will then call the
com interrupt routine from here, but for the others interrupts source
of your PCI adapter you'll probably want to use a soft interrupt or a
kernel thread, to not do all the work at SPL_SERIAL.
> 
> Everything works great until something memory/disk intensive runs (like a
> compile of a large project). The man pages seem to suggest that only
> splhigh(), spllock() and splserial() would block the com driver's
> interrupts. I wouldn't have thought that such high level blocking would
> block for several milliseconds...? Say a lower priority interrupt triggers
> (say IPL_TTY) and an isr starts running to handle that, and while the isr is
> still busy, another interrupt of a higher priority (say IPL_SERIAL) occurs.
> My understanding is that it would break out of the lower priority isr and
> run the higher priority isr and then return to the lower isr. Is that
> correct?

It's correct, if you have different interrupts. In your case, it's the same
interrupt line (and so the same interrupt handler), so you have to register
it at IPL_SERIAL, and use either a soft interrupt or a kernel thread to
handle the interrupts that should not be handled at IPL_SERIAL.

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
     NetBSD: 24 ans d'experience feront toujours la difference
--