LINUX.ORG.RU

fpga + pcie + dma + SG

 , , , sg


1

2

Всех приветствую.

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

Для начала исходные данные:

  1. Есть некая fpga которая может прикидываться EP сидя на шине PCIe для передачи данных от CPU в какую-то физическую среду, которая где-то там с другой стороны выходит в наружу (суть ее на важна, если кому-то нужна определенность пусть будет serdes).

  2. Для эффективной и быстрой передачи делаем SG и схематоз типа сетевых карт. Заводим в памяти массив дескрипторов, где есть битовый флаг владельца этого дескриптора и адрес буфера где лежат сами данные. Ну и для полноты битик обозначающий конец массива дескрипторов (чтобы железка понимала, что надо начинать читать с начала). Для простоты, пока считаем передачу в одну сторону - MEM2DEV. Отдельно выделяем буферы для данных, адреса которых, прописываем в дескрипторы.

  3. В железку, куда-то в регистр прописываем адрес начала массива дескрипторов.

Это все исходные данные.

Дальше берем линукс, пишем стандартный драйвер для pci. Где выделяем память для массива дескрипторов (конечно с когерентностью), выделяем буфера. Заполняем дескрипторы адресами буферов и битики все расставляем куда надо.

Это наше исходное состояние.

А вот теперь внимательно смотрим за руками. В драйвер кто-то закинул пакет данных. Драйвер взял первый пустой дескриптор, взял там адрес буфера, залил в этот буфер пакет данных, пометил, что оунер дескриптора стал DEV и выставил в регистре железки битик, что есть данные для передачи и пошел спать.

И вот тут у меня свербящий вопрос, что дальше делает железка?

Понятно, что железка битик сразу заметит. Как именно? Как быстро?

По моим ощущениям где-то через 1 клок внутренней частоты fpga.

Дальше запустится процесс чтения дескриптора. Как она его будет читать? По-словно по шине pcie из памяти к себе? Стартанет DMA для передачи сразу всего массива дескрипторов?

Призываются все плисоводы которые реализовывали pcie на fpga для передачи чего-то сложнее хеловорда.

★★★★★

Понятно, что железка битик сразу заметит. Как именно? Как быстро?

Делаешь mmio write и железка узнает что у тебя готов новый пакет в ту же микросекунду

А далее она делает серию MRd, смотря какой размер TLP настроен

P.S. С радостью подскажу и отвечу на все остальные вопросы

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)

Дальше запустится процесс чтения дескриптора. Как она его будет читать? По-словно по шине pcie из памяти к себе? Стартанет DMA для передачи сразу всего массива дескрипторов?

Всё просто. Выделяем память в драйвере, а массив адресов держим копию в ПЛИС. Дальше просто пишем в разные буфера, и уведомляем стороны что куда писалось и откуда дочиталось

То есть эти SG мне не понятны. Я не понимаю зачем они, если всё работает и без них и даже так же быстро

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

То есть эти SG мне не понятны.

С этого и надо начинать. Для расширения кругозора: SG нужен, чтобы управлять кучей разрозненныйх буферов, которые лежат не в смежных областях. Не всегда есть возможность 8МБ одним куском в ядре получить. Или 256 МБ. Вот тут и приходит SG.

Во многих DMA-контроллерах есть поддержка SG на аппаратном уровне. Так же всякие сетевки и прочие кто может быстро данные гонять работают через них.

Вопрос в общем-то ровно один: как железки себе подтягивают массив дескрипторов?

Например, RTL8169 работает с массивом дескрипторов в памяти хоста, который к себе копирует скорей всего через DMA по PCI. Но это не точно.

XAPP1171, точно так же. Только тут точно через DMA, но без подробностей по сколько читает, как часто полит и т.д.

Как вариант, можно массив дескрипторов держать на самой железке и ходить туда через трансляцию через BAR. Тогда железка вообще никуда ходить не будет по шине. А RC просто будет ее заполнять, а по прерываниям от EP обновлять, чего там изменилось в связи с передачей. Но это пока мои фантазии и скорей всего так никто не делает, и хочется понять почему.

yax123 ★★★★★
() автор топика

@Puzan - ты случайно не в теме?

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

Не, то что не выделить буфер сразу большой и без дырок - это мне было ясно и 5 лет назад. Я так и пользуюсь - я работаю с десятками буферов по 4/8 килобайт, их адреса вообще не всегда без дырок

Вопрос в общем-то ровно один: как железки себе подтягивают массив дескрипторов?

Я вот выделяю этот массив буферов 1 раз, передаю 1 раз и работаю миллионами циклов в одних и тех же адресах без сбоев

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

Я вот выделяю этот массив буферов 1 раз, передаю 1 раз

Сколько буферов и каких размеров?

У меня вот в текущей версии 4096 буферов по 4K.

yax123 ★★★★★
() автор топика
Ответ на: комментарий от yax123

Вопрос в общем-то ровно один: как железки себе подтягивают массив дескрипторов?

Читают память через PCIe. Это же общая шина, с единым адресным пространством. До изобретения iommu с любого устройства PCIe можно было прочитать всю память и даже управлять другими устройствами. С iommu проц настраивает окна, которые доступны твоему устройству.

Puzan ★★★★★
()
Ответ на: комментарий от yax123

Ну там всегда прямой доступ к памяти. Это в старых системах был выделенный контроллер DMA, который условно отключал от памяти проц и подключал устройство. Сейчас есть шина (pcie это вообще p2p), есть интерконнект (коммутатор), который разруливает запросы, есть контроллер памяти, который получает запросы и выдаёт ответы.

По этому, из устройства шина видится просто как адресное пространство. Сверху на это адресное пространство ставится контроллер DMA, который просто занимается рутиной по разруливанию дескрипторов, чтению/записи блоков, контролю границ и пр.

Puzan ★★★★★
()
Ответ на: комментарий от yax123

SG - это чисто логическая фигулина, которую можно реализовать как угодно (обычно и реализуют кто как придумал). Можно сделать отдельный буфер с дескрипторами, можно цепочкой буферов с заголовками, можно ещё как нибудь. Есть вообще иерархические реализации.

Т.е. для написания дров надо смотреть что там понаделали разработчики микросхемы.

Puzan ★★★★★
()
Последнее исправление: Puzan (всего исправлений: 1)
Ответ на: комментарий от Puzan

Да, при этом можно читать хоть контроллером DMA, хоть встроенным процом, хоть какой-то своей логикой. Разницы нет.

Puzan ★★★★★
()
Ответ на: комментарий от yax123

я работаю с десятками буферов по 4/8 килобайт

Адреса можно выделить 1 раз и не освобождать их, соответственно далее простые счетчики. У меня вот до 100 таких указателей, но даже если 32 битных буферов 4096, это уже 16 килобайт, такое в регистрах не похранить

Но зато это я бы поместил в блочную память, и если надо N буферов одновременно, то шина N * 32 бит у памяти, не все же 4096 одновременно

I-Love-Microsoft ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.