Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1519196 > unrolled thread
| Started by | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| First post | 2016-11-10 18:40 +0100 |
| Last post | 2016-11-18 17:20 +0100 |
| Articles | 16 — 4 participants |
Back to article view | Back to linux.kernel
[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
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2016-11-13 18:30 +0100 |
| Subject | Re: [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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Tobias Klauser <tklauser@distanz.ch> |
|---|---|
| Date | 2016-11-11 12:00 +0100 |
| Subject | Re: [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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.h.duyck@intel.com> |
|---|---|
| Date | 2016-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]
| From | Alexander Duyck <alexander.duyck@gmail.com> |
|---|---|
| Date | 2016-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