Subject: Re: spl priority inversion in NetBSD/arm
To: Toru Nishimura <locore64@alkyltechnology.com>
From: Richard Earnshaw <rearnsha@netbsd.org>
List: port-arm
Date: 01/04/2005 17:27:05
On Tue, 2004-12-28 at 04:50, Toru Nishimura wrote:
> I found a plain obvious evidence that spl inversion can really
> happen. Due to the unknown reason some interrupt(s) is left
> blocked forever, in particular, softintr() is not re-activated. I start
> suspecting that serial->soft_serial or net->soft_net controlling
> path can go wild and wreck intr_enabled variable badly. There
> are two distinct softintr() implementations in NetBSD/arm. One
> is to use software initiated interrupt with the help of hardware.
> Another is genuine software construct to imiate hardware interrupt
> contexts. My case is the former and resulted in intr_enabled
> variable blocks softintr bit forever. So, People who are responsible
> any of evbarm ports, PLS take a look at your *intr.[ch] code. I know
> considerable amount of care has been done to make sure IRQ/IPL do
> the right things but it works wrong, sometimes. It would explain the
> case of Jesse Off experiences too.
I've seen cases where an interrupt can be entered more than once and on
the second entry appears to be already blocked. This can happen on
machines with a memory-mapped interrupt mask register. The code
basically writes to the register (in memory) and then immediately
re-enables interrupts (but before the new mask value has had chance to
take effect).
For example, on the integrator port the following was needed:
/*
* Disable all the interrupts that are pending. We will
* reenable them once they are processed and not masked.
*/
intr_enabled &= ~hwpend;
ifpga_set_intrmask();
/* Wait for these interrupts to be suppressed. */
while ((ifpga_iintsrc_read() & hwpend) != 0)
;
The final empty loop appears to be redundant, but in practice tends to
run for a small number of iterations while the hardware catches up.
R.