From: Christoph Hellwig <hch@lst.de>
To: iommu@lists.linux-foundation.org
Cc: Robin Murphy <robin.murphy@arm.com>,
Vineet Gupta <vgupta@synopsys.com>,
"Matwey V. Kornilov" <matwey@sai.msu.ru>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
linux-snps-arc@lists.infradead.org,
Ezequiel Garcia <ezequiel@collabora.com>,
linux-media@vger.kernel.org, linux-arm-kernel@vger.kernel.org,
dri-devel@lists.freedesktop.org, sparclinux@vger.kernel.org,
openrisc@lists.librecores.org, linux-parisc@vger.kernel.org,
linux-mips@vger.kernel.org
Subject: [PATCH 01/10] dma-direct: provide a generic implementation of DMA_ATTR_NON_CONSISTENT
Date: Sat, 8 Dec 2018 09:36:53 -0800 [thread overview]
Message-ID: <20181208173702.15158-2-hch@lst.de> (raw)
In-Reply-To: <20181208173702.15158-1-hch@lst.de>
If DMA_ATTR_NON_CONSISTENT is passed in the flags we can always just
use the dma_direct_alloc_pages implementation given that the callers
will take care of any cache maintainance on ownership transfers between
the CPU and the device.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arc/mm/dma.c | 21 ++++++--------------
arch/mips/mm/dma-noncoherent.c | 5 ++---
arch/openrisc/kernel/dma.c | 23 +++++++++-------------
arch/parisc/kernel/pci-dma.c | 35 ++++++++++++----------------------
kernel/dma/direct.c | 4 ++--
5 files changed, 31 insertions(+), 57 deletions(-)
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index db203ff69ccf..135759d4ea8c 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -24,7 +24,6 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
struct page *page;
phys_addr_t paddr;
void *kvaddr;
- bool need_coh = !(attrs & DMA_ATTR_NON_CONSISTENT);
/*
* __GFP_HIGHMEM flag is cleared by upper layer functions
@@ -46,14 +45,10 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
* A coherent buffer needs MMU mapping to enforce non-cachability.
* kvaddr is kernel Virtual address (0x7000_0000 based).
*/
- if (need_coh) {
- kvaddr = ioremap_nocache(paddr, size);
- if (kvaddr == NULL) {
- __free_pages(page, order);
- return NULL;
- }
- } else {
- kvaddr = (void *)(u32)paddr;
+ kvaddr = ioremap_nocache(paddr, size);
+ if (kvaddr == NULL) {
+ __free_pages(page, order);
+ return NULL;
}
/*
@@ -66,9 +61,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
* Currently flush_cache_vmap nukes the L1 cache completely which
* will be optimized as a separate commit
*/
- if (need_coh)
- dma_cache_wback_inv(paddr, size);
-
+ dma_cache_wback_inv(paddr, size);
return kvaddr;
}
@@ -78,9 +71,7 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
phys_addr_t paddr = dma_handle;
struct page *page = virt_to_page(paddr);
- if (!(attrs & DMA_ATTR_NON_CONSISTENT))
- iounmap((void __force __iomem *)vaddr);
-
+ iounmap((void __force __iomem *)vaddr);
__free_pages(page, get_order(size));
}
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index cb38461391cb..7576cd7193ba 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -50,7 +50,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
void *ret;
ret = dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
- if (ret && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
+ if (ret) {
dma_cache_wback_inv((unsigned long) ret, size);
ret = (void *)UNCAC_ADDR(ret);
}
@@ -61,8 +61,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr, unsigned long attrs)
{
- if (!(attrs & DMA_ATTR_NON_CONSISTENT))
- cpu_addr = (void *)CAC_ADDR((unsigned long)cpu_addr);
+ cpu_addr = (void *)CAC_ADDR((unsigned long)cpu_addr);
dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
}
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index 159336adfa2f..483adbb000bb 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -98,15 +98,13 @@ arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
va = (unsigned long)page;
- if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) {
- /*
- * We need to iterate through the pages, clearing the dcache for
- * them and setting the cache-inhibit bit.
- */
- if (walk_page_range(va, va + size, &walk)) {
- free_pages_exact(page, size);
- return NULL;
- }
+ /*
+ * We need to iterate through the pages, clearing the dcache for
+ * them and setting the cache-inhibit bit.
+ */
+ if (walk_page_range(va, va + size, &walk)) {
+ free_pages_exact(page, size);
+ return NULL;
}
return (void *)va;
@@ -122,11 +120,8 @@ arch_dma_free(struct device *dev, size_t size, void *vaddr,
.mm = &init_mm
};
- if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) {
- /* walk_page_range shouldn't be able to fail here */
- WARN_ON(walk_page_range(va, va + size, &walk));
- }
-
+ /* walk_page_range shouldn't be able to fail here */
+ WARN_ON(walk_page_range(va, va + size, &walk));
free_pages_exact(vaddr, size);
}
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 04c48f1ef3fb..6780449e3e8b 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -421,29 +421,18 @@ static void *pcxl_dma_alloc(struct device *dev, size_t size,
return (void *)vaddr;
}
-static void *pcx_dma_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
+static inline bool cpu_supports_coherent_area(void)
{
- void *addr;
-
- if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0)
- return NULL;
-
- addr = (void *)__get_free_pages(flag, get_order(size));
- if (addr)
- *dma_handle = (dma_addr_t)virt_to_phys(addr);
-
- return addr;
+ return boot_cpu_data.cpu_type == pcxl2 ||
+ boot_cpu_data.cpu_type == pcxl;
}
void *arch_dma_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
-
- if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl)
+ if (cpu_supports_coherent_area())
return pcxl_dma_alloc(dev, size, dma_handle, gfp, attrs);
- else
- return pcx_dma_alloc(dev, size, dma_handle, gfp, attrs);
+ return NULL;
}
void arch_dma_free(struct device *dev, size_t size, void *vaddr,
@@ -451,14 +440,14 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
{
int order = get_order(size);
- if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) {
- size = 1 << (order + PAGE_SHIFT);
- unmap_uncached_pages((unsigned long)vaddr, size);
- pcxl_free_range((unsigned long)vaddr, size);
+ if (WARN_ON_ONCE(!cpu_supports_coherent_area()))
+ return;
- vaddr = __va(dma_handle);
- }
- free_pages((unsigned long)vaddr, get_order(size));
+ size = 1 << (order + PAGE_SHIFT);
+ unmap_uncached_pages((unsigned long)vaddr, size);
+ pcxl_free_range((unsigned long)vaddr, size);
+
+ free_pages((unsigned long)__va(dma_handle), get_order(size));
}
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 308f88a750c8..4efe1188fd2e 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -206,7 +206,7 @@ void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
void *dma_direct_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
- if (!dev_is_dma_coherent(dev))
+ if (!dev_is_dma_coherent(dev) && !(attrs & DMA_ATTR_NON_CONSISTENT))
return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
}
@@ -214,7 +214,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
void dma_direct_free(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
{
- if (!dev_is_dma_coherent(dev))
+ if (!dev_is_dma_coherent(dev) && !(attrs & DMA_ATTR_NON_CONSISTENT))
arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
else
dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
--
2.19.2
next prev parent reply other threads:[~2018-12-08 17:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-08 17:36 make the non-consistent DMA allocator more userful Christoph Hellwig
2018-12-08 17:36 ` Christoph Hellwig [this message]
2018-12-08 17:36 ` [PATCH 02/10] arm64/iommu: don't remap contiguous allocations for coherent devices Christoph Hellwig
2018-12-10 19:19 ` Robin Murphy
2018-12-10 19:25 ` Christoph Hellwig
2018-12-08 17:36 ` [PATCH 03/10] arm64/iommu: implement support for DMA_ATTR_NON_CONSISTENT Christoph Hellwig
2018-12-08 17:36 ` [PATCH 04/10] arm: implement DMA_ATTR_NON_CONSISTENT Christoph Hellwig
2018-12-08 22:52 ` Ezequiel Garcia
2018-12-10 19:16 ` Christoph Hellwig
2018-12-08 17:36 ` [PATCH 05/10] sparc64/iommu: move code around a bit Christoph Hellwig
2018-12-09 4:58 ` David Miller
2018-12-08 17:36 ` [PATCH 06/10] sparc64/iommu: implement DMA_ATTR_NON_CONSISTENT Christoph Hellwig
2018-12-09 4:58 ` David Miller
2018-12-08 17:36 ` [PATCH 07/10] sparc64/pci_sun4v: move code around a bit Christoph Hellwig
2018-12-09 4:58 ` David Miller
2018-12-08 17:37 ` [PATCH 08/10] sparc64/pci_sun4v: implement DMA_ATTR_NON_CONSISTENT Christoph Hellwig
2018-12-09 4:58 ` David Miller
2018-12-08 17:37 ` [PATCH 09/10] dma-mapping: skip declared coherent memory for DMA_ATTR_NON_CONSISTENT Christoph Hellwig
2018-12-08 17:37 ` [PATCH 10/10] Documentation: update the description " Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181208173702.15158-2-hch@lst.de \
--to=hch@lst.de \
--cc=dri-devel@lists.freedesktop.org \
--cc=ezequiel@collabora.com \
--cc=iommu@lists.linux-foundation.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-arm-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=linux-parisc@vger.kernel.org \
--cc=linux-snps-arc@lists.infradead.org \
--cc=matwey@sai.msu.ru \
--cc=openrisc@lists.librecores.org \
--cc=robin.murphy@arm.com \
--cc=sparclinux@vger.kernel.org \
--cc=vgupta@synopsys.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).