|
|
  |
MSI-X Interrupt |
|
|
|
Nov 17 2015, 19:25
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Приветствую. В системе используется ядро AXI Bridge for PCIe. Пытаюсь использовать MSI-X прерывания. Ядро в стандартной конфигурации поддерживает два MSI-X прерывания. В драйвере Linux Kernel используется функция pci_enable_msix_range(pdev, msixentries, 1, 2), которая разрешает два прерывания. lspci -vv для устройства показывает следующее: CODE 01:00.0 Multimedia controller: Xilinx Corporation Device 7024 Subsystem: Xilinx Corporation Device 0007 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx+ Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 16 Region 0: Memory at f7e20000 (64-bit, non-prefetchable) [size=4K] Region 2: Memory at f7e00000 (64-bit, non-prefetchable) [size=128K] Capabilities: [80] Power Management version 3 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME- Capabilities: [b0] MSI-X: Enable+ Count=2 Masked- Vector table: BAR=0 offset=00000200 PBA: BAR=0 offset=00000280 Capabilities: [c0] Express (v2) Endpoint, MSI 00 DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ MaxPayload 256 bytes, MaxReadReq 512 bytes DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend- LnkCap: Port #0, Speed 5GT/s, Width x4, ASPM not supported, Exit Latency L0s unlimited, L1 unlimited ClockPM- Surprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- DevCap2: Completion Timeout: Range B, TimeoutDis+, LTR-, OBFF Not Supported DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis- Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS- Compliance De-emphasis: -6dB LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-, EqualizationPhase1- EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest- Capabilities: [100 v2] Advanced Error Reporting UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol- UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol- UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol- CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn- Kernel driver in use: htg_v7_g3
В драйвере реализованы два обработчика прерывания, которые вешаются на выделенные pci_enable_msix_range() MSI-X вектора. После инициализации драйвера заполняется таблица векторов MSI-X (Рисунок 1). Реализовано два BAR-a: BAR0 - таблица векторов MSI-X, BAR2 - регистры устройств. Ядро AXI Bridge for PCIe имеет интерфейс cfg_interrupt_msix (Рисунок 2), к нему подключается MSI-X Interrupt controller. На MSI-X Interrupt controller заводится сигнал от PIO (пока, тестовый режим), по высокому уровню от PIO MSI-X Interrupt controller генерит прерывание MSI-X (Рисунок 3), но система на него никак не реагирует (обработчик не срабатывает). Что тут сделано неправильно? Кто должен выставлять биты PBA, указывающие, какой вектор сработал?
Эскизы прикрепленных изображений
 Уменьшено до 88%
1444 x 914 (221.83 килобайт)
|
 Уменьшено до 88%
1345 x 781 (114.53 килобайт)
|
 Уменьшено до 90%
1731 x 819 (48.81 килобайт)
|
|
|
|
|
|
Nov 17 2015, 20:52
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(krux @ Nov 17 2015, 23:00)  MSI и MSI-X - это пакеты. они должны быть сформированы вашим кодом в плис, и отправлены в axi slave pcie-корки. Вот это я и пытаюсь сделать, но у ядра PCIe есть интерфейс cfg_interrupt_msix, который, как понимаю, и предназначен для этих целей. Сделал, как описано в доке (третий рисунок выше), но оно не сгенерило MSI-X. Вот эту штуку (рисунок) из pg023_v7_pcie_gen3.pdf пытаюсь реализовать, должно сгенерировать MSI-X прерывание.
Эскизы прикрепленных изображений
 Уменьшено до 84%
1076 x 496 (110.97 килобайт)
|
|
|
|
|
|
Nov 20 2015, 08:43
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Приветствую. На рисунке представлена работа MSI-X контроллера прерываний. Пока всё работает в тестовом режиме, прерывание срабатывает от порта GPIO. Портом PIO управляет MicroBlaze. Использую подряд две функции Код XGpio_DiscreteWrite(&gpio_1, 1, 1); XGpio_DiscreteWrite(&gpio_1, 1, 0); Как видно из рисунка, пока MicroBlaze меняет данные порта GPIO1, контроллер MSI-X прерываний успевает сгенерировать 8 прерываний. Ядро AXI Bridge for PCIe выставляет сигнал cfg_interrupt_msix_sent, что означает (я так понял) разрешено отправлять следующее прерывание. При этом обработчик прерывания в Linux Kernel срабатывает 2-3 раза (а не 8!!!). Получается cfg_interrupt_msix_sent - это сигнал от ядра PCIe, что прерывание отправлено, но он не даёт гарантии, что оно обработано системой. Вопрос, как разрулить эту ситуацию? Как определить, что ядро Linux обработало прерывание и когда можно генерировать следующее? Пока добавляю в контроллер MSI-X прерываний детектор фронта прерывания, чтоб исключить ситуацию многократной отправки MSI-X на одно прерывание от одного источника. Но это не решает проблему, когда ядро ответило сигналом cfg_interrupt_msix_sent, что можно отправлять следующее (допустим, пришло прерыване от другого источника), а система ещё не обработала первое.
Эскизы прикрепленных изображений
 Уменьшено до 91%
1816 x 990 (71.57 килобайт)
|
|
|
|
|
|
Nov 20 2015, 20:50
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(krux @ Nov 20 2015, 22:48)  sent - это действительно подтверждение отправки. т.е. если нужно отправить прерывание, то int поднимается и удерживается до тех пор пока не поднимется sent. Пока так и сделал, работает, но не соответствует тому, как описано в доке Xilinx (рисунок из доки выше). Пробовал сделать, как в мануале, длительность int один такт - работать не захотело, хочу ещё проверить дительность int 2-3 такта. Цитата(krux @ Nov 20 2015, 22:48)  что касается обмена пользовательскими данными и прерываниями между device и host - то стандарта на эту тему нет. каждый строчит кто как хочет. если вам нужно гарантированная обработка каждого прерывания ядром linux - то вы должны предусмотреть и определить этот механизм сами, как вам будет удобнее. или производительнее. или ещё по каким причинам. Конечно хочу, чтоб обработчик прерывания в ядре срабатывал на каждое отправляемое девайсом MSI-X, но не понимаю, как это реализуется. MSI-X Capability Structure содержит указатели на MSI-X Table Structure и MSI-X PBA (Pending Bit Array) Structure. С MSI-X Table Structure вроде как всё понятно, а вот как используется и для чего необходима MSI-X PBA Structure? Посмотрел пример реализации PCIe DMA для Virtex 7 с opencores.org (там как раз используются MSI-X), но в примере для контроллера прерываний даже сигнал sent не используется, отправили и забыли
|
|
|
|
|
Nov 21 2015, 07:51
|
Профессионал
    
Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596

|
Цитата(doom13 @ Nov 20 2015, 23:50)  Конечно хочу, чтоб обработчик прерывания в ядре срабатывал на каждое отправляемое девайсом MSI-X, но не понимаю, как это реализуется. MSI-X Capability Structure содержит указатели на MSI-X Table Structure и MSI-X PBA (Pending Bit Array) Structure. С MSI-X Table Structure вроде как всё понятно, а вот как используется и для чего необходима MSI-X PBA Structure? ключевое слово Pending - ожидающие. т.е. вы отправляя 8 прерываний на каждом из них записываете с PBA очередной бит. софт, получив всего 2-3 прерывания, определяет сколько же на самом деле событий произошло, читая PBA и сбрасывая биты, соответствующие обработанным данным. если данных, которые нужно перегнать у вас очень много, и прерывания у вас идут буквально одно за другим, то стоит рассмотреть вариант NAPI - т.е. прерывания используются, но не для передачи данных, а для перезарядки указателей. При этом софт работает в Polling-режиме, т.е. принудительно каждые N-мсек опрашивает устройство, а данные затем сливаются SGDMA с большим списком указателей но всего одним прерыванием. При этом софт не тратит время на постоянное переключение контекста для обработки большого количества мелких прерываний.
--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|