Inconsistent dma_alloc_coherent fail issue

Hi,

I am facing an issue while capturing images of size 4224 X 3156 via via ioctl VIDIOC_REQBUFS call.

I have gone through an similar thread given below.

https://devtalk.nvidia.com/default/topic/922871/not-able-to-allocate-more-than-8-v4l2-buffers/?offset=11

But my case is bit different.

I am getting below dmesg alone.

[ 78.615564] vi vi.0: dma_alloc_coherent of size 13332480 failed

Please note, “vmap allocation for size xxxxx failed: use vmalloc= to increase size” is not coming in this case, unlike above mentioned thread.

  1. Also this is inconsistent.Able to save images sometimes.
  2. I checked cat /proc/meminfo. Its having enough vmalloc memory, VmallocChunk.
  3. I also checked by increasing the vmalloc=256M, vmalloc=512M and even vmalloc=768M. But no success.

When I set vmalloc=188M, then only below debug message appears and this goes with the above mentioned thread.

[ 78.605587] vmap allocation for size 13336576 failed459gg: use vmalloc= to increase size.
[ 78.615564] vi vi.0: dma_alloc_coherent of size 13332480 failed

This I can solve by increasing vmalloc=256M (also other higher value).

##############################################################

But yet, Inconsistently, “vi vi.0: dma_alloc_coherent of size 13332480 failed” issue is happening for me.

From my observation, it seems, increasing “vmalloc” has no effect for this issue.

Can anyone help me why I am getting this issue while capturing image of 4224 X 3156 ? Lower resolution does not create this issue.

Regards,
Gopinath S

When it does this, what is the complete output of “cat /proc/meminfo”?

MemTotal: 1837764 kB
MemFree: 904628 kB
Buffers: 8760 kB
Cached: 255200 kB
SwapCached: 0 kB
Active: 300092 kB
Inactive: 207772 kB
Active(anon): 243972 kB
Inactive(anon): 13564 kB
Active(file): 56120 kB
Inactive(file): 194208 kB
Unevictable: 1036 kB
Mlocked: 1036 kB
HighTotal: 1099776 kB
HighFree: 242728 kB
LowTotal: 737988 kB
LowFree: 661900 kB
SwapTotal: 520908 kB
SwapFree: 520908 kB
Dirty: 48 kB
Writeback: 0 kB
AnonPages: 245032 kB
Mapped: 134424 kB
Shmem: 13652 kB
Slab: 32464 kB
SReclaimable: 10848 kB
SUnreclaim: 21616 kB
KernelStack: 5536 kB
PageTables: 8876 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 1439788 kB
Committed_AS: 31712744 kB
VmallocTotal: 253952 kB
VmallocUsed: 136256 kB
VmallocChunk: 43772 kB
NvMapMemFree: 33584 kB
NvMapMemUsed: 309744 kB

This is the complete output.

vmalloc only requires returning virtually contiguous memory; dma_alloc_coherent has other restrictions to make the memory safe for direct write by either CPU or a device, including physically contiguous memory and certain behavior relative to caching.

From what I’ve researched the gist of the issue is that as the system runs and physical memory is allocated and released by whatever is going on physical memory addressing becomes fragmented (smaller pieces spread out in address range versus a single or just a few pieces of larger contiguous memory). There may be enough physically contiguous memory early on for the allocation to succeed, but later the allocation would fail even if the same total memory is free.

Trying to re-consolidate fragmented memory does not seem practical…I saw reports of custom programming to exclude given memory regions from kernel use at boot time, and then coding the specific driver to gain access to that memory as a way to guarantee the memory required is not fragmented. Unless the driver itself is coded to do that it seems perhaps the best way of getting that memory is to use the memory via the driver at boot time and not letting go of the memory until the program exits.

I do not know anything about the specific driver involved, but if this has been an issue in the past then there may be a kernel command line argument to reserve physically contiguous space at boot. The vmalloc was a good example of this, as it also has a kernel command line parameter capable of reserving more memory right at the start of boot. The driver behind the IOCTL would have to be researched to know if this is possible.

Thanks for the reply.

I guess, you are taking about MemTotal: 1837764 kB and MemFree: 904628 kB.

Even though we have 904.628 MB of free physical memory, its memory addressing may not be contiguous. So Is there any parameter like VmallocChunk in case of vmall which gives reserved physically contiguous memory?

Here is an another update about this issue.

I just added one recovery attempt to allocate it again after first failure (vi vi.0: dma_alloc_coherent of size 13332480 failed). below are the observations.

  1. Sometimes VIDIOC_REQBUFS failed in first attempt but on immediate call again, it is succeeded.

2.In some cases, both the two attempts failed.

In this way I can reduce the occurrence of this issue a bit. But It does not fix this issue. Any ideas/comments on the first case??

Physical address memory fragmentation is not predictable…there may be a way to reserve what you need before something grabs on to it, but I don’t know how exactly to do this (you could modify the driver to immediately allocate that memory and make sure it loads very early on in boot prior to fragmentation).

Reducing the occurrence is not really a fix. All kinds of programs and system software will randomly allocate and de-allocate memory over time, and there is nothing to stop the allocations from stepping on some memory location which would further reduce the amount of physically contiguous memory. But…fewer programs running, and lower memory use in general would imply less fragmentation. I’ve never heard of a memory defragmentation feature, but perhaps one exists that I don’t know about.