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


Groups > linux.kernel > #1519196 > unrolled thread

[mm PATCH v3 00/23] Add support for DMA writable pages being writable by the network stack

Started byAlexander Duyck <alexander.h.duyck@intel.com>
First post2016-11-10 18:40 +0100
Last post2016-11-18 17:20 +0100
Articles 16 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [mm PATCH v3 00/23] Add support for DMA writable pages being  writable by the network stack Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 19/23] arch/xtensa: Add option to skip DMA sync as a  part of mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 08/23] arch/m68k: Add option to skip DMA sync as a  part of mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 17/23] arch/sparc: Add option to skip DMA sync as a  part of map and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
      Re: [mm PATCH v3 17/23] arch/sparc: Add option to skip DMA sync as  a part of map and unmap David Miller <davem@davemloft.net> - 2016-11-13 18:30 +0100
    [mm PATCH v3 23/23] igb: Update code to better handle incrementing  page count Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 03/23] arch/avr32: Add option to skip sync on DMA map Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 15/23] arch/powerpc: Add option to skip DMA sync as a  part of mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 12/23] arch/nios2: Add option to skip DMA sync as a  part of map and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
      Re: [mm PATCH v3 12/23] arch/nios2: Add option to skip DMA sync as a  part of map and unmap Tobias Klauser <tklauser@distanz.ch> - 2016-11-11 12:00 +0100
    [mm PATCH v3 10/23] arch/microblaze: Add option to skip DMA sync as  a part of map and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:40 +0100
    [mm PATCH v3 04/23] arch/blackfin: Add option to skip sync on DMA  map Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:50 +0100
    [mm PATCH v3 16/23] arch/sh: Add option to skip DMA sync as a part  of mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:50 +0100
    [mm PATCH v3 05/23] arch/c6x: Add option to skip sync on DMA map  and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:50 +0100
    [mm PATCH v3 13/23] arch/openrisc: Add option to skip DMA sync as a  part of mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-10 18:50 +0100
    Re: [mm PATCH v3 00/23] Add support for DMA writable pages being  writable by the network stack Alexander Duyck <alexander.duyck@gmail.com> - 2016-11-18 17:20 +0100

#1519196 — [mm PATCH v3 00/23] Add support for DMA writable pages being writable by the network stack

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 00/23] Add support for DMA writable pages being writable by the network stack
Message-ID<sC1up-MX-9@gated-at.bofh.it>
The first 19 patches in the set add support for the DMA attribute
DMA_ATTR_SKIP_CPU_SYNC on multiple platforms/architectures.  This is needed
so that we can flag the calls to dma_map/unmap_page so that we do not
invalidate cache lines that do not currently belong to the device.  Instead
we have to take care of this in the driver via a call to
sync_single_range_for_cpu prior to freeing the Rx page.

Patch 20 adds support for dma_map_page_attrs and dma_unmap_page_attrs so
that we can unmap and map a page using the DMA_ATTR_SKIP_CPU_SYNC
attribute.

Patch 21 adds support for freeing a page that has multiple references being
held by a single caller.  This way we can free page fragments that were
allocated by a given driver.

The last 2 patches use these updates in the igb driver, and lay the
groundwork to allow for us to reimplement the use of build_skb.

v1: Minor fixes based on issues found by kernel build bot
    Few minor changes for issues found on code review
    Added Acked-by for patches that were acked and not changed

v2: Added a few more Acked-by
    Submitting patches to mm instead of net-next

v3: Added Acked-by for PowerPC architecture
    Dropped first 3 patches which were accepted into swiotlb tree
    Dropped comments describing swiotlb changes.

---

Alexander Duyck (23):
      arch/arc: Add option to skip sync on DMA mapping
      arch/arm: Add option to skip sync on DMA map and unmap
      arch/avr32: Add option to skip sync on DMA map
      arch/blackfin: Add option to skip sync on DMA map
      arch/c6x: Add option to skip sync on DMA map and unmap
      arch/frv: Add option to skip sync on DMA map
      arch/hexagon: Add option to skip DMA sync as a part of mapping
      arch/m68k: Add option to skip DMA sync as a part of mapping
      arch/metag: Add option to skip DMA sync as a part of map and unmap
      arch/microblaze: Add option to skip DMA sync as a part of map and unmap
      arch/mips: Add option to skip DMA sync as a part of map and unmap
      arch/nios2: Add option to skip DMA sync as a part of map and unmap
      arch/openrisc: Add option to skip DMA sync as a part of mapping
      arch/parisc: Add option to skip DMA sync as a part of map and unmap
      arch/powerpc: Add option to skip DMA sync as a part of mapping
      arch/sh: Add option to skip DMA sync as a part of mapping
      arch/sparc: Add option to skip DMA sync as a part of map and unmap
      arch/tile: Add option to skip DMA sync as a part of map and unmap
      arch/xtensa: Add option to skip DMA sync as a part of mapping
      dma: Add calls for dma_map_page_attrs and dma_unmap_page_attrs
      mm: Add support for releasing multiple instances of a page
      igb: Update driver to make use of DMA_ATTR_SKIP_CPU_SYNC
      igb: Update code to better handle incrementing page count


 arch/arc/mm/dma.c                         |    5 ++
 arch/arm/common/dmabounce.c               |   16 ++++--
 arch/avr32/mm/dma-coherent.c              |    7 ++-
 arch/blackfin/kernel/dma-mapping.c        |    8 +++
 arch/c6x/kernel/dma.c                     |   14 ++++-
 arch/frv/mb93090-mb00/pci-dma-nommu.c     |   14 ++++-
 arch/frv/mb93090-mb00/pci-dma.c           |    9 +++
 arch/hexagon/kernel/dma.c                 |    6 ++
 arch/m68k/kernel/dma.c                    |    8 +++
 arch/metag/kernel/dma.c                   |   16 +++++-
 arch/microblaze/kernel/dma.c              |   10 +++-
 arch/mips/loongson64/common/dma-swiotlb.c |    2 -
 arch/mips/mm/dma-default.c                |    8 ++-
 arch/nios2/mm/dma-mapping.c               |   26 +++++++---
 arch/openrisc/kernel/dma.c                |    3 +
 arch/parisc/kernel/pci-dma.c              |   20 ++++++--
 arch/powerpc/kernel/dma.c                 |    9 +++
 arch/sh/kernel/dma-nommu.c                |    7 ++-
 arch/sparc/kernel/iommu.c                 |    4 +-
 arch/sparc/kernel/ioport.c                |    4 +-
 arch/tile/kernel/pci-dma.c                |   12 ++++-
 arch/xtensa/kernel/pci-dma.c              |    7 ++-
 drivers/net/ethernet/intel/igb/igb.h      |    7 ++-
 drivers/net/ethernet/intel/igb/igb_main.c |   77 +++++++++++++++++++----------
 include/linux/dma-mapping.h               |   20 +++++---
 include/linux/gfp.h                       |    2 +
 mm/page_alloc.c                           |   14 +++++
 27 files changed, 246 insertions(+), 89 deletions(-)

--

[toc] | [next] | [standalone]


#1519199 — [mm PATCH v3 19/23] arch/xtensa: Add option to skip DMA sync as a part of mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 19/23] arch/xtensa: Add option to skip DMA sync as a part of mapping
Message-ID<sC1ur-MX-75@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Cc: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/xtensa/kernel/pci-dma.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 1e68806..6a16dec 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -189,7 +189,9 @@ static dma_addr_t xtensa_map_page(struct device *dev, struct page *page,
 {
 	dma_addr_t dma_handle = page_to_phys(page) + offset;
 
-	xtensa_sync_single_for_device(dev, dma_handle, size, dir);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		xtensa_sync_single_for_device(dev, dma_handle, size, dir);
+
 	return dma_handle;
 }
 
@@ -197,7 +199,8 @@ static void xtensa_unmap_page(struct device *dev, dma_addr_t dma_handle,
 			      size_t size, enum dma_data_direction dir,
 			      unsigned long attrs)
 {
-	xtensa_sync_single_for_cpu(dev, dma_handle, size, dir);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		xtensa_sync_single_for_cpu(dev, dma_handle, size, dir);
 }
 
 static int xtensa_map_sg(struct device *dev, struct scatterlist *sg,

[toc] | [prev] | [next] | [standalone]


#1519201 — [mm PATCH v3 08/23] arch/m68k: Add option to skip DMA sync as a part of mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 08/23] arch/m68k: Add option to skip DMA sync as a part of mapping
Message-ID<sC1ur-MX-63@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
later via a sync_for_cpu or sync_for_device call.

Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/m68k/kernel/dma.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 8cf97cb..0707006 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -134,7 +134,9 @@ static dma_addr_t m68k_dma_map_page(struct device *dev, struct page *page,
 {
 	dma_addr_t handle = page_to_phys(page) + offset;
 
-	dma_sync_single_for_device(dev, handle, size, dir);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		dma_sync_single_for_device(dev, handle, size, dir);
+
 	return handle;
 }
 
@@ -146,6 +148,10 @@ static int m68k_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 
 	for_each_sg(sglist, sg, nents, i) {
 		sg->dma_address = sg_phys(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		dma_sync_single_for_device(dev, sg->dma_address, sg->length,
 					   dir);
 	}

[toc] | [prev] | [next] | [standalone]


#1519206 — [mm PATCH v3 17/23] arch/sparc: Add option to skip DMA sync as a part of map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 17/23] arch/sparc: Add option to skip DMA sync as a part of map and unmap
Message-ID<sC1us-MX-95@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/sparc/kernel/iommu.c  |    4 ++--
 arch/sparc/kernel/ioport.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 5c615ab..8fda4e4 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -415,7 +415,7 @@ static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr,
 		ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 
 	/* Step 1: Kick data out of streaming buffers if necessary. */
-	if (strbuf->strbuf_enabled)
+	if (strbuf->strbuf_enabled && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 		strbuf_flush(strbuf, iommu, bus_addr, ctx,
 			     npages, direction);
 
@@ -640,7 +640,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
 		base = iommu->page_table + entry;
 
 		dma_handle &= IO_PAGE_MASK;
-		if (strbuf->strbuf_enabled)
+		if (strbuf->strbuf_enabled && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 			strbuf_flush(strbuf, iommu, dma_handle, ctx,
 				     npages, direction);
 
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 2344103..6ffaec4 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -527,7 +527,7 @@ static dma_addr_t pci32_map_page(struct device *dev, struct page *page,
 static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
 			     enum dma_data_direction dir, unsigned long attrs)
 {
-	if (dir != PCI_DMA_TODEVICE)
+	if (dir != PCI_DMA_TODEVICE && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
 		dma_make_coherent(ba, PAGE_ALIGN(size));
 }
 
@@ -572,7 +572,7 @@ static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl,
 	struct scatterlist *sg;
 	int n;
 
-	if (dir != PCI_DMA_TODEVICE) {
+	if (dir != PCI_DMA_TODEVICE && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) {
 		for_each_sg(sgl, sg, nents, n) {
 			dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
 		}

[toc] | [prev] | [next] | [standalone]


#1520626 — Re: [mm PATCH v3 17/23] arch/sparc: Add option to skip DMA sync as a part of map and unmap

FromDavid Miller <davem@davemloft.net>
Date2016-11-13 18:30 +0100
SubjectRe: [mm PATCH v3 17/23] arch/sparc: Add option to skip DMA sync as a part of map and unmap
Message-ID<sD6Lo-3gK-13@gated-at.bofh.it>
In reply to#1519206
From: Alexander Duyck <alexander.h.duyck@intel.com>
Date: Thu, 10 Nov 2016 06:35:45 -0500

> This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
> avoid invoking cache line invalidation if the driver will just handle it
> via a sync_for_cpu or sync_for_device call.
> 
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>

Acked-by: David S. Miller <davem@davemloft.net>

[toc] | [prev] | [next] | [standalone]


#1519207 — [mm PATCH v3 23/23] igb: Update code to better handle incrementing page count

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 23/23] igb: Update code to better handle incrementing page count
Message-ID<sC1ur-MX-77@gated-at.bofh.it>
In reply to#1519196
This patch updates the driver code so that we do bulk updates of the page
reference count instead of just incrementing it by one reference at a time.
The advantage to doing this is that we cut down on atomic operations and
this in turn should give us a slight improvement in cycles per packet.  In
addition if we eventually move this over to using build_skb the gains will
be more noticeable.

Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 drivers/net/ethernet/intel/igb/igb.h      |    7 ++++++-
 drivers/net/ethernet/intel/igb/igb_main.c |   24 +++++++++++++++++-------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 5387b3a..786de01 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -210,7 +210,12 @@ struct igb_tx_buffer {
 struct igb_rx_buffer {
 	dma_addr_t dma;
 	struct page *page;
-	unsigned int page_offset;
+#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
+	__u32 page_offset;
+#else
+	__u16 page_offset;
+#endif
+	__u16 pagecnt_bias;
 };
 
 struct igb_tx_queue_stats {
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ba97392..f5a9fd6 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -3937,7 +3937,8 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring)
 				     PAGE_SIZE,
 				     DMA_FROM_DEVICE,
 				     DMA_ATTR_SKIP_CPU_SYNC);
-		__free_page(buffer_info->page);
+		__page_frag_drain(buffer_info->page, 0,
+				  buffer_info->pagecnt_bias);
 
 		buffer_info->page = NULL;
 	}
@@ -6813,13 +6814,15 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
 				  struct page *page,
 				  unsigned int truesize)
 {
+	unsigned int pagecnt_bias = rx_buffer->pagecnt_bias--;
+
 	/* avoid re-using remote pages */
 	if (unlikely(igb_page_is_reserved(page)))
 		return false;
 
 #if (PAGE_SIZE < 8192)
 	/* if we are only owner of page we can reuse it */
-	if (unlikely(page_count(page) != 1))
+	if (unlikely(page_ref_count(page) != pagecnt_bias))
 		return false;
 
 	/* flip page offset to other buffer */
@@ -6832,10 +6835,14 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
 		return false;
 #endif
 
-	/* Even if we own the page, we are not allowed to use atomic_set()
-	 * This would break get_page_unless_zero() users.
+	/* If we have drained the page fragment pool we need to update
+	 * the pagecnt_bias and page count so that we fully restock the
+	 * number of references the driver holds.
 	 */
-	page_ref_inc(page);
+	if (unlikely(pagecnt_bias == 1)) {
+		page_ref_add(page, USHRT_MAX);
+		rx_buffer->pagecnt_bias = USHRT_MAX;
+	}
 
 	return true;
 }
@@ -6887,7 +6894,6 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring,
 			return true;
 
 		/* this page cannot be reused so discard it */
-		__free_page(page);
 		return false;
 	}
 
@@ -6958,10 +6964,13 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
 		/* hand second half of page back to the ring */
 		igb_reuse_rx_page(rx_ring, rx_buffer);
 	} else {
-		/* we are not reusing the buffer so unmap it */
+		/* We are not reusing the buffer so unmap it and free
+		 * any references we are holding to it
+		 */
 		dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma,
 				     PAGE_SIZE, DMA_FROM_DEVICE,
 				     DMA_ATTR_SKIP_CPU_SYNC);
+		__page_frag_drain(page, 0, rx_buffer->pagecnt_bias);
 	}
 
 	/* clear contents of rx_buffer */
@@ -7235,6 +7244,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
 	bi->dma = dma;
 	bi->page = page;
 	bi->page_offset = 0;
+	bi->pagecnt_bias = 1;
 
 	return true;
 }

[toc] | [prev] | [next] | [standalone]


#1519208 — [mm PATCH v3 03/23] arch/avr32: Add option to skip sync on DMA map

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 03/23] arch/avr32: Add option to skip sync on DMA map
Message-ID<sC1us-MX-97@gated-at.bofh.it>
In reply to#1519196
The use of DMA_ATTR_SKIP_CPU_SYNC was not consistent across all of the DMA
APIs in the arch/arm folder.  This change is meant to correct that so that
we get consistent behavior.

Acked-by: Hans-Christian Noren Egtvedt <egtvedt@samfundet.no>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/avr32/mm/dma-coherent.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c
index 58610d0..54534e5 100644
--- a/arch/avr32/mm/dma-coherent.c
+++ b/arch/avr32/mm/dma-coherent.c
@@ -146,7 +146,8 @@ static dma_addr_t avr32_dma_map_page(struct device *dev, struct page *page,
 {
 	void *cpu_addr = page_address(page) + offset;
 
-	dma_cache_sync(dev, cpu_addr, size, direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		dma_cache_sync(dev, cpu_addr, size, direction);
 	return virt_to_bus(cpu_addr);
 }
 
@@ -162,6 +163,10 @@ static int avr32_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 
 		sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
 		virt = sg_virt(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		dma_cache_sync(dev, virt, sg->length, direction);
 	}
 

[toc] | [prev] | [next] | [standalone]


#1519212 — [mm PATCH v3 15/23] arch/powerpc: Add option to skip DMA sync as a part of mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 15/23] arch/powerpc: Add option to skip DMA sync as a part of mapping
Message-ID<sC1us-MX-105@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/powerpc/kernel/dma.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index e64a601..6877e3f 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -203,6 +203,10 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	for_each_sg(sgl, sg, nents, i) {
 		sg->dma_address = sg_phys(sg) + get_dma_offset(dev);
 		sg->dma_length = sg->length;
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
 	}
 
@@ -235,7 +239,10 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev,
 					     unsigned long attrs)
 {
 	BUG_ON(dir == DMA_NONE);
-	__dma_sync_page(page, offset, size, dir);
+
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		__dma_sync_page(page, offset, size, dir);
+
 	return page_to_phys(page) + offset + get_dma_offset(dev);
 }
 

[toc] | [prev] | [next] | [standalone]


#1519213 — [mm PATCH v3 12/23] arch/nios2: Add option to skip DMA sync as a part of map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 12/23] arch/nios2: Add option to skip DMA sync as a part of map and unmap
Message-ID<sC1us-MX-107@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Cc: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/nios2/mm/dma-mapping.c |   26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/arch/nios2/mm/dma-mapping.c b/arch/nios2/mm/dma-mapping.c
index d800fad..f6a5dcf 100644
--- a/arch/nios2/mm/dma-mapping.c
+++ b/arch/nios2/mm/dma-mapping.c
@@ -98,13 +98,17 @@ static int nios2_dma_map_sg(struct device *dev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, sg, nents, i) {
-		void *addr;
+		void *addr = sg_virt(sg);
 
-		addr = sg_virt(sg);
-		if (addr) {
-			__dma_sync_for_device(addr, sg->length, direction);
-			sg->dma_address = sg_phys(sg);
-		}
+		if (!addr)
+			continue;
+
+		sg->dma_address = sg_phys(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
+		__dma_sync_for_device(addr, sg->length, direction);
 	}
 
 	return nents;
@@ -117,7 +121,9 @@ static dma_addr_t nios2_dma_map_page(struct device *dev, struct page *page,
 {
 	void *addr = page_address(page) + offset;
 
-	__dma_sync_for_device(addr, size, direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		__dma_sync_for_device(addr, size, direction);
+
 	return page_to_phys(page) + offset;
 }
 
@@ -125,7 +131,8 @@ static void nios2_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
 		size_t size, enum dma_data_direction direction,
 		unsigned long attrs)
 {
-	__dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		__dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
 }
 
 static void nios2_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
@@ -138,6 +145,9 @@ static void nios2_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 	if (direction == DMA_TO_DEVICE)
 		return;
 
+	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+		return;
+
 	for_each_sg(sg, sg, nhwentries, i) {
 		addr = sg_virt(sg);
 		if (addr)

[toc] | [prev] | [next] | [standalone]


#1519687 — Re: [mm PATCH v3 12/23] arch/nios2: Add option to skip DMA sync as a part of map and unmap

FromTobias Klauser <tklauser@distanz.ch>
Date2016-11-11 12:00 +0100
SubjectRe: [mm PATCH v3 12/23] arch/nios2: Add option to skip DMA sync as a part of map and unmap
Message-ID<sChIR-3fv-7@gated-at.bofh.it>
In reply to#1519213
On 2016-11-10 at 12:35:18 +0100, Alexander Duyck <alexander.h.duyck@intel.com> wrote:
> This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
> avoid invoking cache line invalidation if the driver will just handle it
> via a sync_for_cpu or sync_for_device call.
> 
> Cc: Ley Foon Tan <lftan@altera.com>
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>

Reviewed-by: Tobias Klauser <tklauser@distanz.ch>

[toc] | [prev] | [next] | [standalone]


#1519219 — [mm PATCH v3 10/23] arch/microblaze: Add option to skip DMA sync as a part of map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:40 +0100
Subject[mm PATCH v3 10/23] arch/microblaze: Add option to skip DMA sync as a part of map and unmap
Message-ID<sC1us-MX-109@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Cc: Michal Simek <monstr@monstr.eu>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/microblaze/kernel/dma.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index ec04dc1..818daf2 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -61,6 +61,10 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	/* FIXME this part of code is untested */
 	for_each_sg(sgl, sg, nents, i) {
 		sg->dma_address = sg_phys(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		__dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
 							sg->length, direction);
 	}
@@ -80,7 +84,8 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev,
 					     enum dma_data_direction direction,
 					     unsigned long attrs)
 {
-	__dma_sync(page_to_phys(page) + offset, size, direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		__dma_sync(page_to_phys(page) + offset, size, direction);
 	return page_to_phys(page) + offset;
 }
 
@@ -95,7 +100,8 @@ static inline void dma_direct_unmap_page(struct device *dev,
  * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
  * dma_address is physical address
  */
-	__dma_sync(dma_address, size, direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		__dma_sync(dma_address, size, direction);
 }
 
 static inline void

[toc] | [prev] | [next] | [standalone]


#1519231 — [mm PATCH v3 04/23] arch/blackfin: Add option to skip sync on DMA map

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:50 +0100
Subject[mm PATCH v3 04/23] arch/blackfin: Add option to skip sync on DMA map
Message-ID<sC1E7-QH-49@gated-at.bofh.it>
In reply to#1519196
The use of DMA_ATTR_SKIP_CPU_SYNC was not consistent across all of the DMA
APIs in the arch/arm folder.  This change is meant to correct that so that
we get consistent behavior.

Cc: Steven Miao <realmz6@gmail.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/blackfin/kernel/dma-mapping.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 53fbbb6..a27a74a 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -118,6 +118,10 @@ static int bfin_dma_map_sg(struct device *dev, struct scatterlist *sg_list,
 
 	for_each_sg(sg_list, sg, nents, i) {
 		sg->dma_address = (dma_addr_t) sg_virt(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		__dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
 	}
 
@@ -143,7 +147,9 @@ static dma_addr_t bfin_dma_map_page(struct device *dev, struct page *page,
 {
 	dma_addr_t handle = (dma_addr_t)(page_address(page) + offset);
 
-	_dma_sync(handle, size, dir);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		_dma_sync(handle, size, dir);
+
 	return handle;
 }
 

[toc] | [prev] | [next] | [standalone]


#1519233 — [mm PATCH v3 16/23] arch/sh: Add option to skip DMA sync as a part of mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:50 +0100
Subject[mm PATCH v3 16/23] arch/sh: Add option to skip DMA sync as a part of mapping
Message-ID<sC1E6-QH-39@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/sh/kernel/dma-nommu.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
index eadb669..47fee3b 100644
--- a/arch/sh/kernel/dma-nommu.c
+++ b/arch/sh/kernel/dma-nommu.c
@@ -18,7 +18,9 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
 	dma_addr_t addr = page_to_phys(page) + offset;
 
 	WARN_ON(size == 0);
-	dma_cache_sync(dev, page_address(page) + offset, size, dir);
+
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		dma_cache_sync(dev, page_address(page) + offset, size, dir);
 
 	return addr;
 }
@@ -35,7 +37,8 @@ static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
 	for_each_sg(sg, s, nents, i) {
 		BUG_ON(!sg_page(s));
 
-		dma_cache_sync(dev, sg_virt(s), s->length, dir);
+		if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+			dma_cache_sync(dev, sg_virt(s), s->length, dir);
 
 		s->dma_address = sg_phys(s);
 		s->dma_length = s->length;

[toc] | [prev] | [next] | [standalone]


#1519234 — [mm PATCH v3 05/23] arch/c6x: Add option to skip sync on DMA map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:50 +0100
Subject[mm PATCH v3 05/23] arch/c6x: Add option to skip sync on DMA map and unmap
Message-ID<sC1E7-QH-51@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
later via a sync_for_cpu or sync_for_device call.

Acked-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/c6x/kernel/dma.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c
index db4a6a3..6752df3 100644
--- a/arch/c6x/kernel/dma.c
+++ b/arch/c6x/kernel/dma.c
@@ -42,14 +42,17 @@ static dma_addr_t c6x_dma_map_page(struct device *dev, struct page *page,
 {
 	dma_addr_t handle = virt_to_phys(page_address(page) + offset);
 
-	c6x_dma_sync(handle, size, dir);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		c6x_dma_sync(handle, size, dir);
+
 	return handle;
 }
 
 static void c6x_dma_unmap_page(struct device *dev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
-	c6x_dma_sync(handle, size, dir);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		c6x_dma_sync(handle, size, dir);
 }
 
 static int c6x_dma_map_sg(struct device *dev, struct scatterlist *sglist,
@@ -60,7 +63,8 @@ static int c6x_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 
 	for_each_sg(sglist, sg, nents, i) {
 		sg->dma_address = sg_phys(sg);
-		c6x_dma_sync(sg->dma_address, sg->length, dir);
+		if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+			c6x_dma_sync(sg->dma_address, sg->length, dir);
 	}
 
 	return nents;
@@ -72,9 +76,11 @@ static void c6x_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
 	struct scatterlist *sg;
 	int i;
 
+	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+		return;
+
 	for_each_sg(sglist, sg, nents, i)
 		c6x_dma_sync(sg_dma_address(sg), sg->length, dir);
-
 }
 
 static void c6x_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,

[toc] | [prev] | [next] | [standalone]


#1519243 — [mm PATCH v3 13/23] arch/openrisc: Add option to skip DMA sync as a part of mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-10 18:50 +0100
Subject[mm PATCH v3 13/23] arch/openrisc: Add option to skip DMA sync as a part of mapping
Message-ID<sC1E7-QH-69@gated-at.bofh.it>
In reply to#1519196
This change allows us to pass DMA_ATTR_SKIP_CPU_SYNC which allows us to
avoid invoking cache line invalidation if the driver will just handle it
via a sync_for_cpu or sync_for_device call.

Cc: Jonas Bonn <jonas@southpole.se>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/openrisc/kernel/dma.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index 140c991..906998b 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -141,6 +141,9 @@ or1k_map_page(struct device *dev, struct page *page,
 	unsigned long cl;
 	dma_addr_t addr = page_to_phys(page) + offset;
 
+	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+		return addr;
+
 	switch (dir) {
 	case DMA_TO_DEVICE:
 		/* Flush the dcache for the requested range */

[toc] | [prev] | [next] | [standalone]


#1525485

FromAlexander Duyck <alexander.duyck@gmail.com>
Date2016-11-18 17:20 +0100
Message-ID<sEU3n-113-21@gated-at.bofh.it>
In reply to#1519196
On Thu, Nov 10, 2016 at 3:34 AM, Alexander Duyck
<alexander.h.duyck@intel.com> wrote:
> The first 19 patches in the set add support for the DMA attribute
> DMA_ATTR_SKIP_CPU_SYNC on multiple platforms/architectures.  This is needed
> so that we can flag the calls to dma_map/unmap_page so that we do not
> invalidate cache lines that do not currently belong to the device.  Instead
> we have to take care of this in the driver via a call to
> sync_single_range_for_cpu prior to freeing the Rx page.
>
> Patch 20 adds support for dma_map_page_attrs and dma_unmap_page_attrs so
> that we can unmap and map a page using the DMA_ATTR_SKIP_CPU_SYNC
> attribute.
>
> Patch 21 adds support for freeing a page that has multiple references being
> held by a single caller.  This way we can free page fragments that were
> allocated by a given driver.
>
> The last 2 patches use these updates in the igb driver, and lay the
> groundwork to allow for us to reimplement the use of build_skb.
>
> v1: Minor fixes based on issues found by kernel build bot
>     Few minor changes for issues found on code review
>     Added Acked-by for patches that were acked and not changed
>
> v2: Added a few more Acked-by
>     Submitting patches to mm instead of net-next
>
> v3: Added Acked-by for PowerPC architecture
>     Dropped first 3 patches which were accepted into swiotlb tree
>     Dropped comments describing swiotlb changes.
>
> ---
>
> Alexander Duyck (23):
>       arch/arc: Add option to skip sync on DMA mapping
>       arch/arm: Add option to skip sync on DMA map and unmap
>       arch/avr32: Add option to skip sync on DMA map
>       arch/blackfin: Add option to skip sync on DMA map
>       arch/c6x: Add option to skip sync on DMA map and unmap
>       arch/frv: Add option to skip sync on DMA map
>       arch/hexagon: Add option to skip DMA sync as a part of mapping
>       arch/m68k: Add option to skip DMA sync as a part of mapping
>       arch/metag: Add option to skip DMA sync as a part of map and unmap
>       arch/microblaze: Add option to skip DMA sync as a part of map and unmap
>       arch/mips: Add option to skip DMA sync as a part of map and unmap
>       arch/nios2: Add option to skip DMA sync as a part of map and unmap
>       arch/openrisc: Add option to skip DMA sync as a part of mapping
>       arch/parisc: Add option to skip DMA sync as a part of map and unmap
>       arch/powerpc: Add option to skip DMA sync as a part of mapping
>       arch/sh: Add option to skip DMA sync as a part of mapping
>       arch/sparc: Add option to skip DMA sync as a part of map and unmap
>       arch/tile: Add option to skip DMA sync as a part of map and unmap
>       arch/xtensa: Add option to skip DMA sync as a part of mapping
>       dma: Add calls for dma_map_page_attrs and dma_unmap_page_attrs
>       mm: Add support for releasing multiple instances of a page
>       igb: Update driver to make use of DMA_ATTR_SKIP_CPU_SYNC
>       igb: Update code to better handle incrementing page count
>
>
>  arch/arc/mm/dma.c                         |    5 ++
>  arch/arm/common/dmabounce.c               |   16 ++++--
>  arch/avr32/mm/dma-coherent.c              |    7 ++-
>  arch/blackfin/kernel/dma-mapping.c        |    8 +++
>  arch/c6x/kernel/dma.c                     |   14 ++++-
>  arch/frv/mb93090-mb00/pci-dma-nommu.c     |   14 ++++-
>  arch/frv/mb93090-mb00/pci-dma.c           |    9 +++
>  arch/hexagon/kernel/dma.c                 |    6 ++
>  arch/m68k/kernel/dma.c                    |    8 +++
>  arch/metag/kernel/dma.c                   |   16 +++++-
>  arch/microblaze/kernel/dma.c              |   10 +++-
>  arch/mips/loongson64/common/dma-swiotlb.c |    2 -
>  arch/mips/mm/dma-default.c                |    8 ++-
>  arch/nios2/mm/dma-mapping.c               |   26 +++++++---
>  arch/openrisc/kernel/dma.c                |    3 +
>  arch/parisc/kernel/pci-dma.c              |   20 ++++++--
>  arch/powerpc/kernel/dma.c                 |    9 +++
>  arch/sh/kernel/dma-nommu.c                |    7 ++-
>  arch/sparc/kernel/iommu.c                 |    4 +-
>  arch/sparc/kernel/ioport.c                |    4 +-
>  arch/tile/kernel/pci-dma.c                |   12 ++++-
>  arch/xtensa/kernel/pci-dma.c              |    7 ++-
>  drivers/net/ethernet/intel/igb/igb.h      |    7 ++-
>  drivers/net/ethernet/intel/igb/igb_main.c |   77 +++++++++++++++++++----------
>  include/linux/dma-mapping.h               |   20 +++++---
>  include/linux/gfp.h                       |    2 +
>  mm/page_alloc.c                           |   14 +++++
>  27 files changed, 246 insertions(+), 89 deletions(-)
>

So I am just wondering if I need to resubmit this to pick up the new
"Acked-by"s or if I should just wait?

As I said in the description my hope is to get this into the -mm tree
and I am not familiar with what the process is for being accepted
there.

Thanks.

- Alex

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web