On Mon, Dec 10, 2001, David A. Gatwood <dgatwood@gatwood.net> wrote:
On Mon, 10 Dec 2001, Benjamin Herrenschmidt wrote:
While looking at the Heathrow.cpp code to compare with what I'm doing
in Linux (chasing a lost interrupt problem with the PMU that occurs
occasionally), I found something weird in the Darwin implementation.
Hey, Ben. At least it only occurs occasionally for you. In MkLinux, it's
relatively easy to trigger. :-|
Well, it didn't happen until some additional changes I did to our interrupt management :(
My gut is telling me that continuing to trigger interrupts until the
status register is read could generate spurious interrupts that would
cause performance problems. After all, clearing the interrupt bit happens
in the interrupt context, but reading the status bit probably happens in a
kernel thread. Just my gut.
Darwin does soft-disable, doesn't it ? Well, in linux we mask the interrupt on the controller when it is triggered and unmask it on exit from the handler. One of the changes I did recently to my code was for the main interrupt dispatch to loop until the lower layer (interrupt controller driver) didn't return any new interrupt to service. By doing so, I also removed the code to trigger a lost interrupt when re-enabling on the handler exit code path, since I know we well loop again reading for interrupts. I only trigger the lost interrupt when re-enabling an interrupt outside of this code path. Note that I still mark the interrupt as "lost" so it's properly caught by the new iteration, but I don't cause a new interrupt on the CPU (we use the DEC to trigger fake interrupts in this case).
Cough. Guess Darwin doesn't lose many interrupts or someone would have
noticed this. :-)
Heh, I hope so ;)
I don't seem to have the Heathrow driver handy, but looking at the GC
driver (which should be very similar, I hope), it's being &ed with
kTypeLevelMask, which is a 32 bit quantity. How could that be non-zero?
The Heathrow driver has 2 sets of registers, so interrupt vectors can range from 0 to 63. Code checking the type of interrupt by doing kTypeLevelMask & (1 & << vectorNumber) may lead to strange results if vectorNumber is > 31 (I'm not sure about what C standard says, but I know for sure many compilers loves to miscompile such a construct). Ben.