Avoiding Common IRQ Racing on Linux

I consider the upcoming situation in an embedded Linux project (there is no hardware yet), where two external chips will need to share one physical IRQ line. This line is capable of edge triggering hardware, but is not caused by level interruptions.

Looking at the general irq support in Linux, I understand that the way this will work with two separate drivers is that each of them will have an interrupt handler, check their hardware and process it if necessary.

However, I assume the following state of the race and would like to know if I am missing something or what can be done to get around this. Let's say there are two external interrupt sources: devices A and B:

  • device B is interrupted, IRQ is active.
  • The IRQ edge triggers the Linux kernel interrupt handler.
  • ISR to start device A does not find a pending interrupt
  • Interruption occurs, IRQ remains active (wire-OR)
  • The ISR for device B is running, finds an interrupt pending, processes and clears it.
  • kernel interrupt handler
  • IRQ remains active, edges are no longer created, IRQ is blocked

It seems that for this fix, the kernel interrupt handler will need to check the IRQ level after all the handlers have started, and if it is still active, start them again. Will Linux do this? I don’t think the interrupt kernel knows how to check the level of the IRQ line.

Is this race something that can really happen, and if so, how can I deal with it?

+6
source share
1 answer

Basically, with the hardware you described, wiring - or for interrupts, will NEVER work correctly on it.

If you want to connect to a wired system, you really need to use level-sensitive IRQ inputs. If this is not possible, perhaps you can add interrupts to some controller. This device will receive N level-sensitive input and have one output as well as some β€œclear” output. When the interrupt controller is clean, it will lower its output, and then re-approve the output if any of its inputs were still validated.

On the software side, you can see if the IRQ string works on a different processor input. This will allow you to at least check the status, but the basic ISR processing for Linux is not going to know anything about it, and so you have to pay something to check it and run it again through the ISR. In addition, this means that in difficult interrupt loading situations you are NEVER going to get out of this ISR. Given that you are making a wire or in IRQ, I seem to assume that these devices will not interrupt too often.

One more thing - it’s very hard to look at the processor. There might be some trick you can pull with setting the interrupt to recognize the interrupt again.

I would not try anything too complicated, I would either separate the sources into separate IRQ inputs, switch to a level-sensitive input signal, or add an interrupt controller chip.

+2
source

Source: https://habr.com/ru/post/905688/


All Articles