LINUX.ORG.RU

Scatter/Gather


0

1

Занимаюсь написанием драйвера для самописной железки. Перодически появляются вопросы(newbie). Реализую работу DMA с использованием SG.

После чтения LDD3 и DMA-API-HOWTo осталоcь несколько непонятных моментов

dma_map_sg(dev,sglist,nents,direction)

Как я понял в этом месте происходит мапирование на реальные адреса шины, но функции необходимо подсунуть уже заренее подготовленный sglist. Рекомендуемый способ его создания в документации особо не указан.

После получения bus addres, существует ли стандарт на передачу структур с указанием адресов на устройство, или всё отдается на фантазию разработчика?

> Как я понял в этом месте происходит мапирование на реальные адреса шины, но функции необходимо подсунуть уже заренее подготовленный sglist.

Есть не только *_sg - можешь мапить через dma_map_single

После получения bus addres, существует ли стандарт на передачу структур с указанием адресов на устройство, или всё отдается на фантазию разработчика?

Отдается фантазии разработчиков железа - ты просто кладешь dma_address и dma_length туда, куда нужно устройству.

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

>Есть не только *_sg - можешь мапить через dma_map_single

Мне нужен общий объем буфера порядка 100 МБайт.

Так как правильнее изначально формировать список?

AndriAno ()
Ответ на: комментарий от AndriAno

Дофига что-то... можно попробовать мапить по странице на дескриптор, если у тебя в устройстве хватит места для дескрипторов.

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

>можно попробовать мапить по странице на дескриптор, если у тебя в устройстве хватит места для дескрипторов.

Если я правильно понял dma_map_sg должен объединять рядом лежащие страницы, или я неправ? Но не буду же я изначально постранично такой объём выделять?

AndriAno ()
Ответ на: комментарий от AndriAno

> Если я правильно понял dma_map_sg должен объединять рядом лежащие страницы

Да.

Но не буду же я изначально постранично такой объём выделять?

Почему нет? Кроме того, ты вряд ли сможешь выделить все 100М единым куском без специальных трюков.

tailgunner ★★★★★ ()

...да и вообще, весь смысл S/G в том, чтобы можно было выделить много мелких кусков вместо одного большого.

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

>Почему нет? А сколько времени у меня займет выделение 100М/4К = 25000 отдельных страниц??

AndriAno ()
Ответ на: комментарий от tailgunner

Я согласен на 100, 200, ну 500 запросов выделения страниц. НО 25000!

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

Так я все время буду стоять и ждать накопления нужного числа страниц.

Есть ли возможность запроса пространства заданного объема под буффер с автоматическим объединением смежных областей?

AndriAno ()
Ответ на: комментарий от AndriAno

> Я согласен на 100, 200, ну 500 запросов выделения страниц. НО 25000!

Почему? Выдели всю память при загрузке, и не отдавай до выгрузки.

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

Я очень, очень удивлюсь, если документация такое советует. Процитируй ее.

Есть ли возможность запроса пространства заданного объема под буффер с автоматическим объединением смежных областей?

Тут вопрос в том, какого размера массивы S/G-дескрипторов _на устройстве_. Если они у тебя километровые, то о чем вообще беспокоиться? Замапишь страницы.

Насчет объединения - ХЗ, я нигде не видел обещания «мы обязательно будем сливать подряд лежащие страницы». Если твоя платформа это делает, можно попробовать трюк с high-order выделением (но всё равно придется обрабатывать неудачу такого выделения).

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

Я очень, очень удивлюсь, если документация такое советует. Процитируй ее.

Цитирую: /usr/src/linux/Documentation/DMA-API-HOWTO.txt

You should call dma_unmap_single when the DMA activity is finished, e.g. from the interrupt which told you that the DMA transfer is done.

Насчет объединения - ХЗ, я нигде не видел обещания...

The implementation is free to merge several consecutive sglist entries into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any consecutive sglist entries can be merged into one provided the first one ends and the second one starts on a page boundary - in fact this is a huge advantage for cards which either cannot do scatter-gather or have very limited number of scatter-gather entries) and returns the actual number of sg entries it mapped them to.

Платформа x86. А что за трюк с high-order выделением?

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

AndriAno ()
Ответ на: комментарий от AndriAno

> You should call dma_unmap_single when the DMA activity is finished, e.g. from the interrupt which told you that the DMA transfer is done.

Но это unmap, а не освобождение (так же и map - это не выделение). Кроме того, можно пользоваться sync_for_{cpu,device}

Насчет объединения - ХЗ, я нигде не видел обещания...


The implementation is free to merge


Ну да, «free to merge», но не «will merge».

Платформа x86. А что за трюк с high-order выделением?


Это заказываешь большой order, и, пока ядро может тебе его выделить, наслаждаешься жизнью :) Когда страницы этого order кончаются, переходишь на более низкий.

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


Кстати, есть еще один аппаратный трюк - подгрузка дескрипторов из памяти машины по ходу записи. Конечно, он применим не всегда.

tailgunner ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.