реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> MSI-X Interrupt
doom13
сообщение Nov 17 2015, 19:25
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 303
Регистрация: 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, указывающие, какой вектор сработал?
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
krux
сообщение Nov 17 2015, 20:00
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 565
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596



MSI и MSI-X - это пакеты. они должны быть сформированы вашим кодом в плис, и отправлены в axi slave pcie-корки.
Go to the top of the page
 
+Quote Post
doom13
сообщение Nov 17 2015, 20:52
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 303
Регистрация: 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 прерывание.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
doom13
сообщение Nov 18 2015, 11:51
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 303
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Ошибка в том, что IP Integrator генерит ядро AXI Bridge for PCIe с ошибкой (Vivado 2015.2). Данная корка строится на основе ядра Gen3 Integrated Block for PCIe, для которого порт cfg_interrupt_msix_int никуда не подключен. Если есть необходимость пересобрать систему, приходится вручную править файлы ядра AXI Bridge for PCIe sad.gif

В версии 2015.3 баг остался.
Go to the top of the page
 
+Quote Post
doom13
сообщение Nov 20 2015, 08:43
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 303
Регистрация: 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, что можно отправлять следующее (допустим, пришло прерыване от другого источника), а система ещё не обработала первое.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
krux
сообщение Nov 20 2015, 19:48
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 565
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596



sent - это действительно подтверждение отправки.
т.е. если нужно отправить прерывание, то int поднимается и удерживается до тех пор пока не поднимется sent.
абсолютно идентично как для транзакции широко всеми используемого ready-valid интерфейса.

что касается обмена пользовательскими данными и прерываниями между device и host - то стандарта на эту тему нет.
каждый строчит кто как хочет.
если вам нужно гарантированная обработка каждого прерывания ядром linux - то вы должны предусмотреть и определить этот механизм сами, как вам будет удобнее. или производительнее. или ещё по каким причинам.
Go to the top of the page
 
+Quote Post
doom13
сообщение Nov 20 2015, 20:50
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 303
Регистрация: 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 не используется, отправили и забыли sad.gif
Go to the top of the page
 
+Quote Post
krux
сообщение Nov 21 2015, 07:51
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 565
Регистрация: 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 с большим списком указателей но всего одним прерыванием. При этом софт не тратит время на постоянное переключение контекста для обработки большого количества мелких прерываний.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th September 2017 - 19:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01434 секунд с 7
ELECTRONIX ©2004-2016