problem about share interrupt

My A/D card and net card uses the same interrupt on pci bus,I found one
problem,sometimes my A/D card can’t respond the interrupt because the net card mask the interrupt, the result is losting data,how to solve it,please help me,thank you very much!

The PIC’s masking is handled by the OS so don’t touch it. Both your ISR and the network cards ISR gets called when either card pulls the interrupt. That’s the way shared interrupts work.

When this happens, on each occurance, your ISR has to decide if your card needs updated. Ie: Check the pending register on the A/D card.

But sometimes the net card mask the interrupt,if at that time my A/D card pull the interrupt,my ISR
can’t respond,I have make one test,if I slay io-net programme,my programme is ok.

That’s not a proof by itself.

You are going to have to give more detail of what your code is doing and what the hardware is.

What makes you thing the network driver (hardware by itself can’t disable interrupt) is making the interrupt. If it would for some reason disable the interrupt, it would do it for a very short period of time. If your hardware set the IRQ while it’s makes once unmaks your ISR will get called ( because PCI interrupt are level). If the network card is masking the interrupt for long period of time then it’s a bug.

the interrupt delay time of my A/D card is 10ms,sometimes my interrupt thread lost 2-3 dots(20-30ms),I think the losting time is too long to accept,Do you think it is the bug of network driver?
My ISR do the work as follow,

if (id==my A/D card id)
{
read A/D card register;
if (my card interrupt)
{
clear A/D card register;
return (&event); //active my interrupt thread
}
}
return NULL;

Two things:

I have no idea what good the ID is inside the ISR, so start by ignoring that.

I suggest you track the number of times your ISR sends an event and the number of events the thread identifies. Bags there is a difference.

I have set one varies named “tt” in the ISR,every time it received interrupt,tt++,every second it should be 100(the interrupt delay time of my card is 10ms),I print it in my interrupt from GPS signal
interrupt on int second.
1)I unload network driver,tt is 100.
2)tt is not 100 when network driver works.

How many? It should be more than 100, particularly while there is network activity.

less than 100,97 or 98

That doesn’t make sense, it can’t be, we are missing some piece of information. See, if a network driver would be disabling interrupt for more then 10ms I really doubt you’d be the first one to notice. Hence I tend to trust the network driver doing the goog thing. The problem must lies somewhere else.

Are both cards ISA or PCI?

pci card

I guess the network driver disable my interrupt sometimes,the masking time is not 10ms,10ms is my interrupt delay time,maybe just before my card send interrupt the network disable it,Is it possible?

Nope, I can’t quote PCI specifically, but another feature of shared interrupts is the device holds the interrupt line untill acknowledged. AKA Level triggering.

So, your card shouldn’t let go untill you clear the pending bit.

If the interrupt line is still held after all ISR’s have been called and when the kernel unmasks the interrupt another interrupt will immediately be generated, this results in extra interrupts and possible 100% cpu usage.

Hello,
I have seen the same problem with a special hardware timer sharing the interrupt with the speedo driver. The driver has no direct interrupt handling but use interrupt attach event. The os mask the interrupt level and send a signal to the driver process. The driver unmask interrupt level after processing the interrupt. I have seen the interrupt masked until 30 ms. If your card, sharing this interrupt, send interrupt every 10 ms and has no fifo or interrupt counter you lost few interrupt in this case.

Ouch!, you are absolutely right.

Quote from the function InterruptAttachEvent(),
“To prevent infinite interrupt recursion, the kernel automatically does
an InterruptMask() for intr when delivering the event. After the
interrupt-handling thread has dealt with the event, it must call
InterruptUnmask() to reenable the interrupt.”

So, unless the network thread makes a point of quickly unmasking then you are in the poo. :frowning:

I wonder if this is common to all network drivers?

Hum I didn’t though of that ;-| That means an IRQ is actually lower priority then the thread handling the event in case of interrupt attach event.

Once you share an interrupt you can never be assured deterministic behavior.

I don’t see it that way.

It’s exactly like using InterruptDisable(). The same rules apply. Cooperation of all the ISR’s is required. You are lucky there is more than one IRQ.

And since timeliness is one of QNX’s motos, I fully expect that view of shared interrupts to change.

Don’t get me wrong, InterruptAttachEvent() is correct, the IRQ has to be masked to allow clearing of a level triggered IRQ. In this case, the problem is very much with the network drivers leaving the unmasking until after all network traffic is completed.

evanh: it’s even worst it’s not really how long the ISR is unmask. Let’s say thread handling interrupt event is at priority 30, but a process is eating up the CPU 100% at priority 40. Basicaly the IRQ will stay masked untel the process releases the CPU. Although this is documented to some degree, personnaly starting today I will avoid using InterruptAttachedEvent.

Who’s rules is that. QSS’s ? I think the rules is IRQ have higher priority then any threads or processes. InterruptAttachEvent breaks that rules.