From: Alexander Duyck <hidden> Date: 2016-11-10 17:35:30
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(-)
--
From: Alexander Duyck <hidden> Date: 2016-11-10 17:35:34
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: Vineet Gupta <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
arch/arc/mm/dma.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:35:41
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: Russell King <linux@armlinux.org.uk>
Signed-off-by: Alexander Duyck <redacted>
---
arch/arm/common/dmabounce.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:35:46
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 <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
arch/avr32/mm/dma-coherent.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:06
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: Richard Kuo <redacted>
Cc: linux-hexagon@vger.kernel.org
Signed-off-by: Alexander Duyck <redacted>
---
arch/hexagon/kernel/dma.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:11
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 <redacted>
---
arch/m68k/kernel/dma.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:19
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.
Signed-off-by: Alexander Duyck <redacted>
---
arch/frv/mb93090-mb00/pci-dma-nommu.c | 14 ++++++++++----
arch/frv/mb93090-mb00/pci-dma.c | 9 +++++++--
2 files changed, 17 insertions(+), 6 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:27
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: Ralf Baechle <redacted>
Cc: Keguang Zhang <keguang.zhang@gmail.com>
Cc: linux-mips@linux-mips.org
Signed-off-by: Alexander Duyck <redacted>
---
arch/mips/loongson64/common/dma-swiotlb.c | 2 +-
arch/mips/mm/dma-default.c | 8 +++++---
2 files changed, 6 insertions(+), 4 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:33
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 <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
arch/nios2/mm/dma-mapping.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:38
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 <redacted>
---
arch/openrisc/kernel/dma.c | 3 +++
1 file changed, 3 insertions(+)
@@ -141,6 +141,9 @@ or1k_map_page(struct device *dev, struct page *page,unsignedlongcl;dma_addr_taddr=page_to_phys(page)+offset;+if(attrs&DMA_ATTR_SKIP_CPU_SYNC)+returnaddr;+switch(dir){caseDMA_TO_DEVICE:/* Flush the dcache for the requested range */--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:40
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 <redacted>
---
arch/microblaze/kernel/dma.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
@@ -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);}
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:45
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: James Hogan <redacted>
Cc: linux-metag@vger.kernel.org
Signed-off-by: Alexander Duyck <redacted>
---
arch/metag/kernel/dma.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:55
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 <redacted>
---
arch/sh/kernel/dma-nommu.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:58
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 <redacted>
---
arch/powerpc/kernel/dma.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:36:59
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: "James E.J. Bottomley" <redacted>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Signed-off-by: Alexander Duyck <redacted>
---
arch/parisc/kernel/pci-dma.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
@@ -510,14 +518,16 @@ static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,BUG_ON(direction==DMA_NONE);+if(attrs&DMA_ATTR_SKIP_CPU_SYNC)+return;+if(direction==DMA_TO_DEVICE)-return;+return;/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */for_each_sg(sglist,sg,nents,i)flush_kernel_vmap_range(sg_virt(sg),sg->length);-return;}staticvoidpa11_dma_sync_single_for_cpu(structdevice*dev,--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:37:02
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 <redacted>
---
arch/sparc/kernel/iommu.c | 4 ++--
arch/sparc/kernel/ioport.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:37:09
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 <redacted>
---
arch/xtensa/kernel/pci-dma.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:37:14
Add support for mapping and unmapping a page with attributes. The primary
use for this is currently to allow for us to pass the
DMA_ATTR_SKIP_CPU_SYNC attribute when mapping and unmapping a page. On
some architectures such as ARM the synchronization has significant overhead
and if we are already taking care of the sync_for_cpu and sync_for_device
from the driver there isn't much need to handle this in the map/unmap calls
as well.
Signed-off-by: Alexander Duyck <redacted>
---
include/linux/dma-mapping.h | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
From: Alexander Duyck <hidden> Date: 2016-11-10 17:37:23
This patch adds a function that allows us to batch free a page that has
multiple references outstanding. Specifically this function can be used to
drop a page being used in the page frag alloc cache. With this drivers can
make use of functionality similar to the page frag alloc cache without
having to do any workarounds for the fact that there is no function that
frees multiple references.
Signed-off-by: Alexander Duyck <redacted>
---
include/linux/gfp.h | 2 ++
mm/page_alloc.c | 14 ++++++++++++++
2 files changed, 16 insertions(+)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:37:26
The ARM architecture provides a mechanism for deferring cache line
invalidation in the case of map/unmap. This patch makes use of this
mechanism to avoid unnecessary synchronization.
A secondary effect of this change is that the portion of the page that has
been synchronized for use by the CPU should be writable and could be passed
up the stack (at least on ARM).
The last bit that occurred to me is that on architectures where the
sync_for_cpu call invalidates cache lines we were prefetching and then
invalidating the first 128 bytes of the packet. To avoid that I have moved
the sync up to before we perform the prefetch and allocate the skbuff so
that we can actually make use of it.
Acked-by: Jeff Kirsher <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
drivers/net/ethernet/intel/igb/igb_main.c | 53 ++++++++++++++++++-----------
1 file changed, 33 insertions(+), 20 deletions(-)
@@ -3922,10 +3922,21 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring)if(!buffer_info->page)continue;-dma_unmap_page(rx_ring->dev,-buffer_info->dma,-PAGE_SIZE,-DMA_FROM_DEVICE);+/* Invalidate cache lines that may have been written to by+*devicesothatweavoidcorruptingmemory.+*/+dma_sync_single_range_for_cpu(rx_ring->dev,+buffer_info->dma,+buffer_info->page_offset,+IGB_RX_BUFSZ,+DMA_FROM_DEVICE);++/* free resources associated with mapping */+dma_unmap_page_attrs(rx_ring->dev,+buffer_info->dma,+PAGE_SIZE,+DMA_FROM_DEVICE,+DMA_ATTR_SKIP_CPU_SYNC);__free_page(buffer_info->page);buffer_info->page=NULL;
@@ -6791,12 +6802,6 @@ static void igb_reuse_rx_page(struct igb_ring *rx_ring,/* transfer page from old buffer to new buffer */*new_buff=*old_buff;--/* sync the buffer for use by the device */-dma_sync_single_range_for_device(rx_ring->dev,old_buff->dma,-old_buff->page_offset,-IGB_RX_BUFSZ,-DMA_FROM_DEVICE);}staticinlinebooligb_page_is_reserved(structpage*page)
@@ -6917,6 +6922,13 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,page=rx_buffer->page;prefetchw(page);+/* we are reusing so sync this buffer for CPU use */+dma_sync_single_range_for_cpu(rx_ring->dev,+rx_buffer->dma,+rx_buffer->page_offset,+size,+DMA_FROM_DEVICE);+if(likely(!skb)){void*page_addr=page_address(page)+rx_buffer->page_offset;
@@ -6941,21 +6953,15 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,prefetchw(skb->data);}-/* we are reusing so sync this buffer for CPU use */-dma_sync_single_range_for_cpu(rx_ring->dev,-rx_buffer->dma,-rx_buffer->page_offset,-size,-DMA_FROM_DEVICE);-/* pull page into skb */if(igb_add_rx_frag(rx_ring,rx_buffer,size,rx_desc,skb)){/* 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 */-dma_unmap_page(rx_ring->dev,rx_buffer->dma,-PAGE_SIZE,DMA_FROM_DEVICE);+dma_unmap_page_attrs(rx_ring->dev,rx_buffer->dma,+PAGE_SIZE,DMA_FROM_DEVICE,+DMA_ATTR_SKIP_CPU_SYNC);}/* clear contents of rx_buffer */
@@ -7213,7 +7219,8 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,}/* map page for use */-dma=dma_map_page(rx_ring->dev,page,0,PAGE_SIZE,DMA_FROM_DEVICE);+dma=dma_map_page_attrs(rx_ring->dev,page,0,PAGE_SIZE,+DMA_FROM_DEVICE,DMA_ATTR_SKIP_CPU_SYNC);/* if mapping failed free memory back to system since*thereisn'tmuchpointinholdingmemorywecan'tuse
@@ -7254,6 +7261,12 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)if(!igb_alloc_mapped_page(rx_ring,bi))break;+/* sync the buffer for use by the device */+dma_sync_single_range_for_device(rx_ring->dev,bi->dma,+bi->page_offset,+IGB_RX_BUFSZ,+DMA_FROM_DEVICE);+/* Refresh the desc even if buffer_addrs didn't change*becauseeachwrite-backerasesthisinfo.*/--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:37:31
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 <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
drivers/net/ethernet/intel/igb/igb.h | 7 ++++++-
drivers/net/ethernet/intel/igb/igb_main.c | 24 +++++++++++++++++-------
2 files changed, 23 insertions(+), 8 deletions(-)
@@ -6813,13 +6814,15 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,structpage*page,unsignedinttruesize){+unsignedintpagecnt_bias=rx_buffer->pagecnt_bias--;+/* avoid re-using remote pages */if(unlikely(igb_page_is_reserved(page)))returnfalse;#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))returnfalse;/* flip page offset to other buffer */
@@ -6832,10 +6835,14 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,returnfalse;#endif-/* Even if we own the page, we are not allowed to use atomic_set()-*Thiswouldbreakget_page_unless_zero()users.+/* If we have drained the page fragment pool we need to update+*thepagecnt_biasandpagecountsothatwefullyrestockthe+*numberofreferencesthedriverholds.*/-page_ref_inc(page);+if(unlikely(pagecnt_bias==1)){+page_ref_add(page,USHRT_MAX);+rx_buffer->pagecnt_bias=USHRT_MAX;+}returntrue;}
@@ -6887,7 +6894,6 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring,returntrue;/* this page cannot be reused so discard it */-__free_page(page);returnfalse;}
@@ -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+*anyreferencesweareholdingtoit+*/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 */
From: Alexander Duyck <hidden> Date: 2016-11-10 17:39:11
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: Chris Metcalf <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
arch/tile/kernel/pci-dma.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:42:32
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 <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
arch/c6x/kernel/dma.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-10 17:42:34
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 <redacted>
Signed-off-by: Alexander Duyck <redacted>
---
arch/blackfin/kernel/dma-mapping.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Richard Kuo <hidden> Date: 2016-11-10 18:40:19
On Thu, Nov 10, 2016 at 06:34:52AM -0500, Alexander Duyck 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
later via a sync_for_cpu or sync_for_device call.
Cc: Richard Kuo <redacted>
Cc: linux-hexagon@vger.kernel.org
Signed-off-by: Alexander Duyck <redacted>
---
arch/hexagon/kernel/dma.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
For Hexagon:
Acked-by: Richard Kuo <redacted>
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
On 2016-11-10 at 12:35:18 +0100, Alexander Duyck [off-list ref] 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 <redacted>
Signed-off-by: Alexander Duyck <redacted>
From: David Miller <davem@davemloft.net> Date: 2016-11-13 17:27:07
From: Alexander Duyck <redacted>
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 <redacted>
From: Alexander Duyck <hidden> Date: 2016-11-18 16:10:32
On Thu, Nov 10, 2016 at 3:34 AM, Alexander Duyck
[off-list ref] 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
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Andrew Morton <akpm@linux-foundation.org> Date: 2016-11-18 23:27:21
On Thu, 10 Nov 2016 06:36:06 -0500 Alexander Duyck [off-list ref] wrote:
quoted hunk
This patch adds a function that allows us to batch free a page that has
multiple references outstanding. Specifically this function can be used to
drop a page being used in the page frag alloc cache. With this drivers can
make use of functionality similar to the page frag alloc cache without
having to do any workarounds for the fact that there is no function that
frees multiple references.
...
It's an exported-to-modules library function. It should be documented,
please? The page-frag API is only partially documented, but that's no
excuse.
And perhaps documentation will help explain the naming choice. Why
"drain"? I'd have expected "put"?
And why the leading underscores. The page-frag API is pretty weird :(
And inconsistent. __alloc_page_frag -> page_frag_alloc,
__free_page_frag -> page_frag_free(), etc. I must have been asleep
when I let that lot through.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Alexander Duyck <hidden> Date: 2016-11-21 16:21:43
On Fri, Nov 18, 2016 at 3:27 PM, Andrew Morton
[off-list ref] wrote:
On Thu, 10 Nov 2016 06:36:06 -0500 Alexander Duyck [off-list ref] wrote:
quoted
This patch adds a function that allows us to batch free a page that has
multiple references outstanding. Specifically this function can be used to
drop a page being used in the page frag alloc cache. With this drivers can
make use of functionality similar to the page frag alloc cache without
having to do any workarounds for the fact that there is no function that
frees multiple references.
...
It's an exported-to-modules library function. It should be documented,
please? The page-frag API is only partially documented, but that's no
excuse.
Okay. I assume you want the documentation as a follow-up patch since
I received a notice that the patch was added to -mm?
And perhaps documentation will help explain the naming choice. Why
"drain"? I'd have expected "put"?
The idea was that this is supposed to be a counterpart to
__page_frag_refill. Basically it is a function we can use if we need
to tear down the page frag cache and free the backing page. If you
want I could update the names for these functions to make that
clarification that this is meant to drain a frag cache versus just
freeing a page frag. I had originally thought about coming up with an
mput or something like that since we are dropping multiple references,
but then I figured since we already had __page_frag_refill I would go
for __page_frag_drain.
And why the leading underscores. The page-frag API is pretty weird :(
And inconsistent. __alloc_page_frag -> page_frag_alloc,
__free_page_frag -> page_frag_free(), etc. I must have been asleep
when I let that lot through.
The leading underscores are inherited. Most of it has to do with the
fact that this is a backing API for the netdev sk_buff allocator.
When this stuff existed in net it was already named this way and I
just moved it over. I'm not sure if you approved it or not as I don't
see an Ack-by or Signed-off-by from you on the patch. The timing of
it was such that I think Linus approved it and it was then pulled in
through Dave's tree.
If you would like I could look at doing a couple of renaming patches
so that we make the API a bit more consistent. I could move the
__alloc and __free to what you have suggested, and then take a look at
trying to rename the refill/drain to be a bit more consistent in terms
of what they are supposed to work on and how they are supposed to be
used.
- Alex
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
It's an exported-to-modules library function. It should be documented,
please? The page-frag API is only partially documented, but that's no
excuse.
Okay. I assume you want the documentation as a follow-up patch since
I received a notice that the patch was added to -mm?
Yes please. Or a replacement patch which I'll temporarily turn into a
delta, either is fine.
If you would like I could look at doing a couple of renaming patches
so that we make the API a bit more consistent. I could move the
__alloc and __free to what you have suggested, and then take a look at
trying to rename the refill/drain to be a bit more consistent in terms
of what they are supposed to work on and how they are supposed to be
used.
I think that would be better - it's hardly high-priority but a bit of
attention to the documentation and naming conventions would help tidy
things up. When you can't find anything else to do ;)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>