All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions
@ 2013-08-12 11:22 Felix Fietkau
  2013-08-12 11:22 ` [PATCH 2/2] MIPS: partially inline dma ops Felix Fietkau
  2013-08-12 17:04 ` [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions David Daney
  0 siblings, 2 replies; 6+ messages in thread
From: Felix Fietkau @ 2013-08-12 11:22 UTC (permalink / raw)
  To: linux-mips

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h | 12 ------------
 arch/mips/include/asm/mach-generic/dma-coherence.h       | 10 ----------
 arch/mips/include/asm/mach-ip27/dma-coherence.h          | 10 ----------
 arch/mips/include/asm/mach-ip32/dma-coherence.h          | 11 -----------
 arch/mips/include/asm/mach-jazz/dma-coherence.h          | 10 ----------
 arch/mips/include/asm/mach-loongson/dma-coherence.h      | 10 ----------
 arch/mips/include/asm/mach-powertv/dma-coherence.h       | 10 ----------
 arch/mips/mm/dma-default.c                               |  4 +---
 8 files changed, 1 insertion(+), 76 deletions(-)

diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
index 47fb247..f9f4486 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -52,23 +52,11 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 0;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-	BUG();
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 	return 1;
 }
 
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	BUG();
-	return 0;
-}
-
 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h
index 74cb992..a9e8f6b 100644
--- a/arch/mips/include/asm/mach-generic/dma-coherence.h
+++ b/arch/mips/include/asm/mach-generic/dma-coherence.h
@@ -47,16 +47,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 #ifdef CONFIG_DMA_COHERENT
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
index 06c4419..4ffddfd 100644
--- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
@@ -58,16 +58,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 	return 1;		/* IP27 non-cohernet mode is unsupported */
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
index 073f0c4..104cfbc 100644
--- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
@@ -80,17 +80,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-	return;
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 	return 0;		/* IP32 is non-cohernet */
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
index 9fc1e9a..949003e 100644
--- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
+++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
@@ -48,16 +48,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 	return 0;
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
index e143305..aeb2c05 100644
--- a/arch/mips/include/asm/mach-loongson/dma-coherence.h
+++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
@@ -53,16 +53,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 	return 0;
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
index f831672..5d4c3fe 100644
--- a/arch/mips/include/asm/mach-powertv/dma-coherence.h
+++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
@@ -99,16 +99,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 	return 0;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index aaccf1c..63e45d6 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -292,7 +292,6 @@ static void mips_dma_sync_single_for_cpu(struct device *dev,
 static void mips_dma_sync_single_for_device(struct device *dev,
 	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-	plat_extra_sync_for_device(dev);
 	if (!plat_device_is_coherent(dev))
 		__dma_sync(dma_addr_to_page(dev, dma_handle),
 			   dma_handle & ~PAGE_MASK, size, direction);
@@ -326,7 +325,7 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
 
 int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
-	return plat_dma_mapping_error(dev, dma_addr);
+	return 0;
 }
 
 int mips_dma_supported(struct device *dev, u64 mask)
@@ -339,7 +338,6 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 {
 	BUG_ON(direction == DMA_NONE);
 
-	plat_extra_sync_for_device(dev);
 	if (!plat_device_is_coherent(dev))
 		__dma_sync_virtual(vaddr, size, direction);
 }
-- 
1.8.0.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] MIPS: partially inline dma ops
  2013-08-12 11:22 [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions Felix Fietkau
@ 2013-08-12 11:22 ` Felix Fietkau
  2013-08-12 17:08   ` David Daney
  2013-08-12 17:04 ` [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions David Daney
  1 sibling, 1 reply; 6+ messages in thread
From: Felix Fietkau @ 2013-08-12 11:22 UTC (permalink / raw)
  To: linux-mips

Several DMA ops are no-op on many platforms, and the indirection through
the mips_dma_map_ops function table is causing the compiler to emit
unnecessary code.

Inlining visibly improves network performance in my tests (on a 24Kc
based system), and also slightly reduces code size of a few drivers.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 arch/mips/Kconfig                   |   4 +
 arch/mips/include/asm/dma-mapping.h | 360 +++++++++++++++++++++++++++++++++++-
 arch/mips/mm/dma-default.c          | 161 ++--------------
 3 files changed, 372 insertions(+), 153 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index e12764c..c28e51c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1393,6 +1393,7 @@ config CPU_CAVIUM_OCTEON
 	select LIBFDT
 	select USE_OF
 	select USB_EHCI_BIG_ENDIAN_MMIO
+	select SYS_HAS_DMA_OPS
 	help
 	  The Cavium Octeon processor is a highly integrated chip containing
 	  many ethernet hardware widgets for networking tasks. The processor
@@ -1613,6 +1614,9 @@ config SYS_HAS_CPU_XLR
 config SYS_HAS_CPU_XLP
 	bool
 
+config SYS_HAS_DMA_OPS
+	bool
+
 #
 # CPU may reorder R->R, R->W, W->R, W->W
 # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index 84238c5..1780a06 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -1,6 +1,12 @@
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
 
+#include <linux/kmemcheck.h>
+#include <linux/bug.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/dma-attrs.h>
+
 #include <asm/scatterlist.h>
 #include <asm/dma-coherence.h>
 #include <asm/cache.h>
@@ -12,12 +18,47 @@
 
 extern struct dma_map_ops *mips_dma_map_ops;
 
+void __dma_sync(struct page *page, unsigned long offset, size_t size,
+		enum dma_data_direction direction);
+void *mips_dma_alloc_coherent(struct device *dev, size_t size,
+			      dma_addr_t *dma_handle, gfp_t gfp,
+			      struct dma_attrs *attrs);
+void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+			    dma_addr_t dma_handle, struct dma_attrs *attrs);
+
 static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
+#ifdef CONFIG_SYS_HAS_DMA_OPS
 	if (dev && dev->archdata.dma_ops)
 		return dev->archdata.dma_ops;
 	else
 		return mips_dma_map_ops;
+#else
+	return NULL;
+#endif
+}
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+static inline int cpu_is_noncoherent_r10000(struct device *dev)
+{
+#ifndef CONFIG_SYS_HAS_CPU_R10000
+	return 0;
+#endif
+	return !plat_device_is_coherent(dev) &&
+	       (current_cpu_type() == CPU_R10000 ||
+	       current_cpu_type() == CPU_R12000);
+}
+
+static inline struct page *dma_addr_to_page(struct device *dev,
+	dma_addr_t dma_addr)
+{
+	return pfn_to_page(
+		plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT);
 }
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
@@ -30,12 +71,312 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-#include <asm-generic/dma-mapping-common.h>
+static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
+					      size_t size,
+					      enum dma_data_direction dir,
+					      struct dma_attrs *attrs)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	unsigned long offset = (unsigned long)ptr & ~PAGE_MASK;
+	struct page *page = virt_to_page(ptr);
+	dma_addr_t addr;
+
+	kmemcheck_mark_initialized(ptr, size);
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops) {
+		addr = ops->map_page(dev, page, offset, size, dir, attrs);
+	} else {
+		if (!plat_device_is_coherent(dev))
+			__dma_sync(page, offset, size, dir);
+
+		addr = plat_map_dma_mem_page(dev, page) + offset;
+	}
+	debug_dma_map_page(dev, page, offset, size, dir, addr, true);
+	return addr;
+}
+
+static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
+					  size_t size,
+					  enum dma_data_direction dir,
+					  struct dma_attrs *attrs)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops) {
+		ops->unmap_page(dev, addr, size, dir, attrs);
+	} else {
+		if (cpu_is_noncoherent_r10000(dev))
+			__dma_sync(dma_addr_to_page(dev, addr),
+				   addr & ~PAGE_MASK, size, dir);
+
+		plat_unmap_dma_mem(dev, addr, size, dir);
+	}
+	debug_dma_unmap_page(dev, addr, size, dir, true);
+}
+
+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+				   int nents, enum dma_data_direction dir,
+				   struct dma_attrs *attrs)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	int i, ents;
+	struct scatterlist *s;
+
+	for_each_sg(sg, s, nents, i)
+		kmemcheck_mark_initialized(sg_virt(s), s->length);
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops) {
+		ents = ops->map_sg(dev, sg, nents, dir, attrs);
+	} else {
+		for_each_sg(sg, s, nents, i) {
+			struct page *page = sg_page(s);
+
+			if (!plat_device_is_coherent(dev))
+				__dma_sync(page, s->offset, s->length, dir);
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+			s->dma_length = s->length;
+#endif
+			s->dma_address =
+				plat_map_dma_mem_page(dev, page) + s->offset;
+		}
+		ents = nents;
+	}
+	debug_dma_map_sg(dev, sg, nents, ents, dir);
+
+	return ents;
+}
+
+static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
+				      int nents, enum dma_data_direction dir,
+				      struct dma_attrs *attrs)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	struct scatterlist *s;
+	int i;
+
+	BUG_ON(!valid_dma_direction(dir));
+	debug_dma_unmap_sg(dev, sg, nents, dir);
+	if (ops) {
+		ops->unmap_sg(dev, sg, nents, dir, attrs);
+		return;
+	}
+
+	for_each_sg(sg, s, nents, i) {
+		if (!plat_device_is_coherent(dev) && dir != DMA_TO_DEVICE)
+			__dma_sync(sg_page(s), s->offset, s->length, dir);
+		plat_unmap_dma_mem(dev, s->dma_address, s->length, dir);
+	}
+}
+
+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)
+{
+	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));
+	if (ops) {
+		addr = ops->map_page(dev, page, offset, size, dir, NULL);
+	} else {
+		if (!plat_device_is_coherent(dev))
+			__dma_sync(page, offset, size, dir);
+
+		addr = plat_map_dma_mem_page(dev, page) + offset;
+	}
+	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)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops) {
+		ops->unmap_page(dev, addr, size, dir, NULL);
+	} else {
+		if (cpu_is_noncoherent_r10000(dev))
+			__dma_sync(dma_addr_to_page(dev, addr),
+				   addr & ~PAGE_MASK, size, dir);
+
+		plat_unmap_dma_mem(dev, addr, size, dir);
+	}
+	debug_dma_unmap_page(dev, addr, size, dir, false);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+					   size_t size,
+					   enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops)
+		ops->sync_single_for_cpu(dev, addr, size, dir);
+	else if (cpu_is_noncoherent_r10000(dev))
+		__dma_sync(dma_addr_to_page(dev, addr),
+			   addr & ~PAGE_MASK, size, dir);
+	debug_dma_sync_single_for_cpu(dev, addr, size, dir);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+					      dma_addr_t addr, size_t size,
+					      enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops)
+		ops->sync_single_for_device(dev, addr, size, dir);
+	else if (!plat_device_is_coherent(dev))
+		__dma_sync(dma_addr_to_page(dev, addr),
+			   addr & ~PAGE_MASK, size, dir);
+	debug_dma_sync_single_for_device(dev, addr, size, dir);
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+						 dma_addr_t addr,
+						 unsigned long offset,
+						 size_t size,
+						 enum dma_data_direction dir)
+{
+	const struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops)
+		ops->sync_single_for_cpu(dev, addr + offset, size, dir);
+	else if (cpu_is_noncoherent_r10000(dev))
+		__dma_sync(dma_addr_to_page(dev, addr + offset),
+			   (addr + offset) & ~PAGE_MASK, size, dir);
+	debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+						    dma_addr_t addr,
+						    unsigned long offset,
+						    size_t size,
+						    enum dma_data_direction dir)
+{
+	const struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops)
+		ops->sync_single_for_device(dev, addr + offset, size, dir);
+	else if (!plat_device_is_coherent(dev))
+		__dma_sync(dma_addr_to_page(dev, addr + offset),
+			   (addr + offset) & ~PAGE_MASK, size, dir);
+	debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir);
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+		    int nelems, enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	struct scatterlist *s;
+	int i;
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops)
+		ops->sync_sg_for_cpu(dev, sg, nelems, dir);
+	else if (cpu_is_noncoherent_r10000(dev)) {
+		for_each_sg(sg, s, nelems, i)
+			__dma_sync(sg_page(s), s->offset, s->length, dir);
+	}
+	debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+		       int nelems, enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	struct scatterlist *s;
+	int i;
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops)
+		ops->sync_sg_for_device(dev, sg, nelems, dir);
+	else if (!plat_device_is_coherent(dev)) {
+		for_each_sg(sg, s, nelems, i)
+			__dma_sync(sg_page(s), s->offset, s->length, dir);
+	}
+	debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
+
+}
+
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+			   void *cpu_addr, dma_addr_t dma_addr, size_t size);
+
+/**
+ * dma_mmap_attrs - map a coherent DMA allocation into user space
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @vma: vm_area_struct describing requested user mapping
+ * @cpu_addr: kernel CPU-view address returned from dma_alloc_attrs
+ * @handle: device-view address returned from dma_alloc_attrs
+ * @size: size of memory originally requested in dma_alloc_attrs
+ * @attrs: attributes of mapping properties requested in dma_alloc_attrs
+ *
+ * Map a coherent DMA buffer previously allocated by dma_alloc_attrs
+ * into user space.  The coherent DMA buffer must not be freed by the
+ * driver until the user space mapping has been released.
+ */
+static inline int
+dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
+	       dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	BUG_ON(!ops);
+	if (ops && ops->mmap)
+		return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+	return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+
+static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
+		      void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+	DEFINE_DMA_ATTRS(attrs);
+	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+	return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
+}
+
+int
+dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+		       void *cpu_addr, dma_addr_t dma_addr, size_t size);
+
+static inline int
+dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
+		      dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	BUG_ON(!ops);
+	if (ops && ops->get_sgtable)
+		return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
+					attrs);
+	return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
+}
+
+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
+
 
 static inline int dma_supported(struct device *dev, u64 mask)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
-	return ops->dma_supported(dev, mask);
+	if (ops)
+		return ops->dma_supported(dev, mask);
+	return plat_dma_supported(dev, mask);
 }
 
 static inline int dma_mapping_error(struct device *dev, u64 mask)
@@ -43,7 +384,9 @@ static inline int dma_mapping_error(struct device *dev, u64 mask)
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	debug_dma_mapping_error(dev, mask);
-	return ops->mapping_error(dev, mask);
+	if (ops)
+		return ops->mapping_error(dev, mask);
+	return 0;
 }
 
 static inline int
@@ -69,7 +412,11 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 	void *ret;
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	ret = ops->alloc(dev, size, dma_handle, gfp, attrs);
+	if (ops)
+		ret = ops->alloc(dev, size, dma_handle, gfp, attrs);
+	else
+		ret = mips_dma_alloc_coherent(dev, size, dma_handle, gfp,
+					      attrs);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
 
@@ -84,7 +431,10 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	ops->free(dev, size, vaddr, dma_handle, attrs);
+	if (ops)
+		ops->free(dev, size, vaddr, dma_handle, attrs);
+	else
+		mips_dma_free_coherent(dev, size, vaddr, dma_handle, attrs);
 
 	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
 }
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 63e45d6..860f918 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -42,26 +42,6 @@ static int __init setnocoherentio(char *str)
 }
 early_param("nocoherentio", setnocoherentio);
 
-static inline struct page *dma_addr_to_page(struct device *dev,
-	dma_addr_t dma_addr)
-{
-	return pfn_to_page(
-		plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT);
-}
-
-/*
- * Warning on the terminology - Linux calls an uncached area coherent;
- * MIPS terminology calls memory areas with hardware maintained coherency
- * coherent.
- */
-
-static inline int cpu_is_noncoherent_r10000(struct device *dev)
-{
-	return !plat_device_is_coherent(dev) &&
-	       (current_cpu_type() == CPU_R10000 ||
-	       current_cpu_type() == CPU_R12000);
-}
-
 static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
 {
 	gfp_t dma_flag;
@@ -117,8 +97,9 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
 }
 EXPORT_SYMBOL(dma_alloc_noncoherent);
 
-static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs)
+void *mips_dma_alloc_coherent(struct device *dev, size_t size,
+			      dma_addr_t *dma_handle, gfp_t gfp,
+			      struct dma_attrs *attrs)
 {
 	void *ret;
 
@@ -142,6 +123,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
 
 	return ret;
 }
+EXPORT_SYMBOL(mips_dma_alloc_coherent);
 
 
 void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
@@ -152,8 +134,8 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 }
 EXPORT_SYMBOL(dma_free_noncoherent);
 
-static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-	dma_addr_t dma_handle, struct dma_attrs *attrs)
+void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+			    dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	unsigned long addr = (unsigned long) vaddr;
 	int order = get_order(size);
@@ -168,6 +150,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
 
 	free_pages(addr, get_order(size));
 }
+EXPORT_SYMBOL(mips_dma_free_coherent);
 
 static inline void __dma_sync_virtual(void *addr, size_t size,
 	enum dma_data_direction direction)
@@ -196,8 +179,8 @@ static inline void __dma_sync_virtual(void *addr, size_t size,
  * If highmem is not configured then the bulk of this loop gets
  * optimized out.
  */
-static inline void __dma_sync(struct page *page,
-	unsigned long offset, size_t size, enum dma_data_direction direction)
+void __dma_sync(struct page *page, unsigned long offset, size_t size,
+		enum dma_data_direction direction)
 {
 	size_t left = size;
 
@@ -226,112 +209,7 @@ static inline void __dma_sync(struct page *page,
 		left -= len;
 	} while (left);
 }
-
-static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
-	size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
-{
-	if (cpu_is_noncoherent_r10000(dev))
-		__dma_sync(dma_addr_to_page(dev, dma_addr),
-			   dma_addr & ~PAGE_MASK, size, direction);
-
-	plat_unmap_dma_mem(dev, dma_addr, size, direction);
-}
-
-static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
-	int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		if (!plat_device_is_coherent(dev))
-			__dma_sync(sg_page(sg), sg->offset, sg->length,
-				   direction);
-#ifdef CONFIG_NEED_SG_DMA_LENGTH
-		sg->dma_length = sg->length;
-#endif
-		sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) +
-				  sg->offset;
-	}
-
-	return nents;
-}
-
-static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page,
-	unsigned long offset, size_t size, enum dma_data_direction direction,
-	struct dma_attrs *attrs)
-{
-	if (!plat_device_is_coherent(dev))
-		__dma_sync(page, offset, size, direction);
-
-	return plat_map_dma_mem_page(dev, page) + offset;
-}
-
-static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-	int nhwentries, enum dma_data_direction direction,
-	struct dma_attrs *attrs)
-{
-	int i;
-
-	for (i = 0; i < nhwentries; i++, sg++) {
-		if (!plat_device_is_coherent(dev) &&
-		    direction != DMA_TO_DEVICE)
-			__dma_sync(sg_page(sg), sg->offset, sg->length,
-				   direction);
-		plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
-	}
-}
-
-static void mips_dma_sync_single_for_cpu(struct device *dev,
-	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
-{
-	if (cpu_is_noncoherent_r10000(dev))
-		__dma_sync(dma_addr_to_page(dev, dma_handle),
-			   dma_handle & ~PAGE_MASK, size, direction);
-}
-
-static void mips_dma_sync_single_for_device(struct device *dev,
-	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
-{
-	if (!plat_device_is_coherent(dev))
-		__dma_sync(dma_addr_to_page(dev, dma_handle),
-			   dma_handle & ~PAGE_MASK, size, direction);
-}
-
-static void mips_dma_sync_sg_for_cpu(struct device *dev,
-	struct scatterlist *sg, int nelems, enum dma_data_direction direction)
-{
-	int i;
-
-	/* Make sure that gcc doesn't leave the empty loop body.  */
-	for (i = 0; i < nelems; i++, sg++) {
-		if (cpu_is_noncoherent_r10000(dev))
-			__dma_sync(sg_page(sg), sg->offset, sg->length,
-				   direction);
-	}
-}
-
-static void mips_dma_sync_sg_for_device(struct device *dev,
-	struct scatterlist *sg, int nelems, enum dma_data_direction direction)
-{
-	int i;
-
-	/* Make sure that gcc doesn't leave the empty loop body.  */
-	for (i = 0; i < nelems; i++, sg++) {
-		if (!plat_device_is_coherent(dev))
-			__dma_sync(sg_page(sg), sg->offset, sg->length,
-				   direction);
-	}
-}
-
-int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-
-int mips_dma_supported(struct device *dev, u64 mask)
-{
-	return plat_dma_supported(dev, mask);
-}
+EXPORT_SYMBOL(__dma_sync);
 
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 			 enum dma_data_direction direction)
@@ -344,23 +222,10 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 
 EXPORT_SYMBOL(dma_cache_sync);
 
-static struct dma_map_ops mips_default_dma_map_ops = {
-	.alloc = mips_dma_alloc_coherent,
-	.free = mips_dma_free_coherent,
-	.map_page = mips_dma_map_page,
-	.unmap_page = mips_dma_unmap_page,
-	.map_sg = mips_dma_map_sg,
-	.unmap_sg = mips_dma_unmap_sg,
-	.sync_single_for_cpu = mips_dma_sync_single_for_cpu,
-	.sync_single_for_device = mips_dma_sync_single_for_device,
-	.sync_sg_for_cpu = mips_dma_sync_sg_for_cpu,
-	.sync_sg_for_device = mips_dma_sync_sg_for_device,
-	.mapping_error = mips_dma_mapping_error,
-	.dma_supported = mips_dma_supported
-};
-
-struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
+#ifdef CONFIG_SYS_HAS_DMA_OPS
+struct dma_map_ops *mips_dma_map_ops = NULL;
 EXPORT_SYMBOL(mips_dma_map_ops);
+#endif
 
 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
 
-- 
1.8.0.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions
  2013-08-12 11:22 [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions Felix Fietkau
  2013-08-12 11:22 ` [PATCH 2/2] MIPS: partially inline dma ops Felix Fietkau
@ 2013-08-12 17:04 ` David Daney
  2013-08-12 17:16   ` Felix Fietkau
  1 sibling, 1 reply; 6+ messages in thread
From: David Daney @ 2013-08-12 17:04 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-mips

That's a mighty thin changelog there.

You are changing the semantics in the 
asm/mach-cavium-octeon/dma-coherence.h case.

Have you verified that all in-tree cases really are NOPs?

David Daney


On 08/12/2013 04:22 AM, Felix Fietkau wrote:
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
>   arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h | 12 ------------
>   arch/mips/include/asm/mach-generic/dma-coherence.h       | 10 ----------
>   arch/mips/include/asm/mach-ip27/dma-coherence.h          | 10 ----------
>   arch/mips/include/asm/mach-ip32/dma-coherence.h          | 11 -----------
>   arch/mips/include/asm/mach-jazz/dma-coherence.h          | 10 ----------
>   arch/mips/include/asm/mach-loongson/dma-coherence.h      | 10 ----------
>   arch/mips/include/asm/mach-powertv/dma-coherence.h       | 10 ----------
>   arch/mips/mm/dma-default.c                               |  4 +---
>   8 files changed, 1 insertion(+), 76 deletions(-)
>
> diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
> index 47fb247..f9f4486 100644
> --- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
> @@ -52,23 +52,11 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 0;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -	BUG();
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   	return 1;
>   }
>
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	BUG();
> -	return 0;
> -}
> -
>   dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
>   phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
>
> diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h
> index 74cb992..a9e8f6b 100644
> --- a/arch/mips/include/asm/mach-generic/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h
> @@ -47,16 +47,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 1;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -}
> -
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	return 0;
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   #ifdef CONFIG_DMA_COHERENT
> diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
> index 06c4419..4ffddfd 100644
> --- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
> @@ -58,16 +58,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 1;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -}
> -
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	return 0;
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   	return 1;		/* IP27 non-cohernet mode is unsupported */
> diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
> index 073f0c4..104cfbc 100644
> --- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
> @@ -80,17 +80,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 1;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -	return;
> -}
> -
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	return 0;
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   	return 0;		/* IP32 is non-cohernet */
> diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
> index 9fc1e9a..949003e 100644
> --- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
> @@ -48,16 +48,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 1;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -}
> -
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	return 0;
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   	return 0;
> diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
> index e143305..aeb2c05 100644
> --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
> @@ -53,16 +53,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 1;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -}
> -
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	return 0;
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   	return 0;
> diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
> index f831672..5d4c3fe 100644
> --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
> @@ -99,16 +99,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
>   	return 1;
>   }
>
> -static inline void plat_extra_sync_for_device(struct device *dev)
> -{
> -}
> -
> -static inline int plat_dma_mapping_error(struct device *dev,
> -					 dma_addr_t dma_addr)
> -{
> -	return 0;
> -}
> -
>   static inline int plat_device_is_coherent(struct device *dev)
>   {
>   	return 0;
> diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
> index aaccf1c..63e45d6 100644
> --- a/arch/mips/mm/dma-default.c
> +++ b/arch/mips/mm/dma-default.c
> @@ -292,7 +292,6 @@ static void mips_dma_sync_single_for_cpu(struct device *dev,
>   static void mips_dma_sync_single_for_device(struct device *dev,
>   	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
>   {
> -	plat_extra_sync_for_device(dev);
>   	if (!plat_device_is_coherent(dev))
>   		__dma_sync(dma_addr_to_page(dev, dma_handle),
>   			   dma_handle & ~PAGE_MASK, size, direction);
> @@ -326,7 +325,7 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
>
>   int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
>   {
> -	return plat_dma_mapping_error(dev, dma_addr);
> +	return 0;
>   }
>
>   int mips_dma_supported(struct device *dev, u64 mask)
> @@ -339,7 +338,6 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
>   {
>   	BUG_ON(direction == DMA_NONE);
>
> -	plat_extra_sync_for_device(dev);
>   	if (!plat_device_is_coherent(dev))
>   		__dma_sync_virtual(vaddr, size, direction);
>   }
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] MIPS: partially inline dma ops
  2013-08-12 11:22 ` [PATCH 2/2] MIPS: partially inline dma ops Felix Fietkau
@ 2013-08-12 17:08   ` David Daney
  2013-08-12 17:22     ` Felix Fietkau
  0 siblings, 1 reply; 6+ messages in thread
From: David Daney @ 2013-08-12 17:08 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-mips

On 08/12/2013 04:22 AM, Felix Fietkau wrote:
> Several DMA ops are no-op on many platforms, and the indirection through
> the mips_dma_map_ops function table is causing the compiler to emit
> unnecessary code.
>
> Inlining visibly improves network performance in my tests (on a 24Kc
> based system), and also slightly reduces code size of a few drivers.
>
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
>   arch/mips/Kconfig                   |   4 +
>   arch/mips/include/asm/dma-mapping.h | 360 +++++++++++++++++++++++++++++++++++-
>   arch/mips/mm/dma-default.c          | 161 ++--------------
>   3 files changed, 372 insertions(+), 153 deletions(-)
>

That is not a very pleasing diffstat.


David

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions
  2013-08-12 17:04 ` [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions David Daney
@ 2013-08-12 17:16   ` Felix Fietkau
  0 siblings, 0 replies; 6+ messages in thread
From: Felix Fietkau @ 2013-08-12 17:16 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips

On 2013-08-12 7:04 PM, David Daney wrote:
> That's a mighty thin changelog there.
I thought it was obvious that the lines I removed contain no useful code
at all :)

> You are changing the semantics in the 
> asm/mach-cavium-octeon/dma-coherence.h case.
I'm just removing a fallback BUG() that could never be reached before my
change either. As for the other platforms, I verified that there's no
useful code in these functions anywhere in the tree.

> Have you verified that all in-tree cases really are NOPs?
Yes.

- Felix

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] MIPS: partially inline dma ops
  2013-08-12 17:08   ` David Daney
@ 2013-08-12 17:22     ` Felix Fietkau
  0 siblings, 0 replies; 6+ messages in thread
From: Felix Fietkau @ 2013-08-12 17:22 UTC (permalink / raw)
  To: David Daney; +Cc: linux-mips

On 2013-08-12 7:08 PM, David Daney wrote:
> On 08/12/2013 04:22 AM, Felix Fietkau wrote:
>> Several DMA ops are no-op on many platforms, and the indirection through
>> the mips_dma_map_ops function table is causing the compiler to emit
>> unnecessary code.
>>
>> Inlining visibly improves network performance in my tests (on a 24Kc
>> based system), and also slightly reduces code size of a few drivers.
>>
>> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>> ---
>>   arch/mips/Kconfig                   |   4 +
>>   arch/mips/include/asm/dma-mapping.h | 360 +++++++++++++++++++++++++++++++++++-
>>   arch/mips/mm/dma-default.c          | 161 ++--------------
>>   3 files changed, 372 insertions(+), 153 deletions(-)
> That is not a very pleasing diffstat.
I know. But altering the generic include (of which I duplicated the
inlined code here) would make things even worse. I believe the
improvement in the generated code is worth it though.
I just did some fresh performance tests with an 400 MHz AR7242 system
(MIPS 24Kc), bridging packets from one Ethernet port to another. I'm
running TCP iperf through this device.
Without this patch, I get 710-760 MBit/s with heavy fluctuation.
With this patch, I get 780-790 MBit/s with little fluctuation.
Most other MIPS systems will probably see similar improvements in DMA
heavy drivers.
For Octeon, I don't expect any visible performance change, and the
change shouldn't make it any worse either.

- Felix

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-08-12 17:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-12 11:22 [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions Felix Fietkau
2013-08-12 11:22 ` [PATCH 2/2] MIPS: partially inline dma ops Felix Fietkau
2013-08-12 17:08   ` David Daney
2013-08-12 17:22     ` Felix Fietkau
2013-08-12 17:04 ` [PATCH 1/2] MIPS: remove unnecessary platform dma helper functions David Daney
2013-08-12 17:16   ` Felix Fietkau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.