Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1174770 > unrolled thread
| Started by | Lorenzo Nava <lorenx4@gmail.com> |
|---|---|
| First post | 2015-06-30 23:30 +0200 |
| Last post | 2015-07-03 12:30 +0200 |
| Articles | 2 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v5] arm DMA: Fix allocation from CMA for coherent DMA Lorenzo Nava <lorenx4@gmail.com> - 2015-06-30 23:30 +0200
Re: [PATCH v5] arm DMA: Fix allocation from CMA for coherent DMA Catalin Marinas <catalin.marinas@arm.com> - 2015-07-03 12:30 +0200
| From | Lorenzo Nava <lorenx4@gmail.com> |
|---|---|
| Date | 2015-06-30 23:30 +0200 |
| Subject | [PATCH v5] arm DMA: Fix allocation from CMA for coherent DMA |
| Message-ID | <pHbgn-5xn-37@gated-at.bofh.it> |
This patch allows the use of CMA for DMA coherent memory allocation.
At the moment if the input parameter "is_coherent" is set to true
the allocation is not made using the CMA, which I think is not the
desired behaviour.
Signed-off-by: Lorenzo Nava <lorenx4@gmail.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
Changes in v2:
correct __arm_dma_free() according to __dma_alloc() allocation
---
Changes in v3:
now __dma_alloc(), if 'is_coherent' is true, returns memory from CMA
if there is no need for atomic allocation. If CMA is not available
the function returns the result of __alloc_simple_buffer().
__arm_dma_free() frees memory according to the new alloc function
avoiding __dma_free_remap() for coherent DMA if CMA is not enable.
arm_dma_alloc() mark pages as cacheable if attrs are set by default
to NULL. If attrs is not NULL, attributes are preserved in the allocation.
Coherent allocation tested on Xilinx Zynq processor.
---
Changes in v4:
back to "if..else" code style for __dma_alloc()
avoided unnecessary __free_from_pool() call in __arm_dma_free()
---
Changes in v5:
changed coherent allocation attributes in arm_coherent_dma_alloc()
---
arch/arm/mm/dma-mapping.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1ced8a0..8f3f173 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -648,14 +648,18 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
size = PAGE_ALIGN(size);
want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
- if (is_coherent || nommu())
+ if (nommu())
+ addr = __alloc_simple_buffer(dev, size, gfp, &page);
+ else if (dev_get_cma_area(dev) && (gfp & __GFP_WAIT))
+ addr = __alloc_from_contiguous(dev, size, prot, &page,
+ caller, want_vaddr);
+ else if (is_coherent)
addr = __alloc_simple_buffer(dev, size, gfp, &page);
else if (!(gfp & __GFP_WAIT))
addr = __alloc_from_pool(size, &page);
- else if (!dev_get_cma_area(dev))
- addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller, want_vaddr);
else
- addr = __alloc_from_contiguous(dev, size, prot, &page, caller, want_vaddr);
+ addr = __alloc_remap_buffer(dev, size, gfp, prot, &page,
+ caller, want_vaddr);
if (page)
*handle = pfn_to_dma(dev, page_to_pfn(page));
@@ -683,13 +687,12 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
{
- pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
void *memory;
if (dma_alloc_from_coherent(dev, size, handle, &memory))
return memory;
- return __dma_alloc(dev, size, handle, gfp, prot, true,
+ return __dma_alloc(dev, size, handle, gfp, PAGE_KERNEL, true,
attrs, __builtin_return_address(0));
}
@@ -753,12 +756,12 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
size = PAGE_ALIGN(size);
- if (is_coherent || nommu()) {
+ if (nommu()) {
__dma_free_buffer(page, size);
- } else if (__free_from_pool(cpu_addr, size)) {
+ } else if (!is_coherent && __free_from_pool(cpu_addr, size)) {
return;
} else if (!dev_get_cma_area(dev)) {
- if (want_vaddr)
+ if (want_vaddr && !is_coherent)
__dma_free_remap(cpu_addr, size);
__dma_free_buffer(page, size);
} else {
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Catalin Marinas <catalin.marinas@arm.com> |
|---|---|
| Date | 2015-07-03 12:30 +0200 |
| Message-ID | <pI6oi-7jr-19@gated-at.bofh.it> |
| In reply to | #1174770 |
On Fri, Jul 03, 2015 at 10:03:06AM +0100, Russell King - ARM Linux wrote: > On Wed, Jul 01, 2015 at 12:12:51PM +0100, Catalin Marinas wrote: > > On Tue, Jun 30, 2015 at 11:29:06PM +0200, Lorenzo Nava wrote: > > > This patch allows the use of CMA for DMA coherent memory allocation. > > > At the moment if the input parameter "is_coherent" is set to true > > > the allocation is not made using the CMA, which I think is not the > > > desired behaviour. > > > > > > Signed-off-by: Lorenzo Nava <lorenx4@gmail.com> > > > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> > > > > If Russell doesn't have any objections, you can send the patch to > > his patch system. See here for more information: > > I'm left wondering whether this patch is really want Lorenzo wants. > From my reading of it, while this has the effect of allocating from > CMA for coherent devices, it's no different from the non-coherent > case, because by calling __alloc_from_contiguous(), we end up > remapping the allocated memory, removing the cacheability status > from the allocated pages. The arm_coherent_dma_alloc() function is changed by this patch to pass PAGE_KERNEL as prot, so the cacheability attributes should be preserved. We have a superfluous __dma_remap() call for lowmem CMA pages which changes the protection from PAGE_KERNEL to PAGE_KERNEL but, as you mentioned in another reply, the overhead of CMA is big enough to not make this noticeable. The alternative (as I suggested in one of the earlier versions of this patch) was to change __get_dma_pgprot() to take a "coherent" argument and return PAGE_KERNEL. But since the coherent mmap was fixed in a similar way to this patch (and merged already), I gave up on my initial suggestion. > This brings up an interesting point: presumably, it's been tested, and > people are happy with the performance it's giving, inspite of it not > returning cacheable memory... or maybe it hasn't been tested that much? It must cacheable memory, otherwise it's not a performance but a data corruption issue. For example, a cacheable device access may allocate in an outer cache but non-cacheable CPU access doesn't look into it. -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web