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


Groups > linux.kernel > #1514015 > unrolled thread

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

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

Back to article view | Back to linux.kernel


Contents

  [mm PATCH v2 00/26] Add support for DMA writable pages being  writable by the network stack Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg  and swiotlb_unmap_sg Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
      Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions  swiotlb_map_sg and swiotlb_unmap_sg Christoph Hellwig <hch@infradead.org> - 2016-11-03 15:20 +0100
        Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions  swiotlb_map_sg and swiotlb_unmap_sg Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> - 2016-11-03 15:40 +0100
          Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions  swiotlb_map_sg and swiotlb_unmap_sg Christoph Hellwig <hch@infradead.org> - 2016-11-03 15:50 +0100
            RE: [mm PATCH v2 01/26] swiotlb: Drop unused functions  swiotlb_map_sg and swiotlb_unmap_sg "Duyck, Alexander H" <alexander.h.duyck@intel.com> - 2016-11-03 16:10 +0100
    [mm PATCH v2 06/26] arch/avr32: Add option to skip sync on DMA map Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 23/26] dma: Add calls for dma_map_page_attrs and  dma_unmap_page_attrs Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 21/26] arch/tile: Add option to skip DMA sync as a  part of map and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 04/26] arch/arc: Add option to skip sync on DMA mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 09/26] arch/frv: Add option to skip sync on DMA map Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 26/26] igb: Update code to better handle incrementing  page count Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 12/26] arch/metag: Add option to skip DMA sync as a  part of map and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 08/26] arch/c6x: Add option to skip sync on DMA map  and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 24/26] mm: Add support for releasing multiple  instances of a page Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 16/26] arch/openrisc: Add option to skip DMA sync as a  part of mapping Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:20 +0100
    [mm PATCH v2 13/26] arch/microblaze: Add option to skip DMA sync as  a part of map and unmap Alexander Duyck <alexander.h.duyck@intel.com> - 2016-11-02 18:30 +0100

#1514015 — [mm PATCH v2 00/26] Add support for DMA writable pages being writable by the network stack

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 00/26] Add support for DMA writable pages being writable by the network stack
Message-ID<sz7mF-J6-3@gated-at.bofh.it>
The first 22 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 23 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 24 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 reimpelement the use of build_skb.

v1: Split out changes DMA_ERROR_CODE fix for swiotlb-xen
    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
    Added swiotlb_unmap_sg to functions dropped in patch 1, dropped Acked-by
    Submitting patches to mm instead of net-next

---

Alexander Duyck (26):
      swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
      swiotlb-xen: Enforce return of DMA_ERROR_CODE in mapping function
      swiotlb: Add support for DMA_ATTR_SKIP_CPU_SYNC
      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/arm/xen/mm.c                         |    1 
 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/x86/xen/pci-swiotlb-xen.c            |    1 
 arch/xtensa/kernel/pci-dma.c              |    7 ++-
 drivers/net/ethernet/intel/igb/igb.h      |    7 ++-
 drivers/net/ethernet/intel/igb/igb_main.c |   77 +++++++++++++++++++----------
 drivers/xen/swiotlb-xen.c                 |   27 +++++-----
 include/linux/dma-mapping.h               |   20 +++++---
 include/linux/gfp.h                       |    2 +
 include/linux/swiotlb.h                   |   14 ++---
 include/xen/swiotlb-xen.h                 |    3 -
 lib/swiotlb.c                             |   64 +++++++++++-------------
 mm/page_alloc.c                           |   14 +++++
 33 files changed, 291 insertions(+), 154 deletions(-)

--

[toc] | [next] | [standalone]


#1514016 — [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
Message-ID<sz7mG-J6-55@gated-at.bofh.it>
In reply to#1514015
There are no users for swiotlb_map_sg or swiotlb_unmap_sg so we might as
well just drop them.

Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---

v2: Added swiotlb_unmap_sg to functions dropped.

 include/linux/swiotlb.h |    8 --------
 lib/swiotlb.c           |   16 ----------------
 2 files changed, 24 deletions(-)

diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 5f81f8a..f0d2589 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -73,14 +73,6 @@ extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 			       unsigned long attrs);
 
 extern int
-swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-	       enum dma_data_direction dir);
-
-extern void
-swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-		 enum dma_data_direction dir);
-
-extern int
 swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
 		     enum dma_data_direction dir,
 		     unsigned long attrs);
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 22e13a0..5005316 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -910,14 +910,6 @@ void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 }
 EXPORT_SYMBOL(swiotlb_map_sg_attrs);
 
-int
-swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
-	       enum dma_data_direction dir)
-{
-	return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, 0);
-}
-EXPORT_SYMBOL(swiotlb_map_sg);
-
 /*
  * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
  * concerning calls here are the same as for swiotlb_unmap_page() above.
@@ -938,14 +930,6 @@ void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 }
 EXPORT_SYMBOL(swiotlb_unmap_sg_attrs);
 
-void
-swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
-		 enum dma_data_direction dir)
-{
-	return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, 0);
-}
-EXPORT_SYMBOL(swiotlb_unmap_sg);
-
 /*
  * Make physical memory consistent for a set of streaming mode DMA translations
  * after a transfer.

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


#1514548 — Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg

FromChristoph Hellwig <hch@infradead.org>
Date2016-11-03 15:20 +0100
SubjectRe: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
Message-ID<szr22-4Zd-17@gated-at.bofh.it>
In reply to#1514016
On Wed, Nov 02, 2016 at 07:12:31AM -0400, Alexander Duyck wrote:
> There are no users for swiotlb_map_sg or swiotlb_unmap_sg so we might as
> well just drop them.

FYI, I sent the same patch already on Sep, 11 and Konrad already ACKed
it:

https://lkml.org/lkml/2016/9/11/112
https://lkml.org/lkml/2016/9/16/474

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


#1514557 — Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg

FromKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date2016-11-03 15:40 +0100
SubjectRe: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
Message-ID<szrlo-55s-17@gated-at.bofh.it>
In reply to#1514548
On Thu, Nov 03, 2016 at 07:14:46AM -0700, Christoph Hellwig wrote:
> On Wed, Nov 02, 2016 at 07:12:31AM -0400, Alexander Duyck wrote:
> > There are no users for swiotlb_map_sg or swiotlb_unmap_sg so we might as
> > well just drop them.
> 
> FYI, I sent the same patch already on Sep, 11 and Konrad already ACKed
> it:
> 
> https://lkml.org/lkml/2016/9/11/112
> https://lkml.org/lkml/2016/9/16/474

Somehow I thought you wanted to put them through your tree (which
is why I acked them).

I can take them and also the first couple of Alexander through
my tree. Or if it makes it simpler - they can go through the -mm tree?

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


#1514562 — Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg

FromChristoph Hellwig <hch@infradead.org>
Date2016-11-03 15:50 +0100
SubjectRe: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
Message-ID<szrv4-58U-15@gated-at.bofh.it>
In reply to#1514557
On Thu, Nov 03, 2016 at 10:29:52AM -0400, Konrad Rzeszutek Wilk wrote:
> Somehow I thought you wanted to put them through your tree (which
> is why I acked them).
> 
> I can take them and also the first couple of Alexander through
> my tree. Or if it makes it simpler - they can go through the -mm tree?

I don't have a tree for it, so I kinda expected you to pick it up.
But I'm also fine with you just Acking the version from Alex and having
him funnel it through whatever tree he wants to get his patches in
through.

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


#1514595 — RE: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg

From"Duyck, Alexander H" <alexander.h.duyck@intel.com>
Date2016-11-03 16:10 +0100
SubjectRE: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
Message-ID<szrOq-5vm-27@gated-at.bofh.it>
In reply to#1514562
> -----Original Message-----
> From: Christoph Hellwig [mailto:hch@infradead.org]
> Sent: Thursday, November 3, 2016 7:46 AM
> To: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Christoph Hellwig <hch@infradead.org>; Duyck, Alexander H
> <alexander.h.duyck@intel.com>; linux-mm@kvack.org; akpm@linux-
> foundation.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions
> swiotlb_map_sg and swiotlb_unmap_sg
> 
> On Thu, Nov 03, 2016 at 10:29:52AM -0400, Konrad Rzeszutek Wilk wrote:
> > Somehow I thought you wanted to put them through your tree (which is
> > why I acked them).
> >
> > I can take them and also the first couple of Alexander through my
> > tree. Or if it makes it simpler - they can go through the -mm tree?
> 
> I don't have a tree for it, so I kinda expected you to pick it up.
> But I'm also fine with you just Acking the version from Alex and having him
> funnel it through whatever tree he wants to get his patches in through.

For the first 3 patches in my series I am fine with them being pulled into the swiotlb tree.  So if you want to pull Christoph's two patches, and then drop my duplicate patch and instead pull the next 2 I could submit a v3 of my series without the swiotlb patches in it.

At this point I have redone my series so that I technically don't have anything with a hard dependency on the DMA_ATTR_SKIP_CPU_SYNC actually doing anything yet.  My plan is to get this all into Linus's tree first via whatever tree I can get these patches pulled into and once I have all that I will start updating drivers in net-next.

Thanks.

- Alex

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


#1514017 — [mm PATCH v2 06/26] arch/avr32: Add option to skip sync on DMA map

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 06/26] arch/avr32: Add option to skip sync on DMA map
Message-ID<sz7mG-J6-53@gated-at.bofh.it>
In reply to#1514015
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]


#1514020 — [mm PATCH v2 23/26] dma: Add calls for dma_map_page_attrs and dma_unmap_page_attrs

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 23/26] dma: Add calls for dma_map_page_attrs and dma_unmap_page_attrs
Message-ID<sz7mH-J6-65@gated-at.bofh.it>
In reply to#1514015
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 <alexander.h.duyck@intel.com>
---
 include/linux/dma-mapping.h |   20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 08528af..10c5a17 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -243,29 +243,33 @@ static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg
 		ops->unmap_sg(dev, sg, nents, dir, attrs);
 }
 
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-				      size_t offset, size_t size,
-				      enum dma_data_direction dir)
+static inline dma_addr_t dma_map_page_attrs(struct device *dev,
+					    struct page *page,
+					    size_t offset, size_t size,
+					    enum dma_data_direction dir,
+					    unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	dma_addr_t addr;
 
 	kmemcheck_mark_initialized(page_address(page) + offset, size);
 	BUG_ON(!valid_dma_direction(dir));
-	addr = ops->map_page(dev, page, offset, size, dir, 0);
+	addr = ops->map_page(dev, page, offset, size, dir, attrs);
 	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
 
 	return addr;
 }
 
-static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
-				  size_t size, enum dma_data_direction dir)
+static inline void dma_unmap_page_attrs(struct device *dev,
+					dma_addr_t addr, size_t size,
+					enum dma_data_direction dir,
+					unsigned long attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	BUG_ON(!valid_dma_direction(dir));
 	if (ops->unmap_page)
-		ops->unmap_page(dev, addr, size, dir, 0);
+		ops->unmap_page(dev, addr, size, dir, attrs);
 	debug_dma_unmap_page(dev, addr, size, dir, false);
 }
 
@@ -385,6 +389,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
 #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
 #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
 #define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, 0)
+#define dma_map_page(d, p, o, s, r) dma_map_page_attrs(d, p, o, s, r, 0)
+#define dma_unmap_page(d, a, s, r) dma_unmap_page_attrs(d, a, s, r, 0)
 
 extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 			   void *cpu_addr, dma_addr_t dma_addr, size_t size);

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


#1514022 — [mm PATCH v2 21/26] arch/tile: Add option to skip DMA sync as a part of map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 21/26] arch/tile: Add option to skip DMA sync as a part of map and unmap
Message-ID<sz7mH-J6-71@gated-at.bofh.it>
In reply to#1514015
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 <cmetcalf@mellanox.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/tile/kernel/pci-dma.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index 09bb774..24e0f8c 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -213,10 +213,12 @@ static int tile_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 
 	for_each_sg(sglist, sg, nents, i) {
 		sg->dma_address = sg_phys(sg);
-		__dma_prep_pa_range(sg->dma_address, sg->length, direction);
 #ifdef CONFIG_NEED_SG_DMA_LENGTH
 		sg->dma_length = sg->length;
 #endif
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+		__dma_prep_pa_range(sg->dma_address, sg->length, direction);
 	}
 
 	return nents;
@@ -232,6 +234,8 @@ static void tile_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
 	BUG_ON(!valid_dma_direction(direction));
 	for_each_sg(sglist, sg, nents, i) {
 		sg->dma_address = sg_phys(sg);
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
 		__dma_complete_pa_range(sg->dma_address, sg->length,
 					direction);
 	}
@@ -245,7 +249,8 @@ static dma_addr_t tile_dma_map_page(struct device *dev, struct page *page,
 	BUG_ON(!valid_dma_direction(direction));
 
 	BUG_ON(offset + size > PAGE_SIZE);
-	__dma_prep_page(page, offset, size, direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		__dma_prep_page(page, offset, size, direction);
 
 	return page_to_pa(page) + offset;
 }
@@ -256,6 +261,9 @@ static void tile_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
 {
 	BUG_ON(!valid_dma_direction(direction));
 
+	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+		return;
+
 	__dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)),
 			    dma_address & (PAGE_SIZE - 1), size, direction);
 }

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


#1514023 — [mm PATCH v2 04/26] arch/arc: Add option to skip sync on DMA mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 04/26] arch/arc: Add option to skip sync on DMA mapping
Message-ID<sz7mH-J6-69@gated-at.bofh.it>
In reply to#1514015
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 <vgupta@synopsys.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/arc/mm/dma.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 60aab5a..ea207d2 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -133,7 +133,10 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
 		unsigned long attrs)
 {
 	phys_addr_t paddr = page_to_phys(page) + offset;
-	_dma_cache_sync(paddr, size, dir);
+
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		_dma_cache_sync(paddr, size, dir);
+
 	return plat_phys_to_dma(dev, paddr);
 }
 

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


#1514024 — [mm PATCH v2 09/26] arch/frv: Add option to skip sync on DMA map

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 09/26] arch/frv: Add option to skip sync on DMA map
Message-ID<sz7mH-J6-73@gated-at.bofh.it>
In reply to#1514015
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 <alexander.h.duyck@intel.com>
---
 arch/frv/mb93090-mb00/pci-dma-nommu.c |   14 ++++++++++----
 arch/frv/mb93090-mb00/pci-dma.c       |    9 +++++++--
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 90f2e4c..1876881 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -109,16 +109,19 @@ static int frv_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 		int nents, enum dma_data_direction direction,
 		unsigned long attrs)
 {
-	int i;
 	struct scatterlist *sg;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+		return nents;
 
 	for_each_sg(sglist, sg, nents, i) {
 		frv_cache_wback_inv(sg_dma_address(sg),
 				    sg_dma_address(sg) + sg_dma_len(sg));
 	}
 
-	BUG_ON(direction == DMA_NONE);
-
 	return nents;
 }
 
@@ -127,7 +130,10 @@ static dma_addr_t frv_dma_map_page(struct device *dev, struct page *page,
 		enum dma_data_direction direction, unsigned long attrs)
 {
 	BUG_ON(direction == DMA_NONE);
-	flush_dcache_page(page);
+
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		flush_dcache_page(page);
+
 	return (dma_addr_t) page_to_phys(page) + offset;
 }
 
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index f585745..dba7df9 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -40,13 +40,16 @@ static int frv_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 		int nents, enum dma_data_direction direction,
 		unsigned long attrs)
 {
+	struct scatterlist *sg;
 	unsigned long dampr2;
 	void *vaddr;
 	int i;
-	struct scatterlist *sg;
 
 	BUG_ON(direction == DMA_NONE);
 
+	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+		return nents;
+
 	dampr2 = __get_DAMPR(2);
 
 	for_each_sg(sglist, sg, nents, i) {
@@ -70,7 +73,9 @@ static dma_addr_t frv_dma_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size,
 		enum dma_data_direction direction, unsigned long attrs)
 {
-	flush_dcache_page(page);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		flush_dcache_page(page);
+
 	return (dma_addr_t) page_to_phys(page) + offset;
 }
 

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


#1514026 — [mm PATCH v2 26/26] igb: Update code to better handle incrementing page count

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 26/26] igb: Update code to better handle incrementing page count
Message-ID<sz7mH-J6-81@gated-at.bofh.it>
In reply to#1514015
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 d11093d..acbc3ab 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 c8c458c..5e66cde 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -3962,7 +3962,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;
 	}
@@ -6830,13 +6831,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 */
@@ -6849,10 +6852,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;
 }
@@ -6904,7 +6911,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;
 	}
 
@@ -6975,10 +6981,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 */
@@ -7252,6 +7261,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]


#1514027 — [mm PATCH v2 12/26] arch/metag: Add option to skip DMA sync as a part of map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 12/26] arch/metag: Add option to skip DMA sync as a part of map and unmap
Message-ID<sz7mH-J6-85@gated-at.bofh.it>
In reply to#1514015
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 <james.hogan@imgtec.com>
Cc: linux-metag@vger.kernel.org
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
 arch/metag/kernel/dma.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/metag/kernel/dma.c b/arch/metag/kernel/dma.c
index 0db31e2..91968d9 100644
--- a/arch/metag/kernel/dma.c
+++ b/arch/metag/kernel/dma.c
@@ -484,8 +484,9 @@ static dma_addr_t metag_dma_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size,
 		enum dma_data_direction direction, unsigned long attrs)
 {
-	dma_sync_for_device((void *)(page_to_phys(page) + offset), size,
-			    direction);
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		dma_sync_for_device((void *)(page_to_phys(page) + offset),
+				    size, direction);
 	return page_to_phys(page) + offset;
 }
 
@@ -493,7 +494,8 @@ static void metag_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 int metag_dma_map_sg(struct device *dev, struct scatterlist *sglist,
@@ -507,6 +509,10 @@ static int metag_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 		BUG_ON(!sg_page(sg));
 
 		sg->dma_address = sg_phys(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		dma_sync_for_device(sg_virt(sg), sg->length, direction);
 	}
 
@@ -525,6 +531,10 @@ static void metag_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
 		BUG_ON(!sg_page(sg));
 
 		sg->dma_address = sg_phys(sg);
+
+		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
+			continue;
+
 		dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
 	}
 }

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


#1514028 — [mm PATCH v2 08/26] arch/c6x: Add option to skip sync on DMA map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 08/26] arch/c6x: Add option to skip sync on DMA map and unmap
Message-ID<sz7mH-J6-77@gated-at.bofh.it>
In reply to#1514015
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]


#1514030 — [mm PATCH v2 24/26] mm: Add support for releasing multiple instances of a page

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 24/26] mm: Add support for releasing multiple instances of a page
Message-ID<sz7mH-J6-87@gated-at.bofh.it>
In reply to#1514015
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 <alexander.h.duyck@intel.com>
---
 include/linux/gfp.h |    2 ++
 mm/page_alloc.c     |   14 ++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index f8041f9de..4175dca 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -506,6 +506,8 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order,
 extern void free_hot_cold_page_list(struct list_head *list, bool cold);
 
 struct page_frag_cache;
+extern void __page_frag_drain(struct page *page, unsigned int order,
+			      unsigned int count);
 extern void *__alloc_page_frag(struct page_frag_cache *nc,
 			       unsigned int fragsz, gfp_t gfp_mask);
 extern void __free_page_frag(void *addr);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 65e0b51..bb6d7bd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3938,6 +3938,20 @@ static struct page *__page_frag_refill(struct page_frag_cache *nc,
 	return page;
 }
 
+void __page_frag_drain(struct page *page, unsigned int order,
+		       unsigned int count)
+{
+	VM_BUG_ON_PAGE(page_ref_count(page) == 0, page);
+
+	if (page_ref_sub_and_test(page, count)) {
+		if (order == 0)
+			free_hot_cold_page(page, false);
+		else
+			__free_pages_ok(page, order);
+	}
+}
+EXPORT_SYMBOL(__page_frag_drain);
+
 void *__alloc_page_frag(struct page_frag_cache *nc,
 			unsigned int fragsz, gfp_t gfp_mask)
 {

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


#1514031 — [mm PATCH v2 16/26] arch/openrisc: Add option to skip DMA sync as a part of mapping

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:20 +0100
Subject[mm PATCH v2 16/26] arch/openrisc: Add option to skip DMA sync as a part of mapping
Message-ID<sz7mH-J6-83@gated-at.bofh.it>
In reply to#1514015
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 @@
 	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]


#1514041 — [mm PATCH v2 13/26] arch/microblaze: Add option to skip DMA sync as a part of map and unmap

FromAlexander Duyck <alexander.h.duyck@intel.com>
Date2016-11-02 18:30 +0100
Subject[mm PATCH v2 13/26] arch/microblaze: Add option to skip DMA sync as a part of map and unmap
Message-ID<sz7wm-Mi-29@gated-at.bofh.it>
In reply to#1514015
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] | [standalone]


Back to top | Article view | linux.kernel


csiph-web