Chcę przydzielić duży bufor DMA o rozmiarze około 40 MB. Gdy używam dma_alloc_coherent()
, że nie powiedzie się i co widzę to:Przydzielanie dużego bufora DMA
------------[ cut here ]------------
WARNING: at mm/page_alloc.c:2106 __alloc_pages_nodemask+0x1dc/0x788()
Modules linked in:
[<8004799c>] (unwind_backtrace+0x0/0xf8) from [<80078ae4>] (warn_slowpath_common+0x4c/0x64)
[<80078ae4>] (warn_slowpath_common+0x4c/0x64) from [<80078b18>] (warn_slowpath_null+0x1c/0x24)
[<80078b18>] (warn_slowpath_null+0x1c/0x24) from [<800dfbd0>] (__alloc_pages_nodemask+0x1dc/0x788)
[<800dfbd0>] (__alloc_pages_nodemask+0x1dc/0x788) from [<8004a880>] (__dma_alloc+0xa4/0x2fc)
[<8004a880>] (__dma_alloc+0xa4/0x2fc) from [<8004b0b4>] (dma_alloc_coherent+0x54/0x60)
[<8004b0b4>] (dma_alloc_coherent+0x54/0x60) from [<803ced70>] (mxc_ipu_ioctl+0x270/0x3ec)
[<803ced70>] (mxc_ipu_ioctl+0x270/0x3ec) from [<80123b78>] (do_vfs_ioctl+0x80/0x54c)
[<80123b78>] (do_vfs_ioctl+0x80/0x54c) from [<8012407c>] (sys_ioctl+0x38/0x5c)
[<8012407c>] (sys_ioctl+0x38/0x5c) from [<80041f80>] (ret_fast_syscall+0x0/0x30)
---[ end trace 4e0c10ffc7ffc0d8 ]---
Próbowałem różnych wartości i wygląda dma_alloc_coherent()
nie może przeznaczyć więcej niż 2^25 bajtów (32 MB).
W jaki sposób można przydzielić tak duży bufor DMA?
Duże bufory DMA są drogie. Blok pamięci musi być przyległą pamięcią fizyczną (chyba że istnieje MMU dla I/O, jak w niektórych systemach SPARC) i zablokowany (nie może być stronicowany, aby zrobić miejsce na błędy strony przez zadania o wyższym priorytecie). Typowym obejściem jest użycie więcej niż jednego bufora DMA i wykorzystanie łańcucha DMA (inaczej rozpraszanie/zbieranie). Czy naprawdę masz operację We/Wy, która przesyła 40 MB w jednym bloku, czy to naprawdę nagromadzenie operacji? – sawdust
Używanie oprogramowania, nad którym pracuję, wymaga dużych buforów DMA do przechwytywania wideo i przetwarzania obrazu przez wyspecjalizowany sprzęt. Można tego dokonać za pomocą kilku mniejszych buforów, ale z czasem fragmentacja sprawia, że uwalnianie i ponowne przydzielanie buforów jest problematyczne. Rozmiar i ilość buforów DMA, których potrzebuję, jest poprawiona, więc chcę przydzielić pamięć raz podczas rozruchu i zarządzać żądaniami pamięci w przestrzeni użytkownika. – miluz
@miluz, rozwiązałeś ten problem? w jaki sposób ? – ransh