|
|
  |
Буфер для PCI Express |
|
|
|
Sep 28 2015, 18:54
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(RobFPGA @ Sep 28 2015, 18:47)  Ну а если по простому гнать пакеты в одну сторону то 800-900 MB/s можно получить без проблем. Естетсвенно если у Ваc слон хотябы о 4 ногах и желателно в версии 2  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.  Почитал доку, посмотрел рисунки, получается, понял всё правильно, то что и описано во втором варианте поста #11. Ранее почему-то считал, что после запуска DMA обновлять цепочку дескрипторов не допускается. Получается очень даже "красиво". А как привязать сюда несколько таблиц (колец) дескрипторов? Или оно мне не надо? А что если использовать несколько таблиц и по заполнению таблицы переключаться на следующую, а заполненную отдавать софту на обработку? Т.е. софт обрабатывает данные только после заполнения всей таблицы. Или производительность быдет примерно одинакова и опять же будет ограничена софтом?
|
|
|
|
|
Sep 29 2015, 07:10
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(Golikov A. @ Sep 29 2015, 09:16)  с 2 таблицами проще, что софт сможет монопольно не оглядываясь на то где сейчас ДМА, всю таблицу поправить, переписав назначения и отдать ее в работу. Меньше потенциальных ошибок, а Увы - самая чувствительная точка в этой схеме - переключение колец - и эта точка полное G  Гарантировать малое и детерминированное время обработки прерывания могут только некоторые OC да и то для 10G это время почти что вечность. Работа драйвера в BD ринг всегда монопольна поскольку драйвер работает только с той частью буферов которые DMA УЖЕ прошел. а второй раз DMA по ним не пройдет пока драйвер не обновит доступность этой части BD. Вообще можно делать и не замкнутое кольцо - просто этакая непрерывная лента дескрипторов. Однако при этом появляются дополнительные расходы времени на выделение/освобождение памяти под дескрипторы. Отсюда и кольцо - один раз выделили и используем постоянно. Ну а размер зависит от максимально ожидаемых затыков в работе ДРАЙВЕРА. Успехов! Rob.
|
|
|
|
|
Sep 30 2015, 16:03
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(doom13 @ Sep 30 2015, 17:28)  Столкнулся с тем, что ядро Linux не хочет выделять непрерывное адресное пространство более 4 MBytes. Получается одним ... А зачем Вам непрерывное пространство ? Размер дескриптора 32 байта, а страницу 4k влазит 128 штук (небольшая карусельна ), ну а в 4M аж лень считать сколько (целое колесо обозрения получится  ). Вы наверное пытаетесь еще и буфера тут же втиснуть. так это и не надо буфера выделяются отдельно физическими блоками-страницами и линкуются в дескрипторы В самом простом случае (размер физ страниц 4K) 128 дескрипторов мапят 512K буферов. Теперь грубо считаем что хуже - для маленьких пакетов 128 буферов это на ~7us полета Для jumbo пакетов 512K - это ~512 us парения С учетом того что типичное время обработки прерывания ~10-100 us если взять кольцо из 32*128 дескрипторов то можно быть уверен что драйвер гарантированно обработает прерывание и сможет : пройти по кольцу от последней точки хвоста кольца дескрипторов до текущего положения головы указатели на заполненные буера убрать из дескрипторов и отправить в очередь ленивому юзеру на обработку выделить память под свободные буфера и заполнить указателями на них поля в вытирающих пот дескрипторах вновь отправив их на тяжкий труд передвинув положение хвоста в соответствующем регистре ДМА ДМА при этом на останавливается - так как будет иметь как минимум половину готовых дескрипторов для работы В таком случае можно забить данными всю память которую только можно выделить Успехов! Rob.
|
|
|
|
|
Sep 30 2015, 16:34
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(RobFPGA @ Sep 30 2015, 19:03)  Приветствую. Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на буферы памяти из непрерывного адресного пространства. А система максимум непрерывно даёт 4 MB. Т.е. одно кольцо сможет перебросить максимум 4 MB, если система не успевает обрабатывать и возвращать дескрипторы. А хочется сделать, чтоб оно было больше. Может этого и достаточно. Т.е. под данные выделяем большой блок памяти (непрерывный), а его дробим на отдельные буферы на которые и будут указывать дескрипторы, но размер этого блока пока получается максимум 4 MB. Если дескриптор указывает на буфер из другого адресного пространства, то надо либо переключать мост на это пространство, либо использовать дополнительный BAR. PS: Цитата(RobFPGA @ Sep 30 2015, 19:03)  Вы наверное пытаетесь еще и буфера тут же втиснуть. так это и не надо буфера выделяются отдельно физическими блоками-страницами и линкуются в дескрипторы Да, только адреса буферов транслируются через PCIe мост, т.е. тут и нужно, чтоб они шли непрерывно со смещением на размер буфера. Либо я тут чего-то не понимаю.
|
|
|
|
|
Sep 30 2015, 16:42
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую. Цитата(doom13 @ Sep 30 2015, 19:27)  Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на буферы памяти из непрерывного адресного пространства С какого это перепугу? там единственное ограничение может быть чтобы адреса дескрипторов были в младших 4G А где именно пофиг - ведь в каждом дескрипторе УКАЗАТЕЛЬ на следующий дескриптор и УКАЗАТЕЛЬ на буфер. Надо выделять под буфера много мелких. а не большой непрерывный кусок памяти, главное чтобы в окно попали. Успехов! Rob P.S. Ну и размер аппретуры AXI ->PCIe можно попробовать сделать в 64 бита
|
|
|
|
|
Sep 30 2015, 17:27
|
Профессионал
    
Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596

|
Цитата Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на буферы памяти из непрерывного адресного пространства. А система максимум непрерывно даёт 4 MB. память, в которую может писать DMA располагается в kernelspace. а теперь представьте гипотетическую ситуацию, что вам выделили 512 МБайт непрерывно. Это значит, что как только вы загрузили ваш модуль ядра, он у вас сразу отожрал от оперативки 512 МБайт. Даже если вы DMA-передачи не собирались пока ещё делать. И из userspace эта память больше не доступна. Идиотизм же. Поэтому нормальным размером непрерывно выделяемого блока считается 4 КБайт. Обратите внимание на видеокарты с набортной памятью в 4 Гбайт, 10-GbE сетевки, да вообще любые PCIe устройства. Никто из них не требуют выделения сколь-нибудь заметного линейного пространства. Опять-таки потому что это уже всеми давным-давно признано идиотизмом. Все уже умеют SGDMA.
--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
|
|
|
|
|
Sep 30 2015, 19:56
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Хорошо. Поясните мне вот это: 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?
|
|
|
|
|
Sep 30 2015, 20:06
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(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
|
|
|
|
|
Sep 30 2015, 20:44
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Получается, для системной памяти 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 может видеть всю системную память? Если железо будет видеть всю системную память, то при сбое оно убъёт систему?!
|
|
|
|
|
Sep 30 2015, 21:13
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(doom13 @ Sep 30 2015, 23:42)  Получается, для системной памяти Aperture - это размер адресного пространства начиная с адреса, который записан в Translation Да это так Цитата(doom13 @ Sep 30 2015, 23:42)  ... В Translation записываю физический адрес выделяемого блока памяти 4MB, для остальных блоков уже не получится. А так делать не надо Цитата(doom13 @ Sep 30 2015, 23:42)  Если же в Translation записать начальный физический адрес системной памяти, тогда всё становится понятно. Как это делается, как определить начальный адрес памяти ядра/системы? Это надо мангу ой мануалы на OC покурить - думаю найдете пару-тройку полезных няшек  Цитата(doom13 @ Sep 30 2015, 23:42)  Или это он и есть: т.е. в Translation регистр AXIBAR2PCIEBAR записываем 0 и тогда при выделении блока памяти его физический адрес можно использовать в дескрипторе? Бинго ! Ноль это в самом постом случае - можно так же учитывать этот оффсет при пересчете указателей на физический адрес например если у вас буфера сидят на другом физическом проце. Цитата(doom13 @ Sep 30 2015, 23:42)  Но тут как-то странно получается, через один бар DMA может видеть всю системную память? А чего старинного ? Классические DMA, то есть те которые сидят непосредственно на PCIe контроллере, так мир и видят - плоский стоящий на 3 китах  И да - чуь что н не так - моменто в море А тут целый bridge! который более универсален в применении и не только под DMA рассчитан - вот вводит в ступор от многообразия возможностей. Успехов! Rob
|
|
|
|
|
Oct 1 2015, 09:25
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(RobFPGA @ Oct 1 2015, 00:13)  Ноль это в самом постом случае - можно так же учитывать этот оффсет при пересчете указателей на физический адрес например если у вас буфера сидят на другом физическом проце. Может быть подскажете, как определить начальный физический адрес памяти в системе? Спасибо. Или он равен "0"?
|
|
|
|
|
Oct 2 2015, 13:31
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Для ядра 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).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|