Unable to free CMA memory used via BO created SCANOUT flag if it was mapped with GBM_BO_MAP
- OS: ARM32 Linux 5.7.10 on STM32MP157 using Buildroot
- GPU: Vivante GC400
- Kernel version: 5.7.10
- Mesa version: 23.1.4
- Desktop manager and compositor: None - straight OpenGL ES2 similar to and inspired by kmscube
Describe the issue
After a typical creation of a BO object which allocates from CMA:
bo = gbm_bo_create(gbm.dev,
1024, 768,
GBM_FORMAT_RGB565,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
Followed by something like:
FRAMEBUFFER1 = gbm_bo_map(bo, 0, 0, 1024, 768, GBM_BO_TRANSFER_READ_WRITE, &stride, &map_data1); .... gbm_bo_unmap(bo,map_data1);
results in the allocated CMA memory area not being freed on application termination or any attempt to destroy the BO (such as with GBM_BO_DESTROY()). This results in a massive memory leak.
If GBM_BO_USE_SCANOUT flag is not used then the buffer can be deallocated as expected but CMA memory may not have been allocated as a contiguous block.
The problem also applies to BO objects not used as rendering buffers such as:
videobuffer = gbm_bo_create(gbm.dev, 360, 625*3, GBM_FORMAT_ABGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR);
GBM_BO_USE_SCANOUT needs to be used here as using only GBM_BO_USE_LINEAR still results in fragmented memory allocation (but solves the problem of the memory leak).
The issue can easily be observed using kmscube sightly modified to add the gbm_bo_map (or add the GBM_BO_USE_SCANOUT flag to the argb texture example which uses gbm_bo_map) and observe declining CMA memory using # cat /proc/meminfo after every run (increase size of memory allocation for texture BO to make it more dramatic).
Background: I need user space mapped addresses of the display framebuffers for post OpenGL rendering access. I worked around the above problem by avoiding the use of gbm_bo_map by interrogating the actual buffer address set in the LCD interface peripheral which contains the physical address of the current displaying framebuffer and then do a simple mmap() but so far have not figured out how to obtain the physical address of a BO once allocated by sane means (I use gbm_bo_map followed by virtual to physical translation to get the actual physical address needed for the hardware). So for my case I need a video streaming buffer which works great using the above but still have a significant memory leak for this one.
Alternate DMA-Buf mmap via FD has a limitation that PROT_WRITE cannot be used - so user space mmap is restricted to read-only access. Not sure there are valid reasons for this limitation.