All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: Tony Luck <tony.luck@intel.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
	iommu@lists.linux-foundation.org
Cc: Tomasz Figa <tfiga@chromium.org>, Joerg Roedel <joro@8bytes.org>,
	Robin Murphy <robin.murphy@arm.com>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-ia64@vger.kernel.org, linux-mips@vger.kernel.org
Subject: [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous
Date: Tue,  8 Sep 2020 18:47:47 +0200	[thread overview]
Message-ID: <20200908164758.3177341-2-hch@lst.de> (raw)
In-Reply-To: <20200908164758.3177341-1-hch@lst.de>

When transferring DMA ownership back to the CPU there should never
be any writeback from the cache, as the buffer was owned by the
device until now.  Instead it should just be invalidated for the
mapping directions where the device could have written data.
Note that the changes rely on the fact that kmap_atomic is stubbed
out for the !HIGHMEM case to simplify the code a bit.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/mm/dma-noncoherent.c | 44 +++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 563c2c0d0c8193..97a14adbafc99c 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -55,22 +55,34 @@ void *arch_dma_set_uncached(void *addr, size_t size)
 	return (void *)(__pa(addr) + UNCAC_BASE);
 }
 
-static inline void dma_sync_virt(void *addr, size_t size,
+static inline void dma_sync_virt_for_device(void *addr, size_t size,
 		enum dma_data_direction dir)
 {
 	switch (dir) {
 	case DMA_TO_DEVICE:
 		dma_cache_wback((unsigned long)addr, size);
 		break;
-
 	case DMA_FROM_DEVICE:
 		dma_cache_inv((unsigned long)addr, size);
 		break;
-
 	case DMA_BIDIRECTIONAL:
 		dma_cache_wback_inv((unsigned long)addr, size);
 		break;
+	default:
+		BUG();
+	}
+}
 
+static inline void dma_sync_virt_for_cpu(void *addr, size_t size,
+		enum dma_data_direction dir)
+{
+	switch (dir) {
+	case DMA_TO_DEVICE:
+		break;
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		dma_cache_inv((unsigned long)addr, size);
+		break;
 	default:
 		BUG();
 	}
@@ -82,7 +94,7 @@ static inline void dma_sync_virt(void *addr, size_t size,
  * configured then the bulk of this loop gets optimized out.
  */
 static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
-		enum dma_data_direction dir)
+		enum dma_data_direction dir, bool for_device)
 {
 	struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
 	unsigned long offset = paddr & ~PAGE_MASK;
@@ -90,18 +102,20 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 
 	do {
 		size_t len = left;
+		void *addr;
 
 		if (PageHighMem(page)) {
-			void *addr;
-
 			if (offset + len > PAGE_SIZE)
 				len = PAGE_SIZE - offset;
+		}
+
+		addr = kmap_atomic(page);
+		if (for_device)
+			dma_sync_virt_for_device(addr + offset, len, dir);
+		else
+			dma_sync_virt_for_cpu(addr + offset, len, dir);
+		kunmap_atomic(addr);
 
-			addr = kmap_atomic(page);
-			dma_sync_virt(addr + offset, len, dir);
-			kunmap_atomic(addr);
-		} else
-			dma_sync_virt(page_address(page) + offset, size, dir);
 		offset = 0;
 		page++;
 		left -= len;
@@ -111,7 +125,7 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
-	dma_sync_phys(paddr, size, dir);
+	dma_sync_phys(paddr, size, dir, true);
 }
 
 #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
@@ -119,16 +133,14 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
 	if (cpu_needs_post_dma_flush())
-		dma_sync_phys(paddr, size, dir);
+		dma_sync_phys(paddr, size, dir, false);
 }
 #endif
 
 void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		enum dma_data_direction direction)
 {
-	BUG_ON(direction == DMA_NONE);
-
-	dma_sync_virt(vaddr, size, direction);
+	dma_sync_virt_for_device(vaddr, size, direction);
 }
 
 #ifdef CONFIG_DMA_PERDEV_COHERENT
-- 
2.28.0


WARNING: multiple messages have this Message-ID (diff)
From: Christoph Hellwig <hch@lst.de>
To: Tony Luck <tony.luck@intel.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
	iommu@lists.linux-foundation.org
Cc: linux-ia64@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org,
	Robin Murphy <robin.murphy@arm.com>
Subject: [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous
Date: Tue,  8 Sep 2020 18:47:47 +0200	[thread overview]
Message-ID: <20200908164758.3177341-2-hch@lst.de> (raw)
In-Reply-To: <20200908164758.3177341-1-hch@lst.de>

When transferring DMA ownership back to the CPU there should never
be any writeback from the cache, as the buffer was owned by the
device until now.  Instead it should just be invalidated for the
mapping directions where the device could have written data.
Note that the changes rely on the fact that kmap_atomic is stubbed
out for the !HIGHMEM case to simplify the code a bit.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/mm/dma-noncoherent.c | 44 +++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 563c2c0d0c8193..97a14adbafc99c 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -55,22 +55,34 @@ void *arch_dma_set_uncached(void *addr, size_t size)
 	return (void *)(__pa(addr) + UNCAC_BASE);
 }
 
-static inline void dma_sync_virt(void *addr, size_t size,
+static inline void dma_sync_virt_for_device(void *addr, size_t size,
 		enum dma_data_direction dir)
 {
 	switch (dir) {
 	case DMA_TO_DEVICE:
 		dma_cache_wback((unsigned long)addr, size);
 		break;
-
 	case DMA_FROM_DEVICE:
 		dma_cache_inv((unsigned long)addr, size);
 		break;
-
 	case DMA_BIDIRECTIONAL:
 		dma_cache_wback_inv((unsigned long)addr, size);
 		break;
+	default:
+		BUG();
+	}
+}
 
+static inline void dma_sync_virt_for_cpu(void *addr, size_t size,
+		enum dma_data_direction dir)
+{
+	switch (dir) {
+	case DMA_TO_DEVICE:
+		break;
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		dma_cache_inv((unsigned long)addr, size);
+		break;
 	default:
 		BUG();
 	}
@@ -82,7 +94,7 @@ static inline void dma_sync_virt(void *addr, size_t size,
  * configured then the bulk of this loop gets optimized out.
  */
 static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
-		enum dma_data_direction dir)
+		enum dma_data_direction dir, bool for_device)
 {
 	struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
 	unsigned long offset = paddr & ~PAGE_MASK;
@@ -90,18 +102,20 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 
 	do {
 		size_t len = left;
+		void *addr;
 
 		if (PageHighMem(page)) {
-			void *addr;
-
 			if (offset + len > PAGE_SIZE)
 				len = PAGE_SIZE - offset;
+		}
+
+		addr = kmap_atomic(page);
+		if (for_device)
+			dma_sync_virt_for_device(addr + offset, len, dir);
+		else
+			dma_sync_virt_for_cpu(addr + offset, len, dir);
+		kunmap_atomic(addr);
 
-			addr = kmap_atomic(page);
-			dma_sync_virt(addr + offset, len, dir);
-			kunmap_atomic(addr);
-		} else
-			dma_sync_virt(page_address(page) + offset, size, dir);
 		offset = 0;
 		page++;
 		left -= len;
@@ -111,7 +125,7 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
-	dma_sync_phys(paddr, size, dir);
+	dma_sync_phys(paddr, size, dir, true);
 }
 
 #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
@@ -119,16 +133,14 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
 	if (cpu_needs_post_dma_flush())
-		dma_sync_phys(paddr, size, dir);
+		dma_sync_phys(paddr, size, dir, false);
 }
 #endif
 
 void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		enum dma_data_direction direction)
 {
-	BUG_ON(direction == DMA_NONE);
-
-	dma_sync_virt(vaddr, size, direction);
+	dma_sync_virt_for_device(vaddr, size, direction);
 }
 
 #ifdef CONFIG_DMA_PERDEV_COHERENT
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

WARNING: multiple messages have this Message-ID (diff)
From: Christoph Hellwig <hch@lst.de>
To: Tony Luck <tony.luck@intel.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
	iommu@lists.linux-foundation.org
Cc: Tomasz Figa <tfiga@chromium.org>, Joerg Roedel <joro@8bytes.org>,
	Robin Murphy <robin.murphy@arm.com>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-ia64@vger.kernel.org, linux-mips@vger.kernel.org
Subject: [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous
Date: Tue, 08 Sep 2020 16:47:47 +0000	[thread overview]
Message-ID: <20200908164758.3177341-2-hch@lst.de> (raw)
In-Reply-To: <20200908164758.3177341-1-hch@lst.de>

When transferring DMA ownership back to the CPU there should never
be any writeback from the cache, as the buffer was owned by the
device until now.  Instead it should just be invalidated for the
mapping directions where the device could have written data.
Note that the changes rely on the fact that kmap_atomic is stubbed
out for the !HIGHMEM case to simplify the code a bit.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/mm/dma-noncoherent.c | 44 +++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 563c2c0d0c8193..97a14adbafc99c 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -55,22 +55,34 @@ void *arch_dma_set_uncached(void *addr, size_t size)
 	return (void *)(__pa(addr) + UNCAC_BASE);
 }
 
-static inline void dma_sync_virt(void *addr, size_t size,
+static inline void dma_sync_virt_for_device(void *addr, size_t size,
 		enum dma_data_direction dir)
 {
 	switch (dir) {
 	case DMA_TO_DEVICE:
 		dma_cache_wback((unsigned long)addr, size);
 		break;
-
 	case DMA_FROM_DEVICE:
 		dma_cache_inv((unsigned long)addr, size);
 		break;
-
 	case DMA_BIDIRECTIONAL:
 		dma_cache_wback_inv((unsigned long)addr, size);
 		break;
+	default:
+		BUG();
+	}
+}
 
+static inline void dma_sync_virt_for_cpu(void *addr, size_t size,
+		enum dma_data_direction dir)
+{
+	switch (dir) {
+	case DMA_TO_DEVICE:
+		break;
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		dma_cache_inv((unsigned long)addr, size);
+		break;
 	default:
 		BUG();
 	}
@@ -82,7 +94,7 @@ static inline void dma_sync_virt(void *addr, size_t size,
  * configured then the bulk of this loop gets optimized out.
  */
 static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
-		enum dma_data_direction dir)
+		enum dma_data_direction dir, bool for_device)
 {
 	struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
 	unsigned long offset = paddr & ~PAGE_MASK;
@@ -90,18 +102,20 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 
 	do {
 		size_t len = left;
+		void *addr;
 
 		if (PageHighMem(page)) {
-			void *addr;
-
 			if (offset + len > PAGE_SIZE)
 				len = PAGE_SIZE - offset;
+		}
+
+		addr = kmap_atomic(page);
+		if (for_device)
+			dma_sync_virt_for_device(addr + offset, len, dir);
+		else
+			dma_sync_virt_for_cpu(addr + offset, len, dir);
+		kunmap_atomic(addr);
 
-			addr = kmap_atomic(page);
-			dma_sync_virt(addr + offset, len, dir);
-			kunmap_atomic(addr);
-		} else
-			dma_sync_virt(page_address(page) + offset, size, dir);
 		offset = 0;
 		page++;
 		left -= len;
@@ -111,7 +125,7 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
-	dma_sync_phys(paddr, size, dir);
+	dma_sync_phys(paddr, size, dir, true);
 }
 
 #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
@@ -119,16 +133,14 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir)
 {
 	if (cpu_needs_post_dma_flush())
-		dma_sync_phys(paddr, size, dir);
+		dma_sync_phys(paddr, size, dir, false);
 }
 #endif
 
 void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		enum dma_data_direction direction)
 {
-	BUG_ON(direction = DMA_NONE);
-
-	dma_sync_virt(vaddr, size, direction);
+	dma_sync_virt_for_device(vaddr, size, direction);
 }
 
 #ifdef CONFIG_DMA_PERDEV_COHERENT
-- 
2.28.0

  reply	other threads:[~2020-09-08 16:51 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-08 16:47 dma-mapping cleanups Christoph Hellwig
2020-09-08 16:47 ` Christoph Hellwig
2020-09-08 16:47 ` Christoph Hellwig
2020-09-08 16:47 ` Christoph Hellwig [this message]
2020-09-08 16:47   ` [PATCH 01/12] MIPS: make dma_sync_*_for_cpu a little less overzealous Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 02/12] MIPS/jazzdma: remove the unused vdma_remap function Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 03/12] MIPS/jazzdma: decouple from dma-direct Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 04/12] dma-mapping: fix DMA_OPS dependencies Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 18:04   ` Sergei Shtylyov
2020-09-08 18:04     ` Sergei Shtylyov
2020-09-08 18:04     ` Sergei Shtylyov
2020-09-11  7:10     ` Christoph Hellwig
2020-09-11  7:10       ` Christoph Hellwig
2020-09-11  7:10       ` Christoph Hellwig
2020-09-10 12:55   ` Robin Murphy
2020-09-10 12:55     ` Robin Murphy
2020-09-10 12:55     ` Robin Murphy
2020-09-11  7:09     ` Christoph Hellwig
2020-09-11  7:09       ` Christoph Hellwig
2020-09-11  7:09       ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 05/12] dma-mapping: add (back) arch_dma_mark_clean for ia64 Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 06/12] dma-direct: remove dma_direct_{alloc,free}_pages Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-10 12:57   ` Robin Murphy
2020-09-10 12:57     ` Robin Murphy
2020-09-10 12:57     ` Robin Murphy
2020-09-08 16:47 ` [PATCH 07/12] dma-direct: lift gfp_t manipulation out of__dma_direct_alloc_pages Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-10 13:02   ` Robin Murphy
2020-09-10 13:02     ` Robin Murphy
2020-09-10 13:02     ` Robin Murphy
2020-09-08 16:47 ` [PATCH 08/12] dma-direct: use phys_to_dma_direct in dma_direct_alloc Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-10 13:03   ` Robin Murphy
2020-09-10 13:03     ` Robin Murphy
2020-09-10 13:03     ` Robin Murphy
2020-09-08 16:47 ` [PATCH 09/12] dma-direct: remove __dma_to_phys Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-10  9:45   ` Dan Carpenter
2020-09-10  9:45     ` Dan Carpenter
2020-09-11  7:12     ` Christoph Hellwig
2020-09-10 13:26   ` Robin Murphy
2020-09-10 13:26     ` Robin Murphy
2020-09-10 13:26     ` Robin Murphy
2020-09-11  7:14     ` Christoph Hellwig
2020-09-11  7:14       ` Christoph Hellwig
2020-09-11  7:14       ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 10/12] dma-direct: rename and cleanup __phys_to_dma Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-10 13:30   ` Robin Murphy
2020-09-10 13:30     ` Robin Murphy
2020-09-10 13:30     ` Robin Murphy
2020-09-08 16:47 ` [PATCH 11/12] dma-mapping: move dma_common_{mmap,get_sgtable} out of mapping.c Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} " Christoph Hellwig
2020-09-10 13:34   ` [PATCH 11/12] dma-mapping: move dma_common_{mmap,get_sgtable} " Robin Murphy
2020-09-10 13:34     ` Robin Murphy
2020-09-10 13:34     ` [PATCH 11/12] dma-mapping: move dma_common_{mmap, get_sgtable} " Robin Murphy
2020-09-11  7:15     ` [PATCH 11/12] dma-mapping: move dma_common_{mmap,get_sgtable} " Christoph Hellwig
2020-09-11  7:15       ` Christoph Hellwig
2020-09-11  7:15       ` Christoph Hellwig
2020-09-08 16:47 ` [PATCH 12/12] dma-mapping: move the dma_declare_coherent_memory documentation Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-08 16:47   ` Christoph Hellwig
2020-09-10 13:51   ` Robin Murphy
2020-09-10 13:51     ` Robin Murphy
2020-09-10 13:51     ` Robin Murphy
2020-09-11  7:17     ` Christoph Hellwig
2020-09-11  7:17       ` Christoph Hellwig
2020-09-11  7:17       ` Christoph Hellwig
     [not found] ` <20200910141233.10768-1-hdanton@sina.com>
2020-09-11  7:07   ` [PATCH 03/12] MIPS/jazzdma: decouple from dma-direct 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=20200908164758.3177341-2-hch@lst.de \
    --to=hch@lst.de \
    --cc=fenghua.yu@intel.com \
    --cc=iommu@lists.linux-foundation.org \
    --cc=joro@8bytes.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-ia64@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=tfiga@chromium.org \
    --cc=tony.luck@intel.com \
    --cc=tsbogend@alpha.franken.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.