Перейти к содержанию
    

Ну а если по простому гнать пакеты в одну сторону то 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.

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

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

А как привязать сюда несколько таблиц (колец) дескрипторов? Или оно мне не надо?

 

А что если использовать несколько таблиц и по заполнению таблицы переключаться на следующую, а заполненную отдавать софту на обработку? Т.е. софт обрабатывает данные только после заполнения всей таблицы. Или производительность быдет примерно одинакова и опять же будет ограничена софтом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

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

Увы - самая чувствительная точка в этой схеме - переключение колец - и эта точка полное G :)

Гарантировать малое и детерминированное время обработки прерывания могут только некоторые OC да и то для 10G это время почти что вечность.

Работа драйвера в BD ринг всегда монопольна поскольку драйвер работает только с той частью буферов которые DMA УЖЕ прошел. а второй раз DMA по ним не пройдет пока драйвер не обновит доступность этой части BD.

 

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

 

Успехов! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Столкнулся с тем, что ядро 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

Столкнулся с тем, что ядро Linux не хочет выделять непрерывное адресное пространство более 4 MBytes. Получается одним

...

 

А зачем Вам непрерывное пространство ?

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

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

В самом простом случае (размер физ страниц 4K) 128 дескрипторов мапят 512K буферов.

 

Теперь грубо считаем что хуже -

для маленьких пакетов 128 буферов это на ~7us полета

Для jumbo пакетов 512K - это ~512 us парения

С учетом того что типичное время обработки прерывания ~10-100 us если взять кольцо из 32*128 дескрипторов то можно быть уверен что драйвер гарантированно обработает прерывание и сможет :

пройти по кольцу от последней точки хвоста кольца дескрипторов до текущего положения головы

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

выделить память под свободные буфера и заполнить указателями на них поля в вытирающих пот дескрипторах

вновь отправив их на тяжкий труд передвинув положение хвоста в соответствующем регистре ДМА

 

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

 

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

 

Успехов! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую.

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

Если дескриптор указывает на буфер из другого адресного пространства, то надо либо переключать мост на это пространство, либо использовать дополнительный BAR.

 

PS:

Вы наверное пытаетесь еще и буфера тут же втиснуть. так это и не надо

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую.

 

Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на

буферы памяти из непрерывного адресного пространства

 

С какого это перепугу? там единственное ограничение может быть чтобы адреса дескрипторов были в младших 4G

А где именно пофиг - ведь в каждом дескрипторе УКАЗАТЕЛЬ на следующий дескриптор и УКАЗАТЕЛЬ на буфер.

 

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

 

Успехов! Rob

 

P.S. Ну и размер аппретуры AXI ->PCIe можно попробовать сделать в 64 бита :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как понимаю, чтоб DMA мог работать по цепочке дескрипторов непрерывно, необходимо, чтоб все дескрипторы указывали на буферы памяти из непрерывного адресного пространства. А система максимум непрерывно даёт 4 MB.

память, в которую может писать DMA располагается в kernelspace.

а теперь представьте гипотетическую ситуацию, что вам выделили 512 МБайт непрерывно.

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

Поэтому нормальным размером непрерывно выделяемого блока считается 4 КБайт.

 

Обратите внимание на видеокарты с набортной памятью в 4 Гбайт, 10-GbE сетевки, да вообще любые PCIe устройства.

Никто из них не требуют выделения сколь-нибудь заметного линейного пространства. Опять-таки потому что это уже всеми давным-давно признано идиотизмом.

Все уже умеют SGDMA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо.

Поясните мне вот это: 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 моста.

 

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

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

 

УКАЗАТЕЛЬ на буфер.

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

 

Обратите внимание на видеокарты с набортной памятью в 4 Гбайт, 10-GbE сетевки, да вообще любые PCIe устройства.

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

Хорошо.

Поясните мне вот это: AXI to PCIe Bridge имеет параметры 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Или это он и есть:

ФИЗИЧЕСКИЙ адрес ВСЕЙ памяти системы известен он НЕ меняется в процессе работы

У вас ведь памяти не 2^64 байт? Например если у вас стоит 16G памяти то задав ОДНО окно

Base=0x0_0000_0000 Aperture Hight=0x3_FFFF_FFFF, PCIe Translation=0x0_0000_0000

Вы сможете работать со всей имеющейся у вас памятью (ну почти )

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

Но тут как-то странно получается, через один бар DMA может видеть всю системную память?

 

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

Получается, для системной памяти Aperture - это размер адресного пространства начиная с адреса, который записан в Translation
Да это так

 

... В Translation записываю физический адрес выделяемого блока памяти 4MB, для остальных блоков уже не получится.
А так делать не надо

 

Если же в Translation записать начальный физический адрес системной памяти, тогда всё становится понятно. Как это делается, как определить начальный адрес памяти ядра/системы?
Это надо мангу ой мануалы на OC покурить - думаю найдете пару-тройку полезных няшек :)

 

Или это он и есть:

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

Бинго !

Ноль это в самом постом случае - можно так же учитывать этот оффсет при пересчете указателей на физический адрес например если у вас буфера сидят на другом физическом проце.

 

Но тут как-то странно получается, через один бар DMA может видеть всю системную память?
А чего старинного ? Классические DMA, то есть те которые сидят непосредственно на PCIe контроллере, так мир и видят - плоский стоящий на 3 китах :rolleyes: И да - чуь что н не так - моменто в море

А тут целый bridge! который более универсален в применении и не только под DMA рассчитан - вот вводит в ступор от многообразия возможностей.

 

Успехов! Rob

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ноль это в самом постом случае - можно так же учитывать этот оффсет при пересчете указателей на физический адрес например если у вас буфера сидят на другом физическом проце.

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

Спасибо.

 

Или он равен "0"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашёл, dmidecode показывает всю системную информацию, все мои 16 GB оперативы по адресам 0х00000000_00000000 - 0х00000003_FFFFFFFF. Система выделяет буферы памяти, физические адреса которых лежат в пределах этого адресного пространства. Буду пробовать бросить данные DMA-ой.

Спасибо за помощь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для ядра 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).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...