Desidero allocare un buffer DMA di grandi dimensioni, con una dimensione di circa 40 MB. Quando uso dma_alloc_coherent()
, non riesce e quello che vedo è:Allocazione di un buffer DMA di grandi dimensioni
------------[ 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 ]---
Ho provato diversi valori e sembra che dma_alloc_coherent()
non può allocare più di 2^25 byte (32 MB).
In che modo è possibile allocare un buffer DMA così grande?
grandi buffer DMA sono costosi. Il blocco di memoria deve essere una memoria fisica contigua (a meno che non vi sia una MMU per I/O come in alcuni sistemi SPARC) e bloccata (non può essere sfogliata per fare spazio per gli errori di pagina da attività con priorità più alta). Soluzione tipica consiste nell'utilizzare più di un buffer DMA e utilizzare il concatenamento DMA (ovvero scatter/gather). Avete davvero un'operazione di I/O che trasferisce 40 MB in un blocco, o si tratta davvero di un accumulo di operazioni? – sawdust
Il caso d'uso del software su cui sto lavorando richiede grandi buffer DMA per l'acquisizione di video e l'elaborazione di immagini da parte di hardware specializzato. Può essere fatto usando diversi buffer più piccoli, ma nel tempo la frammentazione rende problematici i processi di liberazione e riallocazione dei buffer. La dimensione e la quantità dei buffer DMA di cui ho bisogno sono fisse, quindi voglio allocare la memoria una volta all'avvio e gestire le richieste di memoria nello spazio utente. – miluz
@miluz, hai risolto questo problema? Come ? – ransh