Large Coherent DMA blocks

I’m having trouble with a iarge DMA allocation I have to do in my driver. As part of a video driver, I need to allocate a few 4Meg regions. The first works fine, but the rest fail.

I tried editing my .config to raise the CONFIG_FORCE_MAX_ZONEORDER to 12, but that didn’t seem to help much.

Anyone with any other ideas?

Hard to say anything without knowing how “fail” is determined. I assume there was some sort of allocation in a kernel module (not userspace?) which returned something for failure? What was the function call and what was the return?

AFAIK, there’s no real error code that comes from it…

Kernel code:

dev->vaddr[0] = dma_alloc_coherent(busdev, VIDEO_DMA_BLOCKSIZE * VIDEO_BUFFERS,
        &dev->dma_addr[0], GFP_KERNEL);
  if(!dev->vaddr[0]) {
    dev_err(busdev, "(%d/1) failed to allocate coherent DMA buffer of %d bytes (%d bytes, %d buffers)\n",
          inst, VIDEO_DMA_BLOCKSIZE * VIDEO_BUFFERS, VIDEO_DMA_BLOCKSIZE, VIDEO_BUFFERS);
    ret = -ENOMEM;
    goto free_dev;
  }

And dmesg result:

[ 4264.491302] mydriver 0000:01:00.0: (1/1) failed to allocate coherent DMA buffer of 4112384 bytes (1028096 bytes, 4 buffers)

I just get back a null pointer… Is there any way to get more info?

I am wondering…

What is the exact type of dma_addr (I assume it is unsigned 32 bit because I’m assuming memory space on busdev addressing is 32 bit)?

Have you tried with GFP_DMA?

have you tried to increase the CMA area size? i.e. increase CONFIG_CMA_SIZE_MBYTES to e.g. 32,
and maybe increase CONFIG_CMA_AREAS by one so you can have your own.

as far as I understand the ARM dma_alloc_coherent logic, it first tries to satisfy this request
from the CMA areas IF they exist and if they have enough space. If not, it tries the “standard”
way which will almost always fail with megabyte-sized blocks when userspace is up.

I solved similar problems passing the parameters “vmalloc=512M cma=64M coherent_pool=32M” to kernel. I’m not sure if that is the correct/best way to do it though.

@linuxdev : that didn’t work…

[  294.702771] ERROR: 256 KiB atomic DMA coherent pool is too small!
[  294.702771] Please increase it with coherent_pool= kernel parameter!
[  294.715372] mlvcm 0000:01:00.0: (0/0) failed to allocate coherent DMA buffer of 4112384 bytes (1028096 bytes, 4 buffers)

Rebuilding with CONFIG_CMA_SIZE_MBYTES to 32… I’ll post results soon…

That got it! Raising the CONFIG_CMA_SIZE_MBYTES to 32 got it working! Thanks for all the help guys.

I added option “vmalloc=512M cma=64M coherent_pool=32M” to /boot/extlinux/extlinux.conf .It’s worked in TX1!