LINUX.ORG.RU

dma_alloc_coherent() and mmap


0

2

Есть модуль ядра для PCI-устройства, который нормально работает на разных версиях Linux c различными ядрами до 2.6.35 на процессорах Intel Core Dou и других x86, кроме Core i7 (на остальных Core iX не проверял). В модуле выделяются блоки памяти с помощью dma_alloc_coherent() для выполнения DMA в режиме bus mastering. Для блоков устанавливаю флаги SetPageReserved(). Физические адреса этих блоков передаются в приложение пользователя, где для них вызывается mmap() (в модуле remap_pfn_range()). Так вот при чтении данных всегда получаю 0xFFFFFFFF, хотя устройство непрерывно заполняет выделенные блоки памяти данными. Т.е. bus mastering DMA работает, формируются прерывания, ничего не подвисает. И такое поведение наблюдается только на Core i7. Подскажите в каком направлении копать. Куски кода приложу какие будут нужны. Спасибо.


>Так вот при чтении данных всегда получаю 0xFFFFFFFF, хотя устройство непрерывно заполняет выделенные блоки памяти данными.

Попробуй man msync перед чтением в юзерспейс- скорей всего на свежих интелях даже DMA-память кешируется :-)

anonymous
()

Я бы на твоем месте мапил память пользователю только после завершения DMA. Вообще, игры с DMA-памятью в пользовательскх программах чреваты разными сюрпризами.

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

>Вообще, игры с DMA-памятью в пользовательскх программах чреваты разными сюрпризами.

Какими например ? При конкурентном доступе арбитр контроллера памяти просто заставить процессор циклы накручивать.

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

К тому же скоростные устройства без аппаратных FIFO просто не делают - не надо думать что устройство присело на шину и никого не пускает, они сразу читают/пишут блоками в/из FIFO.

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

>> Вообще, игры с DMA-памятью в пользовательскх программах чреваты разными сюрпризами.

Какими например?

Например, когда память передана устройству (и в нее может идти DMA), ее можно читать или нельзя? Как отнесется к попыткам чтения устройство? То же, но насчет записи? Как ты это будешь отслеживать?

А главное, зачем это нужно? Пусть за состоянием DMA следит драйвер, и отдает userspace'у уже заполненные страницы. Просто и надежно. Если же нужно отдавать данные на устройство... ну, тогда вряд ли мы говорили бы о mmap.

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

В какой именно спеке это написано?

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

>Например, когда память передана устройству (и в нее может идти DMA), ее можно читать или нельзя?

В каждый момент времени к шине имеет доступ только одно устройство, следит за этим арбитр и дает доступ в соответствии с приоритетами, ЦПУ насколько я помню имеет наименьший приоритет.

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

С синхронизацией вопросов и проблем вроде не возникало. (До текущео момента) Данные поступают непрерывно, и если каждый раз выдлелять/освобождать/отображать/копировать память, то происходит пропуск блоков, или внешнего сигнала, что недопустимо. Синхронизация осуществляется через управляющую структуру, которая так же разделена между драйвером и приложением, но в которую устройство не пишет. Пишет только драйвер. Приложение же определяет какой блок можно читать и читает.

> Попробуй man msync перед чтением в юзерспейс- скорей всего на свежих интелях даже DMA-память кешируется :-)

Попробую. Если есть еще идеи - предлагайте, так как горю! Спасибо всем.

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

>В какой именно спеке это написано?

Как думаешь для чего на современных процессорах делают аж трехуровневый кеш - да потому что процессор очень много времени тратит для синхронизации шины при cache miss.

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

Кстати, если натолкнет га какие нить мысли, то ядро Linux 2.6.32 не смогло стартовать на этом Host-модуле с Core i7, что заставило перейти на более свежее ядро.

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

>> В какой именно спеке это написано?

Как думаешь

Я думаю, что кроме общих рассуждений ты ничего не привел. А я не хочу читать спеки на все арбитры шин, которые существуют в мире, поэтому строго придерживаюсь ядерного API работы с DMA. Я не знаю, как гарантировать соблюдение правил этого API в случае, когда доступ к замапленной на DMA памяти есть у пользователя, поэтому я не даю к ней доступа (или стараюсь не давать).

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

> Данные поступают непрерывно, и если каждый раз выдлелять/освобождать/отображать/копировать память, то происходит пропуск блоков, или внешнего сигнала, что недопустимо.

И устройство не сообщает (прерыванием или флагом) что оно начало/закончило слать данные?

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

>А я не хочу читать спеки на все арбитры шин, которые существуют в мире, поэтому строго придерживаюсь ядерного API работы с DMA.

Ну я еще в теме про Wayland понял что ты пердун, причем там ты был один из самых звонких :-) Можешь посмотреть как выделяют видеопамять для framebuffer в ядре - доступ к этой памяти имеет одновременно процессор (юзерспейсный процесс который ее мапит) и видеоконтроллер посредством DMA. Откуда ты взял что память DMA нельзя мапить - из какого API ?

anonymous
()

У нас такая же ситуация была с самопальным PCIE-устройстом: везде работает, на i7 - нет. Оказалось, что железячники неправильно PCIE-пакет собирают.

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

> Ну я еще в теме про Wayland понял что ты пердун, причем там ты был один из самых звонких :-)

Ребенок, это снова ты? Иди учи умные слова - их еще много, ими можно классно понтоваться перед ровесниками.

Откуда ты взял что память DMA нельзя мапить - из какого API ?

Я не говорил, что «нельзя» - я спросил о последствиях. Ты не ответил ничего конкретного, хотя меня это не удивляет. Но, чтобы не было непонимания: тебе можно мапить всё, что захочешь, и куда захочешь. Do it. baby!

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

>Do it. baby!

Чего ты такой резкий ;-) максимум что требуется от памяти DMA - обеспечить ее когерентность или по крайней мере чтобы политика кеширования для этих страниц была write through, для клинических случаев в ядре предусмотрен механизм dmabounce.

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

Уважаемые коллеги! Проблема разрешилась весьма неожиданным образом. Все исследования кода драйверов на предмет отображения памяти через remap_pfn_range показали, что используемый мною код корректен, тем более он был проверен на другой машине c Core i7. Но при проверке использовался дистрибутив Kubuntu 10.10 с ядром 2.6.35 (x32/x64). На HOST, где были проблемы в отображении блоков данных, был установлен Gentoo Calculate Linux 2.6.35 x64. После того как подцепил винчестер к HOST c Kubuntu все каким то образом заработало на x32/x64. Сейчас устанавливаю Gentoo на HOST чтобы проверить как себя поведет драйвер и ПО с Gentoo ручной сборки. Спасибо.

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

Апдэйт. Проблема была в том, что по умолчанию в ядре Calculate Linux был установлен флаг CONFIG_DMAR_DEFAULT_ON после отключения этой опции проблема исчезла. Нашел причину мой коллега, за что ему спасибо.

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