[review] ARM: dma-mapping: Add support DMA allocate memory without mapping

Arnd Bergmann arnd at arndb.de
Thu May 15 12:42:12 PDT 2014


On Thursday 15 May 2014 15:19:28 albuer wrote:
> Dear all:
> 
> ARM: dma-mapping: Add support DMA allocate memory without mapping
> 
> reserved DMA(CMA) regions may be large than 512MB for devices, placed it
> in the highmem zone is appropriate, but according to the existing
> mechanism, memory allocation with mapping will cause vmalloc area not
> enough.
> 
> Now we don't do mapping if the DMA_ATTR_NO_KERNEL_MAPPING is set.
>
> the DMA(CMA) region used for VPU/VOP/Camera/RGA etc, my screen
> resolution: 2560*1600, we need CMA memory large than 768MB.
> 

Please follow the normal submission procedure as documented in
Documentation/SubmittingPatches, and put the patch inline rather
than an attachment.

I've pasted the patch below for review.

 
> +static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t
> prot); +

Style: better move the inline function here to avoid the forward declaration.

>  static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t
>  gfp,
> 
> -				 pgprot_t prot, struct page **ret_page,
> +				 struct dma_attrs *attrs, struct page **ret_page,
> 
>  				 const void *caller)
>  
>  {
>  
>  	struct page *page;
>  	void *ptr;
> 
> +	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
> 
>  	page = __dma_alloc_buffer(dev, size, gfp);
>  	if (!page)
>  	
>  		return NULL;
> 
> +	if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
> +		return (*ret_page=page);
> +
> 
>  	ptr = __dma_alloc_remap(page, size, gfp, prot, caller);
>  	if (!ptr) {
>  	
>  		__dma_free_buffer(page, size);
> 

Hmm, so if we don't want a mapping, the function returns a pointer
to the struct page rather than to the virtual address?

This sounds like it will do the right thing, but it's also a
very confusing interface. Maybe somebody can think of a better
return value.

We do have a similarly confusing case for the existing __iommu_get_pages
function:

static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
{
        struct vm_struct *area;

        if (__in_atomic_pool(cpu_addr, PAGE_SIZE))
                return __atomic_get_pages(cpu_addr);

        if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
                return cpu_addr;

        area = find_vm_area(cpu_addr);
        if (area && (area->flags & VM_ARM_DMA_CONSISTENT))
                return area->pages;
        return NULL;
}

This either returns 'cpu_addr' directly, or a pointer to the pages. I have
no idea how this can work right, but I may be missing something subtle.

	Arnd




More information about the linux-arm-kernel mailing list