Почему прерывания MSI не передаются?
Может ли кто-нибудь сказать, почему прерывания MSI не делятся в Linux.
Прерывания на основе ПИН-кода могут совместно использоваться устройствами, но прерывания MSI не разделяются устройствами, каждое устройство получает свой собственный номер IRQ MSI. Почему нельзя прерывать MSI?
2 ответа
Старые прерывания INTx имеют два проблемных свойства:
- Каждый сигнал INTx требует отдельной аппаратной линии; а также
- сигнал прерывания не зависит от других сигналов данных, и он отправляется асинхронно.
Последствия таковы, что
- несколько устройств и драйверов должны иметь возможность обмениваться прерываниями (обработчик прерываний должен проверить, действительно ли его устройство вызвало прерывание); а также
- когда драйвер получает прерывание, ему необходимо выполнить чтение некоторого регистра устройства, чтобы убедиться, что все предыдущие записи DMA, сделанные устройством, видны в ЦП.
Как правило, оба случая обрабатываются драйвером, считывающим регистр состояния прерывания его устройства.
Прерывания с сигналом сообщения не требуют отдельной сигнальной линии, а отправляются в виде сообщения по шине данных. Это означает, что одно и то же оборудование может поддерживать много других прерываний (поэтому разделять его не нужно) и что сообщение о прерывании автоматически синхронизируется с любыми доступами DMA. Как следствие, обработчик прерываний не должен ничего делать; прерывание гарантированно исходит от его устройства, а данные DMA гарантированно уже поступили.
Если бы некоторые драйверы были написаны для совместного использования некоторого MSI, обработчик прерываний снова должен был бы проверить, действительно ли прерывание поступило от его собственного устройства, и не было бы никакого преимущества по сравнению с прерываниями INTx.
MSI не являются общими, потому что это невозможно, а потому, что в этом нет необходимости.
Обратите внимание, что совместное использование MSI действительно возможно: как видно в этом отрывке из /proc/interrupts
, расширенные отчеты об ошибках, события управления питанием и драйверы горячего подключения совместно используют одно прерывание:
64: 0 0 PCI-MSI-edge aerdrv, PCIe PME, pciehp
Эти драйверы фактически подключены к одному и тому же устройству, но они по-прежнему ведут себя подобно драйверам INTx, т. Е. Регистрируют свое прерывание с помощью IRQF_SHARED
и обработчики прерываний проверяют, была ли это их собственная функция, которая вызвала прерывание.
Совместное использование прерываний является хаком из-за нехватки ресурсов, например, из-за недостатка физических линий IRQ для каждого устройства, которое требует внимания. Если прерывания представлены сообщениями, которые имеют большое пространство идентификаторов, зачем вам это делать?
"Это" означает: присвоение им одинаковых идентификаторов, чтобы затем можно было проверять устройства, чтобы выяснить, какие из них, конфликтующие с одним и тем же идентификатором, фактически прервались.
На самом деле, мы иногда хотели бы иметь несколько прерываний для одного устройства. Например, полезно, если идентификатор прерывания сообщает нам не только о том, какое устройство прервано, но и почему: как это происходит из-за поступления ввода или из-за опустошения выходного буфера? Если линии прерывания "дешевы", потому что это просто программные идентификаторы с большим количеством битов, мы можем это иметь.