[Rtlinuxgpl] rtl_hard_enable_irq() and system hand/lockup

"Calin A. Culianu" <[email protected]> Mon, 26 Sep 2005 09:36:45 -0400 (EDT)
Newsgroups gmane.linux.real-time.rtlinux.general
Message-ID <[email protected]>
I noticed that most realtime drivers (specifically the comedi drivers) 
like to call rtl_hard_enable_irq() at the end of the interrupt handler 
function.  The RTLinux docs seems to indicate that this is The Right Thing 
To Do since "interrupts are disabled when your interrupt handler is 
invoked".

However what the docs don't say is that if you fail to call 
rtl_hard_enable_irq() it isn't the end of the world: your interrupt 
handler is still 'enabled' and will run again eventually after rtlinux 
returns from its own rtl_intercept() interrupt handler and re-enables 
interrupts globally...

Searching google and the mailing list indicates that a lot of other people 
have experienced system lockups after calling this function in situations 
where they are sharing the interrtupt number with non-realtime linux 
drivers.

So.. my quick question about hard realtime IRQs is:

rtl_hard_enable_irq() seems to turn on the irq right *now*.  That is.. it 
immediately talks to the interrupt controller on the motherboard and tells 
it "hey, turn on irq X".  Is the above correct?  (It appears to do that 
from my reading of the rtlinux sources.)

Anyway.. what precisely is the point of this?  Why not just return from 
the interrupt handler.. presumably the internal rtl_intercept() function 
will eventually re-enable all IRQs when it is done with its processing.

Is this so that any immediately fired IRQs preempt linux once again 
(since, Linux gets to run usually after all the hard realtime interrupt 
handlers)?

In my experience it seems that calling this function leads to a system 
lockup if the IRQ is being shared with non-realtime drivers in linux.  I 
am not an expert on driver-level programming (although I am learning) but 
could this be because the linux-driven hardware might be asserting an 
interrupt line and thus you get an infinite loop where:

1. Your rtl driver is called for interrupt 'I'
2. The interrupt wasn't really for your baord, so you do nothing, but at
    the end of your function you rtl_hard_enable_irq(I).
3. Immediately the interrupt controller is told that 'I' is enabled, which
    causes the rtl_intercept() interrupt handler to run again (it preempts
    itself!).
4. The rtl_intercept() handler sees your code wants IRQ 'I', so goto (1)
    above.. the infinite loop is created and the system hangs.

That seems to be the cause of my system lockups when sharing hard IRQs 
with non-realtime linux drivers.  At least that's my theory.

Is the above assessment of the situation correct or is my theory all wrong 
and are my system lockups probably caused by other causes?

-Calin
_______________________________________________
Rtl mailing list
[email protected]
http://hq.fsmlabs.com/mailman/listinfo/rtl
http:/www.rtlinux-gpl.org/