Dmitry Adamushko wrote:
> > irq K | ----------- | ---o | // Linux only
> > ...
> > irq L | ---o | | // RT-only
> > ...
> > irq M | ---o------- | ---o | // Shared between domains
> > ...
> > irq N | ---o---o--- | | // Shared inside single domain
> > ...
> > irq O | ---o---o--- | ---o | // Shared between and inside
> > domain
> > Xenomai currently handles the K & L cases, Dmitrys patch addresses
> > case, with edge triggered interrupts the M (and O after Dmitry's patch)
> > case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE
> As you pointed out recently, using this combo for M (and thus O)
might also be
> unsafe, e.g. causing some implementation to send eoi twice or more
(and the second
> time while hw IRQs are off and the second IRQ is still pending) if
more than a
> single domain ends the current interrupt. This said, I've never tried
> actually, but this does seem a bit optimistic to always expect a
> in this case (basically, it all depends on what "ending" the
interrupt means hw-wise).
Just to be sure I've got the things more or less clear. I feel there are
some holes in my understanding of the irq handling stuff, mainly hw-wise.
x86 + i8259A.
In this case, .end handler does nothing more than enabling the IRQ line.
The "eoi" is sent in .ack right after disabling the IRQ line.
Let's suppose we have the "M" case ("O" makes no difference here).
When the ISR handler in Linux domain gets control :
- the IRQ line is ON (it was already .end-ed in the primary domain in case
of XN_ISR_ENABLE | XN_ISR_CHAINED ).
Actually, it's possible to set IPIPE_PASS flag for
when THIS_IRQ is shared across domains. This way, there is no need
to call propagate_irq() in xnintr_irq_handler(). Ok, it's not
that important so far.
This is not how it happens when the IRQ is only handled in the
Linux domain. But the ISR is still serialized (need not to be
reentrant) because do_IRQ() takes care of it (by means
of RUNNING and PENDING flags).
So, I suppose, it's possible to use XN_ISR_ENABLE | XN_ISR_CHAINED in that
In case of a pure Linux :
SMP : I/O APIC + local APICs. As I know, enabling/disabling
the IRQ line occurs (normally?) on per-local APIC basis. This said, when
the ISR is running on CPU_0 with the IRQ line disabled, nothing prevents
(probably, if the IRQ also was .ack-ed by that time?) the same IRQ from
being signaled on another CPU (even on a few).
In that case, it gets marked as PENDING and do_IRQ() on CPU_0 will run
handler_IRQ_events() - ISR handlers - once more.
Since PENDING is only a flag (not a counter), the fact that the IRQ was
is not lost but Linux can't know how much time it was signaled.
I guess, it's not true for devices that e.g. do not rise a new interrupt
the ISR handler does some special acknowledgement device-wise.
am I right?
Yes. Additionally, the uncertainty about the last issue is one of the reasons why
Adeos keeps a count of pending IRQs, and not just a flag; the other being that we
do want virtual interrupts to be counted and not just marked so that the software
can rely on this.