How to allocate large DMA memory

I am developing a pci device driver using Jetson Tx2.
I want to be allocated large DMA memory (at least 10MB).
However, the maximum size of DMA memory allocated now is 512kB. (use pci_alloc_consistent function)
How do I allocate large DMA memory?

Should I use CMA memory?
If I need to use CMA memory, how should I use it?
I read https://lwn.net/Articles/486301/ but I am not sure what to do.

Please help me
Thank you.

how much memory you can allocate is depends on current state of system. if system has free contiguous memory available pci_alloc_consistent can also return success

you can try dma_alloc_coherent API as well to allocate memory for DMA operation

pci_alloc_consistent is a dma_alloc_coherent using GFP_AUTOMIC flag.
If I use dma_alloc_coherent instead of pci_alloc_consistent function, should I use the GFP_DMA flag?

And currently my system memory is using 6144 MB out of the total 7852 MB. It is difficult to understand that among the 6144 MBs, only 512 KB of contiguous memory is allocated.

You can use GFP_KERNEL as well.

GFP_AUTOMIC: Unconditionally allocates if the kernel has allocable memory and null if not.
GFP_KERNEL: If there is not enough memory, the process falls asleep, otherwise it allocates memory.

When using the GFP_KERNEL flag in the dma_alloc_coherent function, I was able to allocate more than 10MB of memory.
However, when using GFP_ATOMIC, more than 10MB of memory is not allocated.
The allocation in GFP_KERNEL means that there is enough contiguous memory. Why is GFP_AUTOMIC not allocated more than 10MB of memory?

And can I use dma_alloc_coherent instead of pci_alloc_consistent to use pci devices?

GFP_AUTOMIC and GFP_KERNEL comes for from different pool of memory. GFP_KERNEL definitely has longer range. GFP_AUTOMIC should be only use in interrupt context.

And can I use dma_alloc_coherent instead of pci_alloc_consistent to use pci devices?
yes

1 Like

GFP_AUTOMIC should be only use in interrupt context.

What does it mean to only use it in interrupt context?

irqreturn_t interruptFunc(int irq, void* dev_id)
{
VirtAddr = dma_alloc_coherent(dev, memsize, PhyAddr, GFP_AUTOMIC); ->o
VirtAddr = dma_alloc_coherent(dev, memsize, PhyAddr, GFP_KERNEL); -> x
}

Are you saying that I should not use GFP_KERNEL when assigning DMA memory in interruptFunc, but GFP_AUTOMIC?