Hi,
This patch set introduces dma-api debugging facility on ARM, and is
against -rc2-next tree.
From: Ming Lei <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
---
arch/arm/common/dmabounce.c | 12 +++---
arch/arm/include/asm/dma-mapping.h | 67 +++++++++++++++++++++++++++++++-----
arch/arm/mm/dma-mapping.c | 24 ++++++------
3 files changed, 76 insertions(+), 27 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 734ac91..15353a3 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -330,7 +330,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
* substitute the safe buffer for the unsafe one.
* (basically move the buffer from an unsafe area to a safe one)
*/
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction dir)
{
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -340,9 +340,9 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
return map_single(dev, ptr, size, dir);
}
-EXPORT_SYMBOL(dma_map_single);
+EXPORT_SYMBOL(__dma_map_single);
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
+dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
@@ -358,7 +358,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
return map_single(dev, page_address(page) + offset, size, dir);
}
-EXPORT_SYMBOL(dma_map_page);
+EXPORT_SYMBOL(__dma_map_page);
/*
* see if a mapped address was really a "safe" buffer and if so, copy
@@ -367,7 +367,7 @@ EXPORT_SYMBOL(dma_map_page);
* should be)
*/
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -375,7 +375,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
unmap_single(dev, dma_addr, size, dir);
}
-EXPORT_SYMBOL(dma_unmap_single);
+EXPORT_SYMBOL(__dma_unmap_single);
int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
unsigned long off, size_t sz, enum dma_data_direction dir)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index ff46dfa..0e87498 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -129,6 +129,9 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
{
}
+extern void *__dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
+extern void __dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
+
/**
* dma_alloc_coherent - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -140,7 +143,11 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
* return the CPU-viewed address, and sets @handle to be the
* device-viewed address.
*/
-extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp)
+{
+ return __dma_alloc_coherent(dev, size, handle, gfp);
+}
/**
* dma_free_coherent - free memory allocated by dma_alloc_coherent
@@ -155,7 +162,11 @@ extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
* References to memory and mappings associated with cpu_addr/handle
* during and after this call executing are illegal.
*/
-extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t handle)
+{
+ __dma_free_coherent(dev, size, cpu_addr, handle);
+}
/**
* dma_mmap_coherent - map a coherent DMA allocation into user space
@@ -255,13 +266,29 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
/*
* The DMA API, implemented by dmabounce.c. See below for descriptions.
*/
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
enum dma_data_direction);
-extern dma_addr_t dma_map_page(struct device *, struct page *,
+extern dma_addr_t __dma_map_page(struct device *, struct page *,
unsigned long, size_t, enum dma_data_direction);
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ return __dma_map_single(dev, cpu_addr, size, dir);
+}
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ return __dma_map_page(dev, page, offset, size, dir);
+}
+static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_unmap_single(dev, handle, size, dir);
+}
+
/*
* Private functions
*/
@@ -429,15 +456,37 @@ static inline void dma_sync_single_for_device(struct device *dev,
/*
* The scatter list versions of the above methods.
*/
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
+extern int __dma_map_sg(struct device *, struct scatterlist *, int,
enum dma_data_direction);
-extern void dma_unmap_sg(struct device *, struct scatterlist *, int,
+extern void __dma_unmap_sg(struct device *, struct scatterlist *, int,
enum dma_data_direction);
-extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
+extern void __dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+extern void __dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
enum dma_data_direction);
+static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ return __dma_map_sg(dev, sg, nents, dir);
+}
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ __dma_unmap_sg(dev, sg, nents, dir);
+}
+static inline void dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ __dma_sync_sg_for_cpu(dev, sg, nents, dir);
+}
+static inline void dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ __dma_sync_sg_for_device(dev, sg, nents, dir);
+}
#endif /* __KERNEL__ */
#endif
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 510c179..654cd82 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -273,7 +273,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
* virtual and bus address for that space.
*/
void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+__dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
void *memory;
@@ -294,7 +294,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
return __dma_alloc(dev, size, handle, gfp,
pgprot_noncached(pgprot_kernel));
}
-EXPORT_SYMBOL(dma_alloc_coherent);
+EXPORT_SYMBOL(__dma_alloc_coherent);
/*
* Allocate a writecombining region, in much the same way as
@@ -358,7 +358,7 @@ EXPORT_SYMBOL(dma_mmap_writecombine);
* free a page as defined by the above mapping.
* Must not be called with IRQs disabled.
*/
-void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
+void __dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
{
struct arm_vm_region *c;
unsigned long flags, addr;
@@ -444,7 +444,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
__func__, cpu_addr);
dump_stack();
}
-EXPORT_SYMBOL(dma_free_coherent);
+EXPORT_SYMBOL(__dma_free_coherent);
/*
* Initialise the consistent memory allocation.
@@ -602,7 +602,7 @@ EXPORT_SYMBOL(dma_cache_maint_page);
* Device ownership issues as mentioned for dma_map_single are the same
* here.
*/
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+int __dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
struct scatterlist *s;
@@ -621,7 +621,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
return 0;
}
-EXPORT_SYMBOL(dma_map_sg);
+EXPORT_SYMBOL(__dma_map_sg);
/**
* dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
@@ -633,7 +633,7 @@ EXPORT_SYMBOL(dma_map_sg);
* Unmap a set of streaming mode DMA translations. Again, CPU access
* rules concerning calls here are the same as for dma_unmap_single().
*/
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+void __dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
struct scatterlist *s;
@@ -642,7 +642,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
for_each_sg(sg, s, nents, i)
dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
}
-EXPORT_SYMBOL(dma_unmap_sg);
+EXPORT_SYMBOL(__dma_unmap_sg);
/**
* dma_sync_sg_for_cpu
@@ -651,7 +651,7 @@ EXPORT_SYMBOL(dma_unmap_sg);
* @nents: number of buffers to map (returned from dma_map_sg)
* @dir: DMA transfer direction (same as was passed to dma_map_sg)
*/
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+void __dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
struct scatterlist *s;
@@ -662,7 +662,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
sg_dma_len(s), dir);
}
}
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+EXPORT_SYMBOL(__dma_sync_sg_for_cpu);
/**
* dma_sync_sg_for_device
@@ -671,7 +671,7 @@ EXPORT_SYMBOL(dma_sync_sg_for_cpu);
* @nents: number of buffers to map (returned from dma_map_sg)
* @dir: DMA transfer direction (same as was passed to dma_map_sg)
*/
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+void __dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
struct scatterlist *s;
@@ -687,4 +687,4 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
s->length, dir);
}
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
+EXPORT_SYMBOL(__dma_sync_sg_for_device);
--
1.6.0.GIT
From: Ming Lei <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
---
arch/arm/include/asm/dma-mapping.h | 53 +++++++++++++++++-------------------
1 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 0e87498..86f2964 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -273,22 +273,6 @@ extern dma_addr_t __dma_map_page(struct device *, struct page *,
extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
-static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, enum dma_data_direction dir)
-{
- return __dma_map_single(dev, cpu_addr, size, dir);
-}
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir)
-{
- return __dma_map_page(dev, page, offset, size, dir);
-}
-static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- __dma_unmap_single(dev, handle, size, dir);
-}
-
/*
* Private functions
*/
@@ -309,6 +293,28 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
return 1;
}
+static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ if (!arch_is_coherent())
+ dma_cache_maint(cpu_addr, size, dir);
+
+ return virt_to_dma(dev, cpu_addr);
+}
+static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ if (!arch_is_coherent())
+ dma_cache_maint_page(page, offset, size, dir);
+
+ return page_to_dma(dev, page) + offset;
+}
+static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ /* nothing to do */
+}
+#endif /* CONFIG_DMABOUNCE */
/**
* dma_map_single - map a single buffer for streaming DMA
@@ -328,11 +334,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
size_t size, enum dma_data_direction dir)
{
BUG_ON(!valid_dma_direction(dir));
-
- if (!arch_is_coherent())
- dma_cache_maint(cpu_addr, size, dir);
-
- return virt_to_dma(dev, cpu_addr);
+ return __dma_map_single(dev, cpu_addr, size, dir);
}
/**
@@ -353,11 +355,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
BUG_ON(!valid_dma_direction(dir));
-
- if (!arch_is_coherent())
- dma_cache_maint_page(page, offset, size, dir);
-
- return page_to_dma(dev, page) + offset;
+ return __dma_map_page(dev, page, offset, size, dir);
}
/**
@@ -377,9 +375,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
- /* nothing to do */
+ __dma_unmap_single(dev, handle, size, dir);
}
-#endif /* CONFIG_DMABOUNCE */
/**
* dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
--
1.6.0.GIT
From: Ming Lei <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/dma-mapping.h | 38 ++++++++++++++++++++++++++++++-----
arch/arm/mm/dma-mapping.c | 11 ++++++++++
3 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91da50..867e7c1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -18,6 +18,7 @@ config ARM
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_DMA_API_DEBUG
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 86f2964..a288bab 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,7 +5,7 @@
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
-
+#include <linux/dma-debug.h>
#include <asm-generic/dma-coherent.h>
#include <asm/memory.h>
@@ -146,7 +146,11 @@ extern void __dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t gfp)
{
- return __dma_alloc_coherent(dev, size, handle, gfp);
+ void *mem;
+
+ mem = __dma_alloc_coherent(dev, size, handle, gfp);
+ debug_dma_alloc_coherent(dev, size, *handle, mem);
+ return mem;
}
/**
@@ -165,6 +169,7 @@ static inline void *dma_alloc_coherent(struct device *dev, size_t size,
static inline void dma_free_coherent(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t handle)
{
+ debug_dma_free_coherent(dev, size, cpu_addr, handle);
__dma_free_coherent(dev, size, cpu_addr, handle);
}
@@ -333,8 +338,14 @@ static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
size_t size, enum dma_data_direction dir)
{
+ dma_addr_t addr;
BUG_ON(!valid_dma_direction(dir));
- return __dma_map_single(dev, cpu_addr, size, dir);
+
+ addr = __dma_map_single(dev, cpu_addr, size, dir);
+ debug_dma_map_page(dev, virt_to_page(cpu_addr),
+ (unsigned long)cpu_addr & ~PAGE_MASK, size,
+ dir, addr, true);
+ return addr;
}
/**
@@ -354,8 +365,12 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
+ dma_addr_t addr;
BUG_ON(!valid_dma_direction(dir));
- return __dma_map_page(dev, page, offset, size, dir);
+
+ addr = __dma_map_page(dev, page, offset, size, dir);
+ debug_dma_map_page(dev, page, offset, size, dir, addr, false);
+ return addr;
}
/**
@@ -376,6 +391,7 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
__dma_unmap_single(dev, handle, size, dir);
+ debug_dma_unmap_page(dev, handle, size, dir, true);
}
/**
@@ -395,7 +411,8 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
- dma_unmap_single(dev, handle, size, dir);
+ __dma_unmap_single(dev, handle, size, dir);
+ debug_dma_unmap_page(dev, handle, size, dir, false);
}
/**
@@ -422,6 +439,7 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
{
BUG_ON(!valid_dma_direction(dir));
+ debug_dma_sync_single_range_for_cpu(dev, handle, offset, size, dir);
dmabounce_sync_for_cpu(dev, handle, offset, size, dir);
}
@@ -431,6 +449,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
{
BUG_ON(!valid_dma_direction(dir));
+ debug_dma_sync_single_range_for_device(dev, handle, offset, size, dir);
+
if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
return;
@@ -465,11 +485,15 @@ extern void __dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
- return __dma_map_sg(dev, sg, nents, dir);
+ int ents;
+ ents = __dma_map_sg(dev, sg, nents, dir);
+ debug_dma_map_sg(dev, sg, nents, ents, dir);
+ return ents;
}
static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
+ debug_dma_unmap_sg(dev, sg, nents, dir);
__dma_unmap_sg(dev, sg, nents, dir);
}
static inline void dma_sync_sg_for_cpu(struct device *dev,
@@ -477,12 +501,14 @@ static inline void dma_sync_sg_for_cpu(struct device *dev,
enum dma_data_direction dir)
{
__dma_sync_sg_for_cpu(dev, sg, nents, dir);
+ debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
}
static inline void dma_sync_sg_for_device(struct device *dev,
struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
__dma_sync_sg_for_device(dev, sg, nents, dir);
+ debug_dma_sync_sg_for_device(dev, sg, nents, dir);
}
#endif /* __KERNEL__ */
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 654cd82..64e5d82 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/dma-debug.h>
#include <linux/dma-mapping.h>
#include <asm/memory.h>
@@ -688,3 +689,13 @@ void __dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
}
}
EXPORT_SYMBOL(__dma_sync_sg_for_device);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES 8192
+
+static int __init dma_debug_init_arm(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ return 0;
+}
+fs_initcall(dma_debug_init_arm);
+
--
1.6.0.GIT
2009/7/12 <[email protected]>:
> Hi,
> This patch set introduces dma-api debugging facility on ARM, and is
> against -rc2-next tree.
>
Hi, Russell and All,
Care to give any suggestions or objections on the patches?
thanks.
--
Lei Ming
On Fri, Jul 17, 2009 at 08:02:08AM +0800, Ming Lei wrote:
> 2009/7/12 <[email protected]>:
> > Hi,
> > This patch set introduces dma-api debugging facility on ARM, and is
> > against -rc2-next tree.
> >
>
> Hi, Russell and All,
>
> Care to give any suggestions or objections on the patches?
I don't think it's suitable, because our implementation calls back into
the DMA API for dma_map_sg() - this means that the debugging code will
end up seeing each scatterlist entry twice. I'm not sure what effect
that will have, but it's probably not good.
On Fri, 17 Jul 2009 09:11:49 +0100
Russell King - ARM Linux <[email protected]> wrote:
> I don't think it's suitable, because our implementation calls back
> into the DMA API for dma_map_sg() - this means that the debugging
> code will end up seeing each scatterlist entry twice. I'm not sure
> what effect that will have, but it's probably not good.
Thank you for the review, and does the patch fix the problem?
If yes, I'll sumbmit the v2 version if necessary or you can use it directly.
>From cd2ef8fc869a2e3442fc37d695ca95d286ac6a4d Mon Sep 17 00:00:00 2001
From: Ming Lei <[email protected]>
Date: Fri, 17 Jul 2009 22:54:01 +0800
Subject: [PATCH 4/4] ARM:dma-mapping:fix dma_map_sg and dma_unmap_sg
This patch removes unnecessary calling of debug_dma_map_page
and debug_dma_unmap_page in dma_map_sg and dma_unmap_sg.
Signed-off-by: Ming Lei <[email protected]>
---
arch/arm/mm/dma-mapping.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 64e5d82..584018c 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -610,7 +610,7 @@ int __dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
int i, j;
for_each_sg(sg, s, nents, i) {
- s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+ s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
s->length, dir);
if (dma_mapping_error(dev, s->dma_address))
goto bad_mapping;
@@ -619,7 +619,7 @@ int __dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
bad_mapping:
for_each_sg(sg, s, i, j)
- dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ __dma_unmap_single(dev, sg_dma_address(s), sg_dma_len(s), dir);
return 0;
}
EXPORT_SYMBOL(__dma_map_sg);
@@ -641,7 +641,7 @@ void __dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
int i;
for_each_sg(sg, s, nents, i)
- dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ __dma_unmap_single(dev, sg_dma_address(s), sg_dma_len(s), dir);
}
EXPORT_SYMBOL(__dma_unmap_sg);
--
1.6.0.GIT
--
Lei Ming