Re: [PATCH 0/10] DMA-API debugging facility
From: David Woodhouse <dwmw2@infradead.org>
Date: 2009-02-05 22:44:30
Also in:
lkml
Subsystem:
linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Linus Torvalds
On Fri, 2008-11-21 at 18:27 +0100, Joerg Roedel wrote:
On Fri, Nov 21, 2008 at 05:24:29PM +0000, David Woodhouse wrote:quoted
On Fri, 2008-11-21 at 18:20 +0100, Joerg Roedel wrote:quoted
Ok, I will move the generic bits to lib/ and include/linux and let architectures decide if they want to use it.Once you've done that, I'll try to hook it up on PowerPC to make sure it works there.Ok, cool. Thanks
This builds; I haven't actually tried booting it yet. Will do that in the morning. I'm not so fond of the way each architecture gets to define PREALLOC_DMA_DEBUG_ENTRIES for itself... and also call dma_debug_init(), for that matter. Couldn't we do that in lib/dma-debug.c directly? Signed-off-by: David Woodhouse <redacted>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 74cc312..11db356 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig@@ -124,6 +124,7 @@ config PPC select USE_GENERIC_SMP_HELPERS if SMP select HAVE_OPROFILE select HAVE_SYSCALL_WRAPPERS if PPC64 + select HAVE_DMA_API_DEBUG config EARLY_PRINTK bool
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 86cef7d..b49107a 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h@@ -13,6 +13,7 @@ /* need struct page definitions */ #include <linux/mm.h> #include <linux/scatterlist.h> +#include <linux/dma-debug.h> #include <linux/dma-attrs.h> #include <asm/io.h>
@@ -170,12 +171,17 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, struct dma_attrs *attrs) { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + dma_addr_t addr; BUG_ON(!dma_ops); - return dma_ops->map_page(dev, virt_to_page(cpu_addr), + addr = dma_ops->map_page(dev, virt_to_page(cpu_addr), (unsigned long)cpu_addr % PAGE_SIZE, size, direction, attrs); + debug_dma_map_page(dev, virt_to_page(cpu_addr), + (unsigned long)cpu_addr & PAGE_SIZE, size, + direction, addr, true); + return addr; } static inline void dma_unmap_single_attrs(struct device *dev,
@@ -189,6 +195,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, BUG_ON(!dma_ops); dma_ops->unmap_page(dev, dma_addr, size, direction, attrs); + debug_dma_unmap_page(dev, dma_addr, size, direction, true); } static inline dma_addr_t dma_map_page_attrs(struct device *dev,
@@ -198,10 +205,13 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev, struct dma_attrs *attrs) { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + dma_addr_t addr; BUG_ON(!dma_ops); - return dma_ops->map_page(dev, page, offset, size, direction, attrs); + addr = dma_ops->map_page(dev, page, offset, size, direction, attrs); + debug_dma_map_page(dev, page, offset, size, direction, addr, false); + return addr; } static inline void dma_unmap_page_attrs(struct device *dev,
@@ -215,6 +225,7 @@ static inline void dma_unmap_page_attrs(struct device *dev, BUG_ON(!dma_ops); dma_ops->unmap_page(dev, dma_address, size, direction, attrs); + debug_dma_unmap_page(dev, dma_address, size, direction, false); } static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
@@ -222,9 +233,12 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, struct dma_attrs *attrs) { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + int ents; BUG_ON(!dma_ops); - return dma_ops->map_sg(dev, sg, nents, direction, attrs); + ents = dma_ops->map_sg(dev, sg, nents, direction, attrs); + debug_dma_map_sg(dev, sg, ents, direction); + return ents; } static inline void dma_unmap_sg_attrs(struct device *dev,
@@ -237,15 +251,19 @@ static inline void dma_unmap_sg_attrs(struct device *dev, BUG_ON(!dma_ops); dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs); + debug_dma_unmap_sg(dev, sg, nhwentries, direction); } static inline void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + void *mem; BUG_ON(!dma_ops); - return dma_ops->alloc_coherent(dev, size, dma_handle, flag); + mem = dma_ops->alloc_coherent(dev, size, dma_handle, flag); + debug_dma_alloc_coherent(dev, size, *dma_handle, mem); + return mem; } static inline void dma_free_coherent(struct device *dev, size_t size,
@@ -254,6 +272,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); }
@@ -306,6 +325,8 @@ static inline void dma_sync_single_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_sync_single_range_for_cpu(dev, dma_handle, 0, + size, direction); dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, size, direction); }
@@ -317,6 +338,8 @@ static inline void dma_sync_single_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_sync_single_range_for_device(dev, dma_handle, + 0, size, direction); dma_ops->sync_single_range_for_device(dev, dma_handle, 0, size, direction); }
@@ -328,6 +351,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_sync_sg_for_cpu(dev, sgl, nents, direction); dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); }
@@ -338,6 +362,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_sync_sg_for_device(dev, sgl, nents, direction); dma_ops->sync_sg_for_device(dev, sgl, nents, direction); }
@@ -348,6 +373,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_sync_single_range_for_cpu(dev, dma_handle, + offset, size, direction); dma_ops->sync_single_range_for_cpu(dev, dma_handle, offset, size, direction); }
@@ -359,6 +386,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); + debug_dma_sync_single_range_for_device(dev, dma_handle, offset, + size, direction); dma_ops->sync_single_range_for_device(dev, dma_handle, offset, size, direction); }
@@ -367,36 +396,46 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + debug_dma_sync_single_range_for_cpu(dev, dma_handle, 0, + size, direction); } static inline void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + debug_dma_sync_single_range_for_device(dev, dma_handle, + 0, size, direction); } static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { + debug_dma_sync_sg_for_cpu(dev, sgl, nents, direction); } static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { + debug_dma_sync_sg_for_device(dev, sgl, nents, direction); } static inline void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { + debug_dma_sync_single_range_for_cpu(dev, dma_handle, + offset, size, direction); } static inline void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) { + debug_dma_sync_single_range_for_device(dev, dma_handle, offset, + size, direction); } #endif
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 1c5c8a6..90bb016 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c@@ -6,7 +6,9 @@ */ #include <linux/device.h> +#include <linux/dma-debug.h> #include <linux/dma-mapping.h> +#include <linux/init.h> #include <asm/bug.h> #include <asm/abs_addr.h>
@@ -156,3 +158,12 @@ struct dma_mapping_ops dma_direct_ops = { #endif }; EXPORT_SYMBOL(dma_direct_ops); + +#define PREALLOC_DMA_DEBUG_ENTRIES 8192 + +static int __init dma_debug_init_ppc(void) +{ + dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); + return 0; +} +fs_initcall(dma_debug_init_ppc);
--
David Woodhouse Open Source Technology Centre
David.Woodhouse@intel.com Intel Corporation