Description:
I am writing a kernel driver that requires contiguous memory allocated from the CMA (Contiguous Memory Allocator) region. I have configured the CMA region in the device tree and set the DMA mask correctly in my driver using dma_set_mask_and_coherent(), but I am observing unexpected allocation behavior between two DMA allocation APIs.
Observed behavior:
-
dma_alloc_coherent()— allocates memory from normal RAM, completely ignoring the CMA region, even though the DMA mask is set , cma memory defined in kernel arg cma=512m -
dma_alloc_noncoherent()— correctly allocates memory from the CMA region as expected.
Questions:
-
Why does
dma_alloc_coherentbypass the CMA region on aarch64/Tegra even when the DMA mask and device tree memory region are configured correctly? Is this a known limitation of the Tegra DMA ops implementation? -
Is there a way to force
dma_alloc_coherentto allocate from CMA on the Jetson platform, or isdma_alloc_noncoherentwith manual cache synchronization the only supported path for CMA-backed DMA buffers? -
Are there any Tegra-specific kernel configurations or device tree properties required to make
dma_alloc_coherentuse the CMA pool?
My current setup:
c
/* DMA mask setup in probe */
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
/* This does NOT allocate from CMA */
vaddr = dma_alloc_coherent(dev, size, &dma_handle, GFP_KERNEL);
/* This DOES allocate from CMA */
vaddr = dma_alloc_noncoherent(dev, size, &dma_handle,
DMA_BIDIRECTIONAL, GFP_KERNEL);