On Thu, Aug 23, 2012 at 2:30 AM, Haojian Zhuang haojian.zhuang@gmail.com wrote:
Hi all,
I think that we have a memory mapping issue on ION carveout heap for v3.4+ kernel from android.
The scenario is User app + kernel driver (cpu) + kernel driver (dma) that all these three clients will access memory. And the memory is cacheable.
The .map_kernel() of carveout heap remaps the allocated memory buffer by ioremap().
In arm_ioremap(), we don't allow memory to be mapped. In order to make .map_kernel() working, we need to use memblock_alloc() & memblock_remove() to move the heap memory from system to reserved area. So the linear address of the memory buffer is removed from page table. And the new virtual address comes from .map_kernel() while kernel driver wants to access the buffer.
You are correct, there is a bug in map_kernel for the contigious heap -- it's bit rotted a bit as it's not in use on the program I am currently working on. It shouldn't be using ioremap, it should be using vmap for highmem or can just return the mapping for lowmem if appropriate. I will take a patch that fixes this or fix it myself when I get a chance.
But ION use dma_sync_sg_for_devices() to flush cache that means they're using linear address from page. So they're using the NOT-EXISTED virtual address that is removed by memblock_remove().
When I modified ion to use the dma api's I made a conscious decision to stop supporting memory that was removed from the kernel. The benefits of the dma api's outweighed the small cost of having the metadata around in my mind. Memory for contiguous heaps can be put aside using memblock_reserve instead.
Solution #1. .map_kernel() only returns the linear address. And there's a limitation of this solution, the heap should be always lying in low memory. So we needn't use any ioremap() and memblock_remove() any more.
Solution #2. Use vmap() in .map_kernel().
How do you think about these two solutions?
Regards Haojian