Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Буфер для PCI Express
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
doom13
Приветствую.
Собираю систему для передачи данных от 10G Ethernet по PCIe в ПК (см. рисунок).
Приёмник MAC-уровня для 10G Ethernet пока моделирую Traffic Generator-ом. Прерывание от S2MM FIFO заводится в ПК и обрабатывается драйвером.
Использовал DC FIFO (для перехода между clock domains, Ethernet тактируется 156.25 МГц, PCIe - 250 МГц) и S2MM FIFO (для преобразования AXI4-Stream в AXI4).
S2MM FIFO генерирует прерывание либо по достижению определённого уровня заполнения, либо по приёму очередного пакета данных.
Traffic Generator управляется MicroBlaze (пока, для отладки) и может генерировать пакет 1024*64bit в цикле или постоянно.
Если использую прерывание по заполнению уровня (1024 позиции фифо), то приходится ставить большую задержку между запусками Traffic Generator-а, чтобы
CDMA успевал выгребать данные до накопления новых 1024 позиций, иначе передача фифо забивается и прерывание больше не срабатывает.
Тогда попробовал использовать прерывание по приёму пакета и забирать максимальное число данных кратное 1024 позициям фифо.
Тут Traffic Generator может работать в непрерывном режиме (CDMA постоянно забирает данные), но есть ощущение, что при заполнении фифо Traffic Generator может некоторое
время ожидать следующей передачи.
Вопросы:
1) Правильно ли реализую сам буфер, возможно есть более удобное решение?
2) Как выбрать размер FIFO и размер разовой передачи CDMA с учётом разных скоростей работы FIFO на запись/чтение и времени, требуемого для обработки прерывания и запуска CDMA драйвером?
krux
тупое S2MM fifo вам на 10G не поможет. скорости не те.
посмотрите хотя бы как сделана интеловская сетевушка:
http://www.intel.com/content/dam/www/publi...r-datasheet.pdf
там и идеология алгоритма для драйвера есть.
doom13
Цитата(krux @ Sep 2 2015, 09:07) *
посмотрите хотя бы как сделана интеловская сетевушка:
http://www.intel.com/content/dam/www/publi...r-datasheet.pdf
там и идеология алгоритма для драйвера есть.

Спасибо, посмотрю.

Цитата(krux @ Sep 2 2015, 09:07) *
тупое S2MM fifo вам на 10G не поможет. скорости не те.

А что не так с FIFO? Генератор данных заполняет его на 156.25 МГц, CDMA забирает данные на 250 МГц, шина данных 64 бита на запись/чтение. Основную проблему вижу в затратах времени на обработку прерывания длайвером и перезапуск CDMA (использую Simple DMA mode для CDMA, возможно, лучше применить Scatter Gather mode).

krux
Цитата
А что не так с FIFO?

формально, с FIFO всё нормально =)
прерывание-то от него сформируется как положено, однако перезарядка отработавшего DMA со стороны проца - процесс недетерминированный.
поэтому к тому моменту как проц презарядит DMA, у вас во входном буфере подропается приличное количество пакетов, а если не отслеживать старт-стопы пакетов, то будет ещё нарезка кусков пакетов.
doom13
Цитата(krux @ Sep 2 2015, 11:52) *
формально, с FIFO всё нормально =)
прерывание-то от него сформируется как положено, однако перезарядка отработавшего DMA со стороны проца - процесс недетерминированный.

Вот в этом и вижу основную проблему, нельзя ли отыграть это за счёт вместимости FIFO, вычитка данных происходит со скоростью на 60 % больше чем запись? Возможно тут понадобится очень большой буфер, но как это просчитать? Думал ещё сделать ping pong memory-buffer, но получу то же, что и с ФИФО, за счёт непредсказуемости прерывания отыграться если и можно, то только за счёт размера буфера.

Цитата(krux @ Sep 2 2015, 11:52) *
поэтому к тому моменту как проц презарядит DMA, у вас во входном буфере подропается приличное количество пакетов, а если не отслеживать старт-стопы пакетов, то будет ещё нарезка кусков пакетов.

Тут получается, что на AXI4-Stream приёмник тормозит передатчик. Данные не портятся, просто происходит остановка передачи Traffic Generator-ом.

PS.
Мануал на Intel 82599 10 GbE Controller просмотрел, но вот информации по реализации FIFO не нашёл, там больше о буферизации на уровне драйвера.
krux
Цитата
Мануал на Intel 82599 10 GbE Controller просмотрел, но вот информации по реализации FIFO не нашёл,

если коротко, то там используются:
1) 512 кбайт буферного озу
2) SGDMA
3) DMA для чтения таблиц дескрипторов
4) 16 записей для указателей (видных через BAR)
5) 16 таблиц для дескрипторов для SGDMA

проц формирует в озу пк таблицы дескрипторов-указателей на буферы под хранение данных.
проц заполняет записи 4) -- слейвом (ака запись в target) -- самая медленная операция
после чего DMA 3) вычитывает из оперативки таблицы дескрипторов и складирует их себе в 5)
сетевка готова к приему.
по приему пакета SGDMA 2) берёт очередную запись из 5) и пишет данные из буфера 2) в озу пк по адресу, указанному в дескрипторе. посылает MSI.
при расходовании целых таблиц из 5) посылаются прерывания на пополнение таблицы дескрипторов.
проц снова формирует таблицу дескрипторов, пишет в 4) адрес где он эту табличку положил, и DMA 3) её вычитывает

Цитата
вычитка данных происходит со скоростью на 60 % больше чем запись

вы не можете контролировать процесс формирования готовности со стороны PCIe Root Complex, поэтому в любой момент DMA-передача по PCIe может застрять на очередном отправляемом куске TLB в 128 байт. соотношение максимальных пропускных способностей AXI и FIFO здесь погоды не делают.

Цитата
просто происходит остановка передачи Traffic Generator

в реальной жизни, в отличие от Traffic Generator-а остановить прилетающий поток невозможно.
doom13
Цитата(krux @ Sep 2 2015, 19:51) *
в реальной жизни, в отличие от Traffic Generator-а остановить прилетающий поток невозможно.

тут имелл ввиду, что поток генератора трафика тормозится сигналом ready от слейва AXI4-Stream.


Цитата(krux @ Sep 2 2015, 19:51) *
если коротко, то там используются:
1) 512 кбайт буферного озу
2) SGDMA
3) DMA для чтения таблиц дескрипторов
4) 16 записей для указателей (видных через BAR)
5) 16 таблиц для дескрипторов для SGDMA

проц формирует в озу пк таблицы дескрипторов-указателей на буферы под хранение данных.
проц заполняет записи 4) -- слейвом (ака запись в target) -- самая медленная операция
после чего DMA 3) вычитывает из оперативки таблицы дескрипторов и складирует их себе в 5)
сетевка готова к приему.
по приему пакета SGDMA 2) берёт очередную запись из 5) и пишет данные из буфера 2) в озу пк по адресу, указанному в дескрипторе. посылает MSI.
при расходовании целых таблиц из 5) посылаются прерывания на пополнение таблицы дескрипторов.
проц снова формирует таблицу дескрипторов, пишет в 4) адрес где он эту табличку положил, и DMA 3) её вычитывает

В доке Intel есть упоминание о Rx FIFO, в которое данные (пакет) поступают после прохождения фильтра. Как понимаю, его я и пытаюсь реализовать. Всё остальное - это работа драйвера, который ваделяет буферы в ПК, перезапускает DMA. Тут я не совсем понимаю, как происходит передача данных без потери. Ведь на обработку прерывания и перезапуск DMA опять же требуется время и достаточно много. Даже если работает SgDMA, ему также нужно обновлять цепочку дескрипторов.


Что если вместо MM ядра CDMA попытаться использовать ядро DMA (v7.1) в режиме SgDMA S2MM и зациклить ему цепочку дескрипторов?
Т.е. выбрасываем из системы (см. рисунок) S2MM FIFO и CDMA, ставим DMA, и DMA будет принимать поток AXI4-Stream и сразу складывать в буферы в ПК выделяемые драйвером устройства. Потеря данных будет только если user space application не успевает вычитывать данные из буферов драйвера, т.е. если все буферы заполнены идёт перезапись. Подойдёт ли такой вариант?
krux
1 таблица дескрипторов - это 128 буферов, на 128 SGDMA операций.
таблиц 16.
т.е. в самом худшем случае, если перезарядок со стороны проца не будет некоторое время - SGDMA сможет запуститься 1024 раза, передав по 4 кбайта на каждом запуске.

Цитата
зациклить ему цепочку дескрипторов

зациклить - не советую, поскольку если проц не успеет их обработать - то DMA их может затереть записав следующие данные поверх.
doom13
Возник вопрос, в какой памяти должна размещаться таблица дескрипторов для DMA? Можно разместить в памяти FPGA, а можно - в памяти системы. Что посоветуете?
Спасибо.
RobFPGA
Приветствую!

Цитата(doom13 @ Sep 3 2015, 09:46) *
Что если вместо MM ядра CDMA попытаться использовать ядро Зачи(v7.1) в режиме SgDMA S2MM и зациклить ему цепочку дескрипторов?
Т.е. выбрасываем из системы (см. рисунок) S2MM FIFO и CDMA, ставим DMA, и DMA будет принимать поток AXI4-Stream и сразу складывать в буферы в ПК выделяемые драйвером устройства. Потеря данных будет только если user space application не успевает вычитывать данные из буферов драйвера, т.е. если все буферы заполнены идёт перезапись. Подойдёт ли такой вариант?


Для Ethernet это как раз более правильное решение чем CDMA. Проще структура пересылок данных. К тому же можно взять за основу его драйвер. Однако на входе DMA нужно FIFO для буферизации коротких затыков на PCIe шине.

Дескрипторы проще размещать в системной памяти. Опят же со стороны драйвера проще и быстрее их (дескрипторы ) обрабатывать.
Смотрите доки на DMA - как работать с кольцом дескрипторов. Там все продуманно - затирки данных не будет в худшем случае просто потеря новых данных.

Успехов! Rob.
doom13
Цитата(RobFPGA @ Sep 28 2015, 15:23) *
Для Ethernet это как раз более правильное решение чем CDMA. Проще структура пересылок данных. К тому же можно взять за основу его драйвер. Однако на входе DMA нужно FIFO для буферизации коротких затыков на PCIe шине.

Спасибо, долго тупил на этом вопросе, но вот уже начал разбираться с работой DMA S2MM. А как рассчитать размер этого FIFO?
Цитата(RobFPGA @ Sep 28 2015, 15:23) *
Дескрипторы проще размещать в системной памяти. Опят же со стороны драйвера проще и быстрее их (дескрипторы ) обрабатывать.

А не возникнет ли тут проблем по доступу к дескрипторам со стороны DMA (ему-то проще получать доступ к памяти в FPGA), как найти тут "золотую середину"?
Цитата(RobFPGA @ Sep 28 2015, 15:23) *
Смотрите доки на DMA - как работать с кольцом дескрипторов. Там все продуманно - затирки данных не будет в худшем случае просто потеря новых данных.

Может быть посоветуете что-то конкретное? Спасибо.

Пока есть такие вот варианты c применением DMA S2MM, не знаю какой выбрать:
1) Создаём N таблиц по M дескрипторов. По завершению таблицы DMA генерирует прерывание. В прерывании драйвер перенастраивает DMA на следующую таблицу и перезапускает его. Далее система начинает обрабатывать данные соответствующие отработанной таблице дескрипторов. Тут вопрос с FIFO, на прерывание (перезапуск DMA) потратится какое-то время, а поток данных идёт и хотелось бы их сохранить.

2) Второй вариант - кольцо дескрипторов (если всё правильно понял). Создаём кольцо дескрипторов и запускаем DMA S2MM, при обработке дескриптора DMA генерит прерывание, а сам переходит к следующему дескриптору. По прерыванию система обрабатывает полученные данные и возвращает дескриптор в цепочку. Тут будет тормозить если система не успевает возвращать обработанные дескрипторы в цепочку. Т.е. получим, что система будет тормозить работу DMA, только каким образом - обрабатывать и возвращать в кольцо по одному дескриптору или обработает и вернёт все накопленные дескрипторы?

В приведённой выше доке на 10G карту используется несколько таблиц дескрипторов, но не понял для чего. Если софт обновляет (возвращает) дескрипторы в кольцо, то зачем нужна другая (16 шт., если правильно понял) таблица. Возможно, если DMA обрабатывает все дескрипторы из таблицы, чтобы софт долго не тормозил DMA, идёт прерывание и переключение на следующую таблицу?
RobFPGA
Приветствую!

Для начала почитайте LogiCORE IP AXI DMA v6.00.a Product Guide (pg021_axi_dma.pdf) В более новых доках отсутствуют понятные картинки про ring buffer. sad.gif

Я обычно ставлю FIFO как минимум на пару пакетов максимального размера. Конкретно это сильно зависит от конфигурации системы - соотношения средней полосы PCIe r к полосе траффика 10G, другой активности через этот же сегмент PCIe шины, и.т.д. и.т.п. Ну и также Ваших хотелок по допустимым потерям пакетов.

DMA в режиме SG "кеширует" в локальном FIFO 3 дескриптора, сглаживая latecy при чтении дескрипторов. Однако это может быть недостаточно если предполагается трафик с большим количеством малых пакетов и при этом еще и желательно разбивка этих пакетов на отдельные буфера в системной памяти В этом случае можно дескрипторы располагать и в памяти FPGA . Но при этом существенно усложняется драйвер (для гарантированного получения пиковых характеристик).
Есть еще куча промежуточных вариантов, но это уже все экзотика - Опят же тут надо четко представлять себе требования к системе в целом.

Вариант N2 - Вы можете и миллион дескрипторов закольцевать - лишь бы памяти хватило - настроить iterrupt coalesing в DMA и потом не спеша перебирать эти "четки" выискивая в пришедших горах мусо... ..данных крупицы истины. Но опят же ничто не даром под луной - latecy обработки пакетов в этом случае будет большой.

Сложная структура дескрипторов в сетевых картах позволяет разгрузить софт от рутинных дел - например разгребать траффик от разных источников и переслать напрямую его на выделенный проц. в многопроцессорных системах, приоритеты пересылки для разного типа пакетов, и кучу других приятных плюшек. Никто не мешает Вам сделать все тоже самое если нужно и даже больше - главное тут понять - а оно нам нужно? wacko.gif

Начните с малого/простого - запустите 10G Ethernet sm.gif

Успехов! Rob.
doom13
Цитата(RobFPGA @ Sep 28 2015, 17:23) *
Для начала почитайте LogiCORE IP AXI DMA v6.00.a Product Guide (pg021_axi_dma.pdf) В более новых доках отсутствуют понятные картинки про ring buffer. sad.gif

Спасибо, смотрю, есть картинки, которых у меня не было.

Цитата(RobFPGA @ Sep 28 2015, 17:23) *
Я обычно ставлю FIFO как минимум на пару пакетов максимального размера. Конкретно это сильно зависит от конфигурации системы - соотношения средней полосы PCIe r к полосе траффика 10G, другой активности через этот же сегмент PCIe шины, и.т.д. и.т.п. Ну и также Ваших хотелок по допустимым потерям пакетов.

DMA в режиме SG "кеширует" в локальном FIFO 3 дескриптора, сглаживая latecy при чтении дескрипторов. Однако это может быть недостаточно если предполагается трафик с большим количеством малых пакетов и при этом еще и желательно разбивка этих пакетов на отдельные буфера в системной памяти В этом случае можно дескрипторы располагать и в памяти FPGA . Но при этом существенно усложняется драйвер (для гарантированного получения пиковых характеристик).
Есть еще куча промежуточных вариантов, но это уже все экзотика - Опят же тут надо четко представлять себе требования к системе в целом.

Вариант N2 - Вы можете и миллион дескрипторов закольцевать - лишь бы памяти хватило - настроить iterrupt coalesing в DMA и потом не спеша перебирать эти "четки" выискивая в пришедших горах мусо... ..данных крупицы истины. Но опят же ничто не даром под луной - latecy обработки пакетов в этом случае будет большой.


Система будет состоять из приёма 10G Ethernet трафика и передачи его по PCIe в ПК. По 10G Ethernet принимается непрерывный поток данных от плат АЦП. Соединение "точка-точка" - мусор отсутствует, только полезные данные.

Цитата(RobFPGA @ Sep 28 2015, 17:23) *
Начните с малого/простого - запустите 10G Ethernet sm.gif

Это уже готово (возможно, понадобится усложнить систему, но данные с платы на плату погонял).
RobFPGA
Приветствую!

Цитата(doom13 @ Sep 28 2015, 18:07) *
Система будет состоять из приёма 10G Ethernet трафика и передачи его по PCIe в ПК. По 10G Ethernet принимается непрерывный поток данных от плат АЦП. Соединение "точка-точка" - мусор отсутствует, только полезные данные.

Увы - пока я Вашего слона представляю как нечто похожее на веревку wink.gif

Плат АЦП у Вас несколько? Каков траффик средний/пиковый? Будет ли lose-less режим 10G MAC? каков протокол передачи данных/управления платами? Нужен ли контроль целостности/непрервыности данных? необходима ли заливка потока данных каждого АЦП в независимый буфер? Нужена ли преобработка/статистика данных? Режимы работы? ...................

Ну а если по простому гнать пакеты в одну сторону то 800-900 MB/s можно получить без проблем. Естетсвенно если у Ваc слон хотябы о 4 ногах и желателно в версии 2 sm.gif

Успехов! Rob.


doom13
Цитата(RobFPGA @ Sep 28 2015, 18:47) *

Что-то мы ушли от темы. Считаем, что есть генератор трафика (просто пакеты данных) с максимальным потоком данных 10Gbit/s, шина данных 64 бита, тактовая частота 156.25 MHz и надо всё это запихнуть в ПК по PCIe. Пока сделал, как на рисунке выше, но вижу, что это неправильно, и начинаю попытки запустить DMA S2MM. А тут есть вопросы, как правильно идет формирование и работа с дескрипторами.
doom13
Цитата(RobFPGA @ Sep 28 2015, 18:47) *
Ну а если по простому гнать пакеты в одну сторону то 800-900 MB/s можно получить без проблем. Естетсвенно если у Ваc слон хотябы о 4 ногах и желателно в версии 2 sm.gif

C FIFO S2MM + CDMA для системы описанной выше пока получилось примерно 6 Gbit/s, но это совсем ерунда для PCIe x4 Gen2. Далее, при увеличении скорости потока данных, система в прерывании от FIFO не успевает перезапускать CDMA и тормозит генератор трафика. CDMA работает в Simple Mode, а как запустить его в режиме Scatter-Gather Mode для данной реализации не придумал. Поэтому смотрю в сторону DMA S2MM.
Цитата(RobFPGA @ Sep 28 2015, 17:23) *
Для начала почитайте LogiCORE IP AXI DMA v6.00.a Product Guide (pg021_axi_dma.pdf) В более новых доках отсутствуют понятные картинки про ring buffer. sad.gif

Почитал доку, посмотрел рисунки, получается, понял всё правильно, то что и описано во втором варианте поста #11. Ранее почему-то считал, что после запуска DMA обновлять цепочку дескрипторов не допускается. Получается очень даже "красиво".
А как привязать сюда несколько таблиц (колец) дескрипторов? Или оно мне не надо?

А что если использовать несколько таблиц и по заполнению таблицы переключаться на следующую, а заполненную отдавать софту на обработку? Т.е. софт обрабатывает данные только после заполнения всей таблицы. Или производительность быдет примерно одинакова и опять же будет ограничена софтом?
Golikov A.
с 2 таблицами проще, что софт сможет монопольно не оглядываясь на то где сейчас ДМА, всю таблицу поправить, переписав назначения и отдать ее в работу. Меньше потенциальных ошибок, а производительность похоже не измениться если только на проценты...
RobFPGA
Приветствую!

Цитата(Golikov A. @ Sep 29 2015, 09:16) *
с 2 таблицами проще, что софт сможет монопольно не оглядываясь на то где сейчас ДМА, всю таблицу поправить, переписав назначения и отдать ее в работу. Меньше потенциальных ошибок, а

Увы - самая чувствительная точка в этой схеме - переключение колец - и эта точка полное G sm.gif
Гарантировать малое и детерминированное время обработки прерывания могут только некоторые OC да и то для 10G это время почти что вечность.
Работа драйвера в BD ринг всегда монопольна поскольку драйвер работает только с той частью буферов которые DMA УЖЕ прошел. а второй раз DMA по ним не пройдет пока драйвер не обновит доступность этой части BD.

Вообще можно делать и не замкнутое кольцо - просто этакая непрерывная лента дескрипторов. Однако при этом появляются дополнительные расходы времени на выделение/освобождение памяти под дескрипторы. Отсюда и кольцо - один раз выделили и используем постоянно. Ну а размер зависит от максимально ожидаемых затыков в работе ДРАЙВЕРА.

Успехов! Rob.
doom13
Столкнулся с тем, что ядро Linux не хочет выделять непрерывное адресное пространство более 4 MBytes. Получается одним кольцом дескрипторов могу передать максимум 4 MBytes (если система затупила и какое-то время не обновляет дескрипторы), а хотелось больше. На плате есть ещё планка DDR3 SO-DIMM.
1) Есть ли смысл выделить память под буферы данных в ней (одним кольцом дескрипторов смогу передавать больше данных), а драйвер будет забирать данные из DDR3 (адреса DDR3 через PCIe:BARs транслируем в систему)?
2) Лучше сделать несколько колец дескрипторов. Если DMA заполнил все буферы в одном кольце, а система не успела обработать и обновить, то переключаемся на другое??? Тут не нравится, что придётся менять настройки моста при переключении кольца дескрипторов.
3) Может можно как-то "обмануть" систему и заставить выделить непрерывное адресное пространство более 4 MBytes? В доке Xilinx на AXI2PCIe Bridge они приводят пример для AXI:BARs с размером 32 MBytes.
RobFPGA
Приветствую!

Цитата(doom13 @ Sep 30 2015, 17:28) *
Столкнулся с тем, что ядро Linux не хочет выделять непрерывное адресное пространство более 4 MBytes. Получается одним
...


А зачем Вам непрерывное пространство ?
Размер дескриптора 32 байта, а страницу 4k влазит 128 штук (небольшая карусельна ), ну а в 4M аж лень считать сколько (целое колесо обозрения получится sm.gif ). Вы наверное пытаетесь еще и буфера тут же втиснуть. так это и не надо
буфера выделяются отдельно физическими блоками-страницами и линкуются в дескрипторы
В самом простом случае (размер физ страниц 4K) 128 дескрипторов мапят 512K буферов.

Теперь грубо считаем что хуже -
для маленьких пакетов 128 буферов это на ~7us полета
Для jumbo пакетов 512K - это ~512 us парения
С учетом того что типичное время обработки прерывания ~10-100 us если взять кольцо из 32*128 дескрипторов то можно быть уверен что драйвер гарантированно обработает прерывание и сможет :
пройти по кольцу от последней точки хвоста кольца дескрипторов до текущего положения головы
указатели на заполненные буера убрать из дескрипторов и отправить в очередь ленивому юзеру на обработку
выделить память под свободные буфера и заполнить указателями на них поля в вытирающих пот дескрипторах
вновь отправив их на тяжкий труд передвинув положение хвоста в соответствующем регистре ДМА

ДМА при этом на останавливается - так как будет иметь как минимум половину готовых дескрипторов для работы

В таком случае можно забить данными всю память которую только можно выделить

Успехов! Rob.
doom13
Цитата(RobFPGA @ Sep 30 2015, 19:03) *

Приветствую.
Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на буферы памяти из непрерывного адресного пространства. А система максимум непрерывно даёт 4 MB. Т.е. одно кольцо сможет перебросить максимум 4 MB, если система не успевает обрабатывать и возвращать дескрипторы. А хочется сделать, чтоб оно было больше. Может этого и достаточно. Т.е. под данные выделяем большой блок памяти (непрерывный), а его дробим на отдельные буферы на которые и будут указывать дескрипторы, но размер этого блока пока получается максимум 4 MB.
Если дескриптор указывает на буфер из другого адресного пространства, то надо либо переключать мост на это пространство, либо использовать дополнительный BAR.

PS:
Цитата(RobFPGA @ Sep 30 2015, 19:03) *
Вы наверное пытаетесь еще и буфера тут же втиснуть. так это и не надо
буфера выделяются отдельно физическими блоками-страницами и линкуются в дескрипторы

Да, только адреса буферов транслируются через PCIe мост, т.е. тут и нужно, чтоб они шли непрерывно со смещением на размер буфера. Либо я тут чего-то не понимаю.
RobFPGA
Приветствую.

Цитата(doom13 @ Sep 30 2015, 19:27) *
Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на
буферы памяти из непрерывного адресного пространства


С какого это перепугу? там единственное ограничение может быть чтобы адреса дескрипторов были в младших 4G
А где именно пофиг - ведь в каждом дескрипторе УКАЗАТЕЛЬ на следующий дескриптор и УКАЗАТЕЛЬ на буфер.

Надо выделять под буфера много мелких. а не большой непрерывный кусок памяти, главное чтобы в окно попали.

Успехов! Rob

P.S. Ну и размер аппретуры AXI ->PCIe можно попробовать сделать в 64 бита sm.gif
krux
Цитата
Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на буферы памяти из непрерывного адресного пространства. А система максимум непрерывно даёт 4 MB.

память, в которую может писать DMA располагается в kernelspace.
а теперь представьте гипотетическую ситуацию, что вам выделили 512 МБайт непрерывно.
Это значит, что как только вы загрузили ваш модуль ядра, он у вас сразу отожрал от оперативки 512 МБайт. Даже если вы DMA-передачи не собирались пока ещё делать. И из userspace эта память больше не доступна. Идиотизм же.
Поэтому нормальным размером непрерывно выделяемого блока считается 4 КБайт.

Обратите внимание на видеокарты с набортной памятью в 4 Гбайт, 10-GbE сетевки, да вообще любые PCIe устройства.
Никто из них не требуют выделения сколь-нибудь заметного линейного пространства. Опять-таки потому что это уже всеми давным-давно признано идиотизмом.
Все уже умеют SGDMA.
doom13
Хорошо.
Поясните мне вот это: AXI to PCIe Bridge имеет параметры Aperture Base Address, Aperture Hight Address, AXI to PCIe Translation, где Aperture - это адресное пространство для AXI DMA, Translation - куда будет ложиться в память выделяемую ядром. Т.е. ядро выделяет память и начальный физический адрес этой памяти записываем в регистр AXIBAR2PCIEBAR, когда DMA бросает данные по адресам Aperture, они попадают в память адрес которой хранится в AXIBAR2PCIEBAR (непрерывный участок памяти 4 MB разбиваем на буферы, а их адреса записываем в дескрипторы). Что делать, если хотим отдать под буферы памяти больше 4 MB? Тут придётся использовать другой BAR, под который выделяется свой блок памяти 4 MB, или для другого кольца/таблицы дескрипторов менять значение в регистре AXIBAR2PCIEBAR моста.

Цитата(RobFPGA @ Sep 30 2015, 19:42) *
Надо выделять под буфера много мелких. а не большой непрерывный кусок памяти, главное чтобы в окно попали.

Если много мелких по 4 MB (блоки памяти с разными адресами не из одного адресного пространства), как их тогда все запихнуть в AXI:BAR?

Цитата(RobFPGA @ Sep 30 2015, 19:42) *
УКАЗАТЕЛЬ на буфер.

Указатель на буфер - физический адрес буфера, записывается в регистр моста (начальный адрес). Адрес следующего можем определить смещением относительно первого на размер буфера и т.д. Но размер всех буферов получим 4 MB. Как иначе?

Цитата(krux @ Sep 30 2015, 20:27) *
Обратите внимание на видеокарты с набортной памятью в 4 Гбайт, 10-GbE сетевки, да вообще любые PCIe устройства.

Как эту наборную память адресовать через один AXI:BAR?
RobFPGA
Приветствую!

Цитата(doom13 @ Sep 30 2015, 22:07) *
Хорошо.
Поясните мне вот это: AXI to PCIe Bridge имеет параметры [i]Aperture Base Address, Aperture Hight Address, AXI to PCIe
....

Все совсем не так
Aperture Base Address -Aperture Hight Address диапазон адресов на AXI SLAVE при обращении в который происходит мапинг в ФИЗИЧЕСКОЕ пространство системы с соответствующим смещение PCIe Translation
(SLAVE:Base<= X <= Hight -> SYTEM:X-Base+Translation )

ФИЗИЧЕСКИЙ адрес ВСЕЙ памяти системы известен он НЕ меняется в процессе работы
У вас ведь памяти не 2^64 байт? Например если у вас стоит 16G памяти то задав ОДНО окно
Base=0x0_0000_0000 Aperture Hight=0x3_FFFF_FFFF, PCIe Translation=0x0_0000_0000
Вы сможете работать со всей имеющейся у вас памятью (ну почти )

Успехов! Rob
doom13
Получается, для системной памяти Aperture - это размер адресного пространства начиная с адреса, который записан в Translation. В Translation записываю физический адрес выделяемого блока памяти 4MB, для остальных блоков уже не получится.

Если же в Translation записать начальный физический адрес системной памяти, тогда всё становится понятно. Как это делается, как определить начальный адрес памяти ядра/системы?

Или это он и есть:
Цитата(RobFPGA @ Sep 30 2015, 23:06) *
ФИЗИЧЕСКИЙ адрес ВСЕЙ памяти системы известен он НЕ меняется в процессе работы
У вас ведь памяти не 2^64 байт? Например если у вас стоит 16G памяти то задав ОДНО окно
Base=0x0_0000_0000 Aperture Hight=0x3_FFFF_FFFF, PCIe Translation=0x0_0000_0000
Вы сможете работать со всей имеющейся у вас памятью (ну почти )

т.е. в Translation регистр AXIBAR2PCIEBAR записываем 0 и тогда при выделении блока памяти его физический адрес можно использовать в дескрипторе?
Но тут как-то странно получается, через один бар DMA может видеть всю системную память?


Если железо будет видеть всю системную память, то при сбое оно убъёт систему?!
RobFPGA
Приветствую!

Цитата(doom13 @ Sep 30 2015, 23:42) *
Получается, для системной памяти Aperture - это размер адресного пространства начиная с адреса, который записан в Translation
Да это так

Цитата(doom13 @ Sep 30 2015, 23:42) *
... В Translation записываю физический адрес выделяемого блока памяти 4MB, для остальных блоков уже не получится.
А так делать не надо

Цитата(doom13 @ Sep 30 2015, 23:42) *
Если же в Translation записать начальный физический адрес системной памяти, тогда всё становится понятно. Как это делается, как определить начальный адрес памяти ядра/системы?
Это надо мангу ой мануалы на OC покурить - думаю найдете пару-тройку полезных няшек sm.gif

Цитата(doom13 @ Sep 30 2015, 23:42) *
Или это он и есть:
т.е. в Translation регистр AXIBAR2PCIEBAR записываем 0 и тогда при выделении блока памяти его физический адрес можно использовать в дескрипторе?
Бинго !
Ноль это в самом постом случае - можно так же учитывать этот оффсет при пересчете указателей на физический адрес например если у вас буфера сидят на другом физическом проце.

Цитата(doom13 @ Sep 30 2015, 23:42) *
Но тут как-то странно получается, через один бар DMA может видеть всю системную память?
А чего старинного ? Классические DMA, то есть те которые сидят непосредственно на PCIe контроллере, так мир и видят - плоский стоящий на 3 китах rolleyes.gif И да - чуь что н не так - моменто в море
А тут целый bridge! который более универсален в применении и не только под DMA рассчитан - вот вводит в ступор от многообразия возможностей.

Успехов! Rob
doom13
Цитата(RobFPGA @ Oct 1 2015, 00:13) *
Ноль это в самом постом случае - можно так же учитывать этот оффсет при пересчете указателей на физический адрес например если у вас буфера сидят на другом физическом проце.

Может быть подскажете, как определить начальный физический адрес памяти в системе?
Спасибо.

Или он равен "0"?
doom13
Нашёл, dmidecode показывает всю системную информацию, все мои 16 GB оперативы по адресам 0х00000000_00000000 - 0х00000003_FFFFFFFF. Система выделяет буферы памяти, физические адреса которых лежат в пределах этого адресного пространства. Буду пробовать бросить данные DMA-ой.
Спасибо за помощь.
doom13
Для ядра AXI Bridge for PCIe Gen 3 есть такая закономерность, если задать параметры:
Aperture Base Address 0x00000000_00000000
Aperture Hight Address 0x00000003_FFFFFFFF
AXI to PCIe Translation 0xXXXXXXXC_00000000 (X - любое значение).

Т.е. мост хочет, чтобы в Translation был 0 на месте, где в Aperture Hight Address стоит 1, либо говорит, что параметр задан неправильно.
Это можно как-то объяснить или это какой-то баг?

С другой стороны, если сгенерить ядро с такими настройками, не получится динамически менять значение младшего регистра Translation (значение старшего регистра Translation можно динамически задавать любым 0xXXXXXXXX_00000000), предполагаю , что что-то оптимизировалось при сборке проекта.

C описанной выше адресацией опять ерунда получилась и хотелось бы проверить работу системы при Translation = 0x00000000_С0000000, а задать его не получается (или ругается при настройке параметров ядра, или не меняет значение при записи в младший регистр Translation).
RobFPGA
Приветствую!

Цитата(doom13 @ Oct 2 2015, 16:31) *
Т.е. мост хочет, чтобы в Translation был 0 на месте, где в Aperture Hight Address стоит 1, либо говорит, что параметр задан неправильно.
Это можно как-то объяснить или это какой-то баг?

Вобще то это большой секрет фирмы Xilinx но благодоря утечкам Вы можете ознакомится с ним в PG194 AXI Bridge for PCI Express Gen3 v1.1 стр 37. sm.gif
Это просто такая оптимизация трансляции адреса в железе не нужен длинный сумматор

Успехов! Rob.
doom13
Что-то я вообще запутался, как оно работает.
А как мне тогда для апертуры Aperture Base Address 0x00000000_00000000 и Aperture Hight Address 0x00000003_FFFFFFFF задать смещение
0x00000000_С0000000? Как вижу это невозможно.
Тогда самый главный вопрос - что записывается в регистры Translation? Я писал туда адрес блока памяти, который возвращала функция virt_to_phys и оно работало, сейчас думай - как? Может ещё тут что посоветуете?
krux
Цитата
Что-то я вообще запутался, как оно работает.

зависит от того, с чем вы хотите разобраться.

если с PCI-Express, то предлагаю выкинуть AXI-to-PCIe bridge и по-человечески разобраться c PCI-Express при помощи "заката солнца вручную", без посторонних инструментов. Например сделав простой DMA для передачи всего лишь 4КБайт. С BAR-ами и прочими обязательными аттрибутами этого интерфейса.

если же с мостом AXI-to-PCIe bridge, то предполагается что с PCI-E "врукопашную" вы уже знакомы.
отделите мух от котлет, станет попроще.
doom13
Цитата(krux @ Oct 2 2015, 20:56) *
зависит от того, с чем вы хотите разобраться.

если с PCI-Express, то предлагаю выкинуть AXI-to-PCIe bridge и по-человечески разобраться c PCI-Express при помощи "заката солнца вручную", без посторонних инструментов. Например сделав простой DMA для передачи всего лишь 4КБайт. С BAR-ами и прочими обязательными аттрибутами этого интерфейса.

если же с мостом AXI-to-PCIe bridge, то предполагается что с PCI-E "врукопашную" вы уже знакомы.
отделите мух от котлет, станет попроще.

Разбираться с Transaction Layer пока не хотел, как понимаю, мост делает это за меня. PCIe to AXI BAR работает и всё понятно, а вот с AXI to PCIe BAR есть какое-то непонимание.
Объясните, если я задаю Aperture 16 ГБ (как в посте выше), Translation 0, получается, должно позволить адресовать 16 ГБ системной памяти? А система выделяет буфер с физическим адресом за пределами этих 16 ГБ. Вот и как получить к нему доступ?
RobFPGA
Приветствую!

Цитата(doom13 @ Oct 2 2015, 22:52) *
Разбираться с Transaction Layer пока не хотел, как понимаю, мост делает это за меня. PCIe to AXI BAR работает и всё понятно, а вот с AXI to PCIe BAR есть какое-то непонимание.
Объясните, если я задаю Aperture 16 ГБ (как в посте выше), Translation 0, получается, должно позволить адресовать 16 ГБ системной памяти? А система выделяет буфер с физическим адресом за пределами этих 16 ГБ. Вот и как получить к нему доступ?
Никак!
Мне не понятно Ваше желание ограничить свободу DMA без предявления оному внятных обвинений а нам не менее внятных обяснений. Ведь DMA он мелкая сошка - и делает то что прикажет бугор (драйвер). Поэтому разбирайтес с бугром и его боссом (програмистом) почему они возволяют себе такое безобразие.

Вы судя по всему устаете под вечер вот очевидных вещей и не видете - я же уже вредлагал - сделайте аппертуру в 64 бит и смещение 0 - и тогда хитрый CPU не сможет нигде от Вас спрятатся sm.gif
Ой - и да - при этом получается вариант как "заката солнца вручную" - ну разве что катить светило на тележке удобнее.

Успехов! Rob.
doom13
Цитата(RobFPGA @ Oct 3 2015, 00:03) *
Поэтому разбирайтес с бугром и его боссом (програмистом) почему они возволяют себе такое безобразие.

Тут я сам себе босс sm.gif, поэтому и вопросов очень много.

Цитата(RobFPGA @ Oct 3 2015, 00:03) *
сделайте аппертуру в 64 бит и смещение 0 - и тогда хитрый CPU не сможет нигде от Вас спрятатся sm.gif
Ой - и да - при этом получается вариант как "заката солнца вручную" - ну разве что катить светило на тележке удобнее.

Апертуру 0 - 2^64 и смещение 0 ??? Это можно, но нет уверенности что физический адрес буфера за пределами RAM будет соответствовать ему же записанному в дескрипторе. Или будет? Т.е. физический адрес буфера записываю в дескриптор и такая апертура позволит DMA добраться к любому адресу?
Цитата(RobFPGA @ Oct 3 2015, 00:03) *
Мне не понятно Ваше желание ограничить свободу DMA без предявления оному внятных обвинений а нам не менее внятных обяснений.

Свободу DMA ограничивать не хотел, просто не понимаю как система выделяет буфер за пределами адресов моего RAM.
doom13
Цитата(RobFPGA @ Oct 3 2015, 00:03) *

Цитата(krux @ Oct 2 2015, 20:56) *

Приветствую!
Спасибо за помощь.
Сделал апертуру 0x0000000000000000 - 0x7FFFFFFFFFFFFFFF, DMA может добраться к дескрипторам и буферам для данных не зависимо от того, где выделила для них память система.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.