Subject: Re: common irq handler code
To: None <port-arm@netbsd.org>
From: Steve Woodford <scw@netbsd.org>
List: port-arm
Date: 04/10/2007 08:41:26
On Monday 09 April 2007 08:01, Toru Nishimura wrote:
> Chris Gilbert says;
>
> [ ... proposal to add "common irq code path" ... ]
>
> > So instead I've taken the footbridge irqhandler code, and made it a
> > common file. (The footbridge version was based on Jason's work for
> > xscale platforms)
>
> I agree with that providing "the common" is an better idea, but it
> should be emphasised that it has limitations which might be inadequate
> for some cases.

I'll echo that. While the common code may be useful during early bring-up 
of a new port, there is no substitute for an implementation targetted 
directly at the flavour of interrupt controller. This code is critical 
to good performance. In particular, the spl(9) implementation must be as 
small as possible. I have a few comments...

1. Consider the proposed arm_intr_splx() implementation. Right at the 
start there are a whole bunch of 'extern foo' declarations. Each one of 
those variables will generate, on ARM, a PC-relative load just to find 
the address of the variable. This is all inlined code, so even small 
functions like this contrived example:

{
 extern volatile int x;
 int s = splbio();
 x = 0;
 splx(s);
}

when compiled will be very much larger than you'd expect. Consider moving 
some state into cpu_info.

2. As you noted, the 'mask' approach whereby pending interrupts are 
recorded in a mask which mirrors the hardware's mask registers does not 
scale well with more than 32 individual interrupt sources. It also 
becomes extremely unwieldy in splx(9) where you'd have to logically AND 
multiple 32-bit values to determine if an interrupt is pending. Instead, 
on CPUs with an ffs(2)-like instruction ("clz" for example) you can use 
a single 32-bit variable to record pending interrupts per IPL_*. Then 
splx(9) can simply use "clz" to determine if it needs to invoke the 
'dispatch pending' heavy lifter. You also greatly reduce the number of 
external variable references in splx(9).

Using the above two suggestions in tandem, the spl(9) implementation will 
be much smaller, the code will scale to multiple hardware masks much 
more easily, and you may find some more opportunities to factor out 
common/shared code.

Cheers, Steve