Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1353064

Re: [PATCH 1/4] ARM64: dma: Add support for NO_KERNEL_MAPPING attribute

From Robin Murphy <robin.murphy@arm.com>
Newsgroups linux.kernel
Subject Re: [PATCH 1/4] ARM64: dma: Add support for NO_KERNEL_MAPPING attribute
Date 2016-03-08 15:00 +0100
Message-ID <raql4-1Bi-5@gated-at.bofh.it> (permalink)
References <ram7L-7oJ-5@gated-at.bofh.it> <ram7N-7oJ-21@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


On 08/03/16 09:22, Stephen Boyd wrote:
> Both the IOMMU and non-IOMMU allocations don't respect the
> NO_KERNEL_MAPPING attribute, therefore drivers can't save virtual
> address space and time spent mapping large buffers that are
> intended only for userspace. Plumb this attribute into the code
> for both types of DMA ops.

I have to say I'm a little dubious about how much time we save by not 
creating one mapping once, and instead going on to repeatedly create and 
tear down lots of mappings - my initial hunch would place that number 
somewhere below 0. Similarly for the degree of pressure on our hundreds 
of gigabytes of vmalloc space, especially on "memory constrained" systems.

Some real data would be a lot more convincing ;)

Robin.

> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>   arch/arm64/mm/dma-mapping.c | 39 ++++++++++++++++++++++++++++++---------
>   1 file changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 331c4ca6205c..06a593653f23 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -169,6 +169,9 @@ static void *__dma_alloc(struct device *dev, size_t size,
>
>   	/* create a coherent mapping */
>   	page = virt_to_page(ptr);
> +	if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
> +		return page;
> +
>   	coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
>   						   prot, NULL);
>   	if (!coherent_ptr)
> @@ -194,7 +197,8 @@ static void __dma_free(struct device *dev, size_t size,
>   	if (!is_device_dma_coherent(dev)) {
>   		if (__free_from_pool(vaddr, size))
>   			return;
> -		vunmap(vaddr);
> +		if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
> +			vunmap(vaddr);
>   	}
>   	__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
>   }
> @@ -567,6 +571,9 @@ static void *__iommu_alloc_attrs(struct device *dev, size_t size,
>   		if (!pages)
>   			return NULL;
>
> +		if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
> +			return pages;
> +
>   		addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
>   					      __builtin_return_address(0));
>   		if (!addr)
> @@ -624,18 +631,32 @@ static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
>   		if (WARN_ON(!area || !area->pages))
>   			return;
>   		iommu_dma_free(dev, area->pages, iosize, &handle);
> -		dma_common_free_remap(cpu_addr, size, VM_USERMAP);
> +		if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
> +			dma_common_free_remap(cpu_addr, size, VM_USERMAP);
>   	} else {
>   		iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
>   		__free_pages(virt_to_page(cpu_addr), get_order(size));
>   	}
>   }
>
> +static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
> +{
> +	struct vm_struct *area;
> +
> +	if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
> +		return cpu_addr;
> +
> +	area = find_vm_area(cpu_addr);
> +	if (area)
> +		return area->pages;
> +	return NULL;
> +}
> +
>   static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   			      void *cpu_addr, dma_addr_t dma_addr, size_t size,
>   			      struct dma_attrs *attrs)
>   {
> -	struct vm_struct *area;
> +	struct page **pages;
>   	int ret;
>
>   	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
> @@ -644,11 +665,11 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   	if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
>   		return ret;
>
> -	area = find_vm_area(cpu_addr);
> -	if (WARN_ON(!area || !area->pages))
> +	pages = __iommu_get_pages(cpu_addr, attrs);
> +	if (WARN_ON(!pages))
>   		return -ENXIO;
>
> -	return iommu_dma_mmap(area->pages, size, vma);
> +	return iommu_dma_mmap(pages, size, vma);
>   }
>
>   static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
> @@ -656,12 +677,12 @@ static int __iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
>   			       size_t size, struct dma_attrs *attrs)
>   {
>   	unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
> -	struct vm_struct *area = find_vm_area(cpu_addr);
> +	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
>
> -	if (WARN_ON(!area || !area->pages))
> +	if (WARN_ON(!pages))
>   		return -ENXIO;
>
> -	return sg_alloc_table_from_pages(sgt, area->pages, count, 0, size,
> +	return sg_alloc_table_from_pages(sgt, pages, count, 0, size,
>   					 GFP_KERNEL);
>   }
>
>

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[RFC/PATCH 0/4] request_firmware() on memory constrained devices Stephen Boyd <stephen.boyd@linaro.org> - 2016-03-08 10:30 +0100
  [RFC/PATCH 4/4] firmware: Support requesting firmware directly into DMA memory Stephen Boyd <stephen.boyd@linaro.org> - 2016-03-08 10:30 +0100
    Re: [RFC/PATCH 4/4] firmware: Support requesting firmware directly  into DMA memory Mimi Zohar <zohar@linux.vnet.ibm.com> - 2016-03-08 13:10 +0100
    Re: [RFC/PATCH 4/4] firmware: Support requesting firmware directly  into DMA memory Ming Lei <tom.leiming@gmail.com> - 2016-03-08 14:50 +0100
      Re: [RFC/PATCH 4/4] firmware: Support requesting firmware directly  into DMA memory Mark Brown <broonie@kernel.org> - 2016-03-09 03:30 +0100
  [PATCH 1/4] ARM64: dma: Add support for NO_KERNEL_MAPPING attribute Stephen Boyd <stephen.boyd@linaro.org> - 2016-03-08 10:30 +0100
    Re: [PATCH 1/4] ARM64: dma: Add support for NO_KERNEL_MAPPING  attribute Robin Murphy <robin.murphy@arm.com> - 2016-03-08 15:00 +0100
  [RFC/PATCH 2/4] dma-mapping: Add dma_remap() APIs Stephen Boyd <stephen.boyd@linaro.org> - 2016-03-08 10:30 +0100
  [RFC/PATCH 3/4] firmware_class: Provide infrastructure to make fw caching optional Stephen Boyd <stephen.boyd@linaro.org> - 2016-03-08 10:30 +0100
  Re: [RFC/PATCH 0/4] request_firmware() on memory constrained devices Alexander Stein <alexander.stein@systec-electronic.com> - 2016-03-08 10:40 +0100
    Re: [RFC/PATCH 0/4] request_firmware() on memory constrained devices Stephen Boyd <stephen.boyd@linaro.org> - 2016-03-08 11:10 +0100

csiph-web