Как избежать гонки общих IRQ в Linux

Я рассматриваю предстоящую ситуацию во встраиваемом Linux-проекте (пока нет оборудования), когда два внешних чипа должны будут совместно использовать одну физическую линию IRQ. Эта линия способна на аппаратном уровне запускать фронты, но не по уровню инициируемые прерывания.

Глядя на поддержку разделяемого irq в Linux, я понимаю, что способ, которым это будет работать с двумя отдельными драйверами, состоит в том, что каждый будет вызывать свой обработчик прерывания, проверять свое оборудование и обрабатывать его, если это необходимо.

Однако я представьте себе следующее состояние гонки и хотел бы знать, упускаю ли я что-то или что можно сделать, чтобы решить эту проблему.Допустим, есть два внешних источника прерываний, устройства A и B:

  1. происходит прерывание устройства B, IRQ становится активным
  2. Граница IRQ вызывает выполнение обработчика прерывания ядра Linux
  3. ISR для устройства A работает, не находит ожидающих прерываний
  4. устройство A прерывание происходит, IRQ остается активным (Wire-OR)
  5. ISR для устройства B запускается, находит ожидающее прерывание, обрабатывает и очищает его
  6. основной обработчик прерывания выходит
  7. IRQ остается активным, ребер больше нет генерируются, IRQ заблокирован

Похоже, что для устранения этой проблемы основной обработчик прерываний должен будет проверить уровень IRQ после запуска всех обработчиков, и, если он все еще активен, запустить их все снова. Будет ли Linux это делать? Я не думаю, что ядро ​​прерывания знает, как проверить уровень линии IRQ.

Может ли эта гонка произойти на самом деле, и если да, то как мне с этим справиться?

6
задан blueshift 11 January 2012 в 07:01
поделиться