Использование статических структур данных для прямого доступа к памяти - PullRequest
3 голосов
/ 03 декабря 2009

У меня был драйвер для ядра Linux (2.6.18), в котором я использовал kmalloc (sizeof (my_struct_t), GFP_ATOMIC) для выделения памяти, которая позже использовалась для передачи данных с использованием контроллера DMA какого-либо устройства. Позже мне пришлось увеличить размер my_struct. Он стал слишком большим, поэтому код kmalloc () использовал статическое утверждение и скомпилировал символ __you_cannot_kmalloc_that_much для уведомления о том, что фрагменты памяти слишком велики для размещения. Поэтому я подумал, что я объявлю my_struct_t как статическую переменную, и его вообще не нужно будет выделять.

я определил статическая my_struct_t my_struct;

но транзакция DMA не сработала, и я получил недействительные данные DMA'd в буфер.

Мой вопрос: запрещено использовать статические (глобальные) буферы для dma? И если да, то где именно в карте памяти ядра находятся эти буферы.

Спасибо

Ответы [ 2 ]

2 голосов
/ 04 декабря 2009

Обычно вы не можете использовать старую память и использовать ее для прямого доступа к памяти. Проблема в том, что ваша область памяти может пересекать границы страниц и разделяться на различные области физической памяти. Кроме того, он может быть заменен, а затем снова переключен в другое физическое местоположение, чем раньше. На некоторых архитектурах есть области памяти, которые вообще не видны с шины устройства. Иногда вам может повезти, что ваши неправильно приобретенные буферы DMA работают, но это не гарантировано.

Проверьте функции распределения dma, такие как dma_alloc_coherent(). Также LDD3 Глава 15.

Если у вас есть проблемы с распределением буферов DMA, потому что они слишком велики, у вас есть еще одна проблема, требующая, чтобы вы либо разделили свои передачи DMA вручную, либо использовали DMA с разбросом сбора.

2 голосов
/ 03 декабря 2009

Проблема будет в том, что если вы выделяете память в стеке, вы не можете гарантировать, что память находится в непрерывном физическом блоке памяти. Если это не так, вы не можете DMA это.

Не проще ли разбить передачу DMA на несколько блоков, которые вы МОЖЕТЕ kmalloc? Затем вы можете отправлять n передач DMA вместо одного. Это будет иметь незначительную разницу в использовании вашей шины и будет работать, в отличие от текущей проблемы.

...