[PATCHv2 2/4] mm: cma: Contiguous Memory Allocator added

Russell King - ARM Linux linux at arm.linux.org.uk
Tue Jul 27 08:08:41 EDT 2010


On Mon, Jul 26, 2010 at 04:40:30PM +0200, Michal Nazarewicz wrote:
> +** Why is it needed?
> +
> +    Various devices on embedded systems have no scatter-getter and/or
> +    IO map support and as such require contiguous blocks of memory to
> +    operate.  They include devices such as cameras, hardware video
> +    decoders and encoders, etc.

Yes, this is becoming quite a big problem - and many ARM SoCs suffer
from the existing memory allocators being extremely inadequate for
their use.

One of the areas I've been working on is sorting out the DMA coherent
allocator so we don't violate the architecture requirements for ARMv6
and ARMv7 CPUs (which basically prohibits multiple mappings of memory
with different attributes.)

One of the ideas that I've thought about for this is to reserve an
amount of contiguous memory at boot time to fill the entire DMA coherent
mapping, marking the memory in the main kernel memory map as 'no access',
and allocate directly from the DMA coherent region.

However, discussing this with people who have the problem you're trying
to solve indicates that they do not want to set aside an amount of
memory as they perceive this to be a waste of resources.

This concern also applies to 'cma'.

> +/*
> + * Don't call it directly, use cma_alloc(), cma_alloc_from() or
> + * cma_alloc_from_region().
> + */
> +dma_addr_t __must_check
> +__cma_alloc(const struct device *dev, const char *kind,
> +	    size_t size, dma_addr_t alignment);

Does this really always return DMA-able memory (memory which can be
DMA'd to/from without DMA-mapping etc?)

As it returns a dma_addr_t, it's returning a cookie for the memory which
will be suitable for writing directly to the device 'dev' doing the DMA.
(NB: DMA addresses may not be the same as physical addresses, especially
if the device is on a downstream bus.  We have ARM platforms which have
different bus offsets.)

How does one obtain the CPU address of this memory in order for the CPU
to access it?

> +static inline dma_addr_t __must_check
> +cma_alloc(const struct device *dev, const char *kind,
> +	  size_t size, dma_addr_t alignment)
> +{
> +	return dev ? -EINVAL : __cma_alloc(dev, kind, size, alignment);

So I can't use this to allocate memory for anything but a NULL device?

> +static inline int
> +cma_info(struct cma_info *info, const struct device *dev, const char *kind)
> +{
> +	return dev ? -EINVAL : __cma_info(info, dev, kind);

This won't return information for anything but a NULL device?



More information about the linux-arm-kernel mailing list