On Fri, Aug 20, 2010 at 11:50:42AM +0200, Michal Nazarewicz wrote:The Contiguous Memory Allocator framework is a set of APIs for
allocating physically contiguous chunks of memory.
Various chips require contiguous blocks of memory to operate. Those
chips include devices such as cameras, hardware video decoders and
encoders, etc.
I am not that familiar with how StrongARM works, and I took a bit look
at the arch/arm/mach-s* and then some of the
drivers/video/media/video/cx88 to get an idea how the hardware video
decoders would work this.
What I got from this patch review is that you are writting an IOMMU
that is on steroids. It essentially knows that this device and that
device can both share the same region, and it has fancy plugin system
to deal with fragmentation and offers an simple API for other to
write their own "allocators".
Even better, during init, the sub-platform can use
cma_early_regions_reserve(<func>) to register their own function
for reserving large regions of memory. Which from my experience (with
Xen) means that there is a mechanism in place to have it setup
contingous regions using sub-platform code.
This is how I think it works, but I am not sure if I got it right. From
looking at 'cma_alloc' and 'cma_alloc_from_region' - both return
an dma_addr_t, which is what is usually feed in the DMA API. And looking
at the cx88 driver I see it using that API..
I do understand that under ARM platform you might not have a need for
DMA at all, and you use the 'dma_addr_t' just as handles, but for
other platforms this would be used.
So here is the bit where I am confused. Why not have this
as Software IOMMU that would utilize the IOMMU API? There would be some
technical questions to be answered (such as, what to do when you have
another IOMMU and can you stack them on top of each other).
A light review below:
+ * cma_alloc_from - allocates contiguous chunk of memory from named regions.
+ * @regions: Comma separated list of region names. Terminated by NUL
I think you mean 'NULL'
+ * byte or a semicolon.
Uh, really? Why? Why not just simplify your life and make it \0?
+ * The cma_allocator::alloc() operation need to set only the @start^^- C++, eh?
[...]+int __init cma_early_region_reserve(struct cma_region *reg)
+{
[...]+#ifndef CONFIG_NO_BOOTMEM
[...]+#endif
+
+#ifdef CONFIG_HAVE_MEMBLOCK
+#endif
Those two #ifdefs are pretty ugly. What if you defined in a header
something along this:
#ifdef CONFIG_HAVE_MEMBLOCK
int __init default_early_region_reserve(struct cma_region *reg) {
.. do it using memblock
}
#endif
#ifdef CONFIG_NO_BOOTMEM
int __init default_early_region_reserve(struct cma_region *reg) {
.. do it using bootmem
}
#endif
and you would cut the API by one function, the
cma_early_regions_reserve(struct cma_region *reg)