[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/