Re: [PATCHv7 3/5] common: dma-mapping: Introduce common remapping functions
On Tue, 2014-08-26 at 09:58 -0700, Laura Abbott wrote: > On 8/26/2014 3:05 AM, James Hogan wrote: > > On 12 August 2014 00:40, Laura Abbott wrote: > >> > >> For architectures without coherent DMA, memory for DMA may > >> need to be remapped with coherent attributes. Factor out > >> the the remapping code from arm and put it in a > >> common location to reduce code duplication. > >> > >> As part of this, the arm APIs are now migrated away from > >> ioremap_page_range to the common APIs which use map_vm_area for remapping. > >> This should be an equivalent change and using map_vm_area is more > >> correct as ioremap_page_range is intended to bring in io addresses > >> into the cpu space and not regular kernel managed memory. > >> > >> Reviewed-by: Catalin Marinas > >> Signed-off-by: Laura Abbott > > > > This commit in linux-next () breaks the build for metag: > > > > drivers/base/dma-mapping.c: In function ‘dma_common_contiguous_remap’: > > drivers/base/dma-mapping.c:294: error: implicit declaration of > > function ‘dma_common_pages_remap’ > > drivers/base/dma-mapping.c:294: warning: assignment makes pointer from > > integer without a cast > > drivers/base/dma-mapping.c: At top level: > > drivers/base/dma-mapping.c:308: error: conflicting types for > > ‘dma_common_pages_remap’ > > drivers/base/dma-mapping.c:294: error: previous implicit declaration > > of ‘dma_common_pages_remap’ was here > > > > Looks like metag isn't alone either: > > > > $ git grep -L dma-mapping-common arch/*/include/asm/dma-mapping.h > > arch/arc/include/asm/dma-mapping.h > > arch/avr32/include/asm/dma-mapping.h > > arch/blackfin/include/asm/dma-mapping.h > > arch/c6x/include/asm/dma-mapping.h > > arch/cris/include/asm/dma-mapping.h > > arch/frv/include/asm/dma-mapping.h > > arch/m68k/include/asm/dma-mapping.h > > arch/metag/include/asm/dma-mapping.h > > arch/mn10300/include/asm/dma-mapping.h > > arch/parisc/include/asm/dma-mapping.h > > arch/xtensa/include/asm/dma-mapping.h > > > > I've checked a couple of these arches (blackfin, xtensa) which don't > > include dma-mapping-common.h and their builds seem to be broken too. > > > > Cheers > > James > > > > Thanks for the report. Would you mind giving the following patch > a test (this is theoretical only but I think it should work) There's a further problem with c6x (no MMU): drivers/built-in.o: In function `dma_common_pages_remap': (.text+0x220c4): undefined reference to `get_vm_area_caller' drivers/built-in.o: In function `dma_common_pages_remap': (.text+0x22108): undefined reference to `map_vm_area' drivers/built-in.o: In function `dma_common_free_remap': (.text+0x22278): undefined reference to `find_vm_area' -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCHv7 3/5] common: dma-mapping: Introduce common remapping functions
On 26/08/14 17:58, Laura Abbott wrote: > On 8/26/2014 3:05 AM, James Hogan wrote: >> On 12 August 2014 00:40, Laura Abbott wrote: >>> >>> For architectures without coherent DMA, memory for DMA may >>> need to be remapped with coherent attributes. Factor out >>> the the remapping code from arm and put it in a >>> common location to reduce code duplication. >>> >>> As part of this, the arm APIs are now migrated away from >>> ioremap_page_range to the common APIs which use map_vm_area for remapping. >>> This should be an equivalent change and using map_vm_area is more >>> correct as ioremap_page_range is intended to bring in io addresses >>> into the cpu space and not regular kernel managed memory. >>> >>> Reviewed-by: Catalin Marinas >>> Signed-off-by: Laura Abbott >> >> This commit in linux-next () breaks the build for metag: >> >> drivers/base/dma-mapping.c: In function ‘dma_common_contiguous_remap’: >> drivers/base/dma-mapping.c:294: error: implicit declaration of >> function ‘dma_common_pages_remap’ >> drivers/base/dma-mapping.c:294: warning: assignment makes pointer from >> integer without a cast >> drivers/base/dma-mapping.c: At top level: >> drivers/base/dma-mapping.c:308: error: conflicting types for >> ‘dma_common_pages_remap’ >> drivers/base/dma-mapping.c:294: error: previous implicit declaration >> of ‘dma_common_pages_remap’ was here >> >> Looks like metag isn't alone either: >> >> $ git grep -L dma-mapping-common arch/*/include/asm/dma-mapping.h >> arch/arc/include/asm/dma-mapping.h >> arch/avr32/include/asm/dma-mapping.h >> arch/blackfin/include/asm/dma-mapping.h >> arch/c6x/include/asm/dma-mapping.h >> arch/cris/include/asm/dma-mapping.h >> arch/frv/include/asm/dma-mapping.h >> arch/m68k/include/asm/dma-mapping.h >> arch/metag/include/asm/dma-mapping.h >> arch/mn10300/include/asm/dma-mapping.h >> arch/parisc/include/asm/dma-mapping.h >> arch/xtensa/include/asm/dma-mapping.h >> >> I've checked a couple of these arches (blackfin, xtensa) which don't >> include dma-mapping-common.h and their builds seem to be broken too. >> >> Cheers >> James >> > > Thanks for the report. Would you mind giving the following patch > a test (this is theoretical only but I think it should work) It certainly fixes the build for metag. Thanks James > > -8<-- > > From 81c9a5504cbc1d72ff1df084d48502b248cd79d0 Mon Sep 17 00:00:00 2001 > From: Laura Abbott > Date: Tue, 26 Aug 2014 09:50:49 -0700 > Subject: [PATCH] common: dma-mapping: Swap function order > > Fix the order of dma_common_contiguous_remap and > dma_common_pages_remap to avoid function declaration errors: > > drivers/base/dma-mapping.c: In function 'dma_common_contiguous_remap': > drivers/base/dma-mapping.c:294: error: implicit declaration of > function 'dma_common_pages_remap' > drivers/base/dma-mapping.c:294: warning: assignment makes pointer from > integer without a cast > drivers/base/dma-mapping.c: At top level: > drivers/base/dma-mapping.c:308: error: conflicting types for > 'dma_common_pages_remap' > drivers/base/dma-mapping.c:294: error: previous implicit declaration > of 'dma_common_pages_remap' was here > > Change-Id: I65db739114e8f5816a24a279a2ff1a6dc92e2b83 > Reported-by: James Hogan > Reported-by: kbuild test robot > Signed-off-by: Laura Abbott > --- > drivers/base/dma-mapping.c | 44 ++-- > 1 file changed, 22 insertions(+), 22 deletions(-) > > diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c > index 1bc46df..056fd46 100644 > --- a/drivers/base/dma-mapping.c > +++ b/drivers/base/dma-mapping.c > @@ -271,6 +271,28 @@ int dma_common_mmap(struct device *dev, struct > vm_area_struct *vma, > EXPORT_SYMBOL(dma_common_mmap); > > /* > + * remaps an array of PAGE_SIZE pages into another vm_area > + * Cannot be used in non-sleeping contexts > + */ > +void *dma_common_pages_remap(struct page **pages, size_t size, > + unsigned long vm_flags, pgprot_t prot, > + const void *caller) > +{ > + struct vm_struct *area; > + > + area = get_vm_area_caller(size, vm_flags, caller); > + if (!area) > + return NULL; > + > + if (map_vm_area(area, prot, pages)) { > + vunmap(area->addr); > + return NULL; > + } > + > + return area->addr; > +} > + > +/* > * remaps an allocated contiguous region into another vm_area. > * Cannot be used in non-sleeping contexts > */ > @@ -299,28 +321,6 @@ void *dma_common_contiguous_remap(struct page *page, > size_t size, > } > > /* > - * remaps an array of PAGE_SIZE pages into another vm_area > - * Cannot be used in non-sleeping contexts > - */ > -void *dma_common_pages_remap(struct page **pages, size_t size, > - unsigned long vm_flags, pgprot_t prot, > - const void *caller) > -{ > - struct vm_struct *area; > - > - area = get_vm_area_caller(size, vm_flags, caller); > - if (!area) > - r
Re: [PATCHv7 3/5] common: dma-mapping: Introduce common remapping functions
On 8/26/2014 3:05 AM, James Hogan wrote: > On 12 August 2014 00:40, Laura Abbott wrote: >> >> For architectures without coherent DMA, memory for DMA may >> need to be remapped with coherent attributes. Factor out >> the the remapping code from arm and put it in a >> common location to reduce code duplication. >> >> As part of this, the arm APIs are now migrated away from >> ioremap_page_range to the common APIs which use map_vm_area for remapping. >> This should be an equivalent change and using map_vm_area is more >> correct as ioremap_page_range is intended to bring in io addresses >> into the cpu space and not regular kernel managed memory. >> >> Reviewed-by: Catalin Marinas >> Signed-off-by: Laura Abbott > > This commit in linux-next () breaks the build for metag: > > drivers/base/dma-mapping.c: In function ‘dma_common_contiguous_remap’: > drivers/base/dma-mapping.c:294: error: implicit declaration of > function ‘dma_common_pages_remap’ > drivers/base/dma-mapping.c:294: warning: assignment makes pointer from > integer without a cast > drivers/base/dma-mapping.c: At top level: > drivers/base/dma-mapping.c:308: error: conflicting types for > ‘dma_common_pages_remap’ > drivers/base/dma-mapping.c:294: error: previous implicit declaration > of ‘dma_common_pages_remap’ was here > > Looks like metag isn't alone either: > > $ git grep -L dma-mapping-common arch/*/include/asm/dma-mapping.h > arch/arc/include/asm/dma-mapping.h > arch/avr32/include/asm/dma-mapping.h > arch/blackfin/include/asm/dma-mapping.h > arch/c6x/include/asm/dma-mapping.h > arch/cris/include/asm/dma-mapping.h > arch/frv/include/asm/dma-mapping.h > arch/m68k/include/asm/dma-mapping.h > arch/metag/include/asm/dma-mapping.h > arch/mn10300/include/asm/dma-mapping.h > arch/parisc/include/asm/dma-mapping.h > arch/xtensa/include/asm/dma-mapping.h > > I've checked a couple of these arches (blackfin, xtensa) which don't > include dma-mapping-common.h and their builds seem to be broken too. > > Cheers > James > Thanks for the report. Would you mind giving the following patch a test (this is theoretical only but I think it should work) -8<-- >From 81c9a5504cbc1d72ff1df084d48502b248cd79d0 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Tue, 26 Aug 2014 09:50:49 -0700 Subject: [PATCH] common: dma-mapping: Swap function order Fix the order of dma_common_contiguous_remap and dma_common_pages_remap to avoid function declaration errors: drivers/base/dma-mapping.c: In function 'dma_common_contiguous_remap': drivers/base/dma-mapping.c:294: error: implicit declaration of function 'dma_common_pages_remap' drivers/base/dma-mapping.c:294: warning: assignment makes pointer from integer without a cast drivers/base/dma-mapping.c: At top level: drivers/base/dma-mapping.c:308: error: conflicting types for 'dma_common_pages_remap' drivers/base/dma-mapping.c:294: error: previous implicit declaration of 'dma_common_pages_remap' was here Change-Id: I65db739114e8f5816a24a279a2ff1a6dc92e2b83 Reported-by: James Hogan Reported-by: kbuild test robot Signed-off-by: Laura Abbott --- drivers/base/dma-mapping.c | 44 ++-- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 1bc46df..056fd46 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -271,6 +271,28 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, EXPORT_SYMBOL(dma_common_mmap); /* + * remaps an array of PAGE_SIZE pages into another vm_area + * Cannot be used in non-sleeping contexts + */ +void *dma_common_pages_remap(struct page **pages, size_t size, + unsigned long vm_flags, pgprot_t prot, + const void *caller) +{ + struct vm_struct *area; + + area = get_vm_area_caller(size, vm_flags, caller); + if (!area) + return NULL; + + if (map_vm_area(area, prot, pages)) { + vunmap(area->addr); + return NULL; + } + + return area->addr; +} + +/* * remaps an allocated contiguous region into another vm_area. * Cannot be used in non-sleeping contexts */ @@ -299,28 +321,6 @@ void *dma_common_contiguous_remap(struct page *page, size_t size, } /* - * remaps an array of PAGE_SIZE pages into another vm_area - * Cannot be used in non-sleeping contexts - */ -void *dma_common_pages_remap(struct page **pages, size_t size, - unsigned long vm_flags, pgprot_t prot, - const void *caller) -{ - struct vm_struct *area; - - area = get_vm_area_caller(size, vm_flags, caller); - if (!area) - return NULL; - - if (map_vm_area(area, prot, pages)) { - vunmap(area->addr); - return NULL; - } - - return area->addr; -} - -/* * unmaps a range previously mapped by dma_common_*_remap */ void dma_common_free_remap(void *cp
Re: [PATCHv7 3/5] common: dma-mapping: Introduce common remapping functions
On 12 August 2014 00:40, Laura Abbott wrote: > > For architectures without coherent DMA, memory for DMA may > need to be remapped with coherent attributes. Factor out > the the remapping code from arm and put it in a > common location to reduce code duplication. > > As part of this, the arm APIs are now migrated away from > ioremap_page_range to the common APIs which use map_vm_area for remapping. > This should be an equivalent change and using map_vm_area is more > correct as ioremap_page_range is intended to bring in io addresses > into the cpu space and not regular kernel managed memory. > > Reviewed-by: Catalin Marinas > Signed-off-by: Laura Abbott This commit in linux-next () breaks the build for metag: drivers/base/dma-mapping.c: In function ‘dma_common_contiguous_remap’: drivers/base/dma-mapping.c:294: error: implicit declaration of function ‘dma_common_pages_remap’ drivers/base/dma-mapping.c:294: warning: assignment makes pointer from integer without a cast drivers/base/dma-mapping.c: At top level: drivers/base/dma-mapping.c:308: error: conflicting types for ‘dma_common_pages_remap’ drivers/base/dma-mapping.c:294: error: previous implicit declaration of ‘dma_common_pages_remap’ was here Looks like metag isn't alone either: $ git grep -L dma-mapping-common arch/*/include/asm/dma-mapping.h arch/arc/include/asm/dma-mapping.h arch/avr32/include/asm/dma-mapping.h arch/blackfin/include/asm/dma-mapping.h arch/c6x/include/asm/dma-mapping.h arch/cris/include/asm/dma-mapping.h arch/frv/include/asm/dma-mapping.h arch/m68k/include/asm/dma-mapping.h arch/metag/include/asm/dma-mapping.h arch/mn10300/include/asm/dma-mapping.h arch/parisc/include/asm/dma-mapping.h arch/xtensa/include/asm/dma-mapping.h I've checked a couple of these arches (blackfin, xtensa) which don't include dma-mapping-common.h and their builds seem to be broken too. Cheers James > --- > arch/arm/mm/dma-mapping.c| 57 +- > drivers/base/dma-mapping.c | 68 > > include/asm-generic/dma-mapping-common.h | 9 + > 3 files changed, 86 insertions(+), 48 deletions(-) > > diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c > index 4c88935..f5190ac 100644 > --- a/arch/arm/mm/dma-mapping.c > +++ b/arch/arm/mm/dma-mapping.c > @@ -297,37 +297,19 @@ static void * > __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, > const void *caller) > { > - struct vm_struct *area; > - unsigned long addr; > - > /* > * DMA allocation can be mapped to user space, so lets > * set VM_USERMAP flags too. > */ > - area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, > - caller); > - if (!area) > - return NULL; > - addr = (unsigned long)area->addr; > - area->phys_addr = __pfn_to_phys(page_to_pfn(page)); > - > - if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) { > - vunmap((void *)addr); > - return NULL; > - } > - return (void *)addr; > + return dma_common_contiguous_remap(page, size, > + VM_ARM_DMA_CONSISTENT | VM_USERMAP, > + prot, caller); > } > > static void __dma_free_remap(void *cpu_addr, size_t size) > { > - unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP; > - struct vm_struct *area = find_vm_area(cpu_addr); > - if (!area || (area->flags & flags) != flags) { > - WARN(1, "trying to free invalid coherent area: %p\n", > cpu_addr); > - return; > - } > - unmap_kernel_range((unsigned long)cpu_addr, size); > - vunmap(cpu_addr); > + dma_common_free_remap(cpu_addr, size, > + VM_ARM_DMA_CONSISTENT | VM_USERMAP); > } > > #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K > @@ -1261,29 +1243,8 @@ static void * > __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t > prot, > const void *caller) > { > - unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; > - struct vm_struct *area; > - unsigned long p; > - > - area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, > - caller); > - if (!area) > - return NULL; > - > - area->pages = pages; > - area->nr_pages = nr_pages; > - p = (unsigned long)area->addr; > - > - for (i = 0; i < nr_pages; i++) { > - phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i])); > - if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot)) > - goto err; > - p += PAGE_SIZE; > - } > - return area->addr; > -err: > - unmap_kernel_range((unsigned long)area->addr, size); > - vunmap(area->addr); > + return dma_common_pages_remap(pag
[PATCHv7 3/5] common: dma-mapping: Introduce common remapping functions
For architectures without coherent DMA, memory for DMA may need to be remapped with coherent attributes. Factor out the the remapping code from arm and put it in a common location to reduce code duplication. As part of this, the arm APIs are now migrated away from ioremap_page_range to the common APIs which use map_vm_area for remapping. This should be an equivalent change and using map_vm_area is more correct as ioremap_page_range is intended to bring in io addresses into the cpu space and not regular kernel managed memory. Reviewed-by: Catalin Marinas Signed-off-by: Laura Abbott --- arch/arm/mm/dma-mapping.c| 57 +- drivers/base/dma-mapping.c | 68 include/asm-generic/dma-mapping-common.h | 9 + 3 files changed, 86 insertions(+), 48 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 4c88935..f5190ac 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -297,37 +297,19 @@ static void * __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, const void *caller) { - struct vm_struct *area; - unsigned long addr; - /* * DMA allocation can be mapped to user space, so lets * set VM_USERMAP flags too. */ - area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, - caller); - if (!area) - return NULL; - addr = (unsigned long)area->addr; - area->phys_addr = __pfn_to_phys(page_to_pfn(page)); - - if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) { - vunmap((void *)addr); - return NULL; - } - return (void *)addr; + return dma_common_contiguous_remap(page, size, + VM_ARM_DMA_CONSISTENT | VM_USERMAP, + prot, caller); } static void __dma_free_remap(void *cpu_addr, size_t size) { - unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP; - struct vm_struct *area = find_vm_area(cpu_addr); - if (!area || (area->flags & flags) != flags) { - WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); - return; - } - unmap_kernel_range((unsigned long)cpu_addr, size); - vunmap(cpu_addr); + dma_common_free_remap(cpu_addr, size, + VM_ARM_DMA_CONSISTENT | VM_USERMAP); } #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K @@ -1261,29 +1243,8 @@ static void * __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot, const void *caller) { - unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; - struct vm_struct *area; - unsigned long p; - - area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, - caller); - if (!area) - return NULL; - - area->pages = pages; - area->nr_pages = nr_pages; - p = (unsigned long)area->addr; - - for (i = 0; i < nr_pages; i++) { - phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i])); - if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot)) - goto err; - p += PAGE_SIZE; - } - return area->addr; -err: - unmap_kernel_range((unsigned long)area->addr, size); - vunmap(area->addr); + return dma_common_pages_remap(pages, size, + VM_ARM_DMA_CONSISTENT | VM_USERMAP, prot, caller); return NULL; } @@ -1491,8 +1452,8 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, } if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) { - unmap_kernel_range((unsigned long)cpu_addr, size); - vunmap(cpu_addr); + dma_common_free_remap(cpu_addr, size, + VM_ARM_DMA_CONSISTENT | VM_USERMAP); } __iommu_remove_mapping(dev, handle, size); diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 6cd08e1..1bc46df 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include /* @@ -267,3 +269,69 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } EXPORT_SYMBOL(dma_common_mmap); + +/* + * remaps an allocated contiguous region into another vm_area. + * Cannot be used in non-sleeping contexts + */ + +void *dma_common_contiguous_remap(struct page *page, size_t size, + unsigned long vm_flags, + pgprot_t prot, const void *caller) +{ + int i; + struct page **pages; + void *ptr; + unsigned long pfn; + + pages = kmalloc(sizeof(struct page *) << get_order(size), GFP_KERNEL); + if (!pages) +