We have more than enough CMA. Only a little over half is used. There is over 100 MB CMA free.
Can you look at the code? In gc_hal_kernel_allocator_cma:CMAFSLAlloctorInit()
allocator->capability = gcvALLOC_FLAG_CONTIGUOUS
| gcvALLOC_FLAG_DMABUF_EXPORTABLE;
The CMA allocator cannot allocate NON_CONTIGUOUS memory.
USE_KERNEL_VIRTUAL_BUFFERS is explicitly set in gc_hal_options.h:
#ifndef USE_KERNEL_VIRTUAL_BUFFERS
#if defined(UNDER_CE)
# define USE_KERNEL_VIRTUAL_BUFFERS 1
#else
# define USE_KERNEL_VIRTUAL_BUFFERS 1
#endif
#endif
This results in:
gckCOMMAND_Construct()->gckKERNEL_AllocateVirtualCommandBuffer()
Where the flag is set to gcvALLOC_FLAG_NON_CONTIGUOUS, and the GFP is used instead because the CMA is not configured to allocate NON_CONTIGUOUS memory. I expect it may be a bad idea to allocate the command objects from CMA anyway, due to potential fragmentation from many smaller allocations. Not 100% sure on this though.
This is not the real issue, however. The CMA allocator explicitly flushes the caches in _CMAFSLMapUser(), which seems unnecessary altogether. It is this cache flush that takes extraordinarily long, and seems like it should just be removed:
gc_hal_kernel_allocator_cma.c:
if (gcmIS_SUCCESS(status)) {
gcmkONERROR(gckOS_CacheFlush(
Allocator->os,
_GetProcessID(),
Mdl,
gcvINVALID_ADDRESS,
userLogical,
Mdl->numPages * PAGE_SIZE
));
*UserLogical = userLogical;
}
What is the reason for the above call to gckOS_CacheFlush()?