All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Woodhouse <dwmw2@infradead.org>
To: Joerg Roedel <joerg.roedel@amd.com>
Cc: mingo@redhat.com, linux-kernel@vger.kernel.org,
	fujita.tomonori@lab.ntt.co.jp, iommu@lists.linux-foundation.org,
	johannes@sipsolutions.net
Subject: Re: [PATCH 0/16] DMA-API debugging facility v3
Date: Wed, 25 Feb 2009 16:33:19 +0900	[thread overview]
Message-ID: <1235547199.519.36.camel@macbook.infradead.org> (raw)
In-Reply-To: <1232376423-11067-1-git-send-email-joerg.roedel@amd.com>

Where we complain about a discrepancy between unmap/sync and the
original mapping, it can sometimes be useful to see the backtrace of the
code which _mapped_ the region originally.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
Untested. Builds though. Thanks Johannes for pointing me at an example.

diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 9c1a498..79542db 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/list.h>
+#include <linux/stacktrace.h>
 #include <linux/slab.h>
 
 #define HASH_SIZE       256
@@ -39,6 +40,8 @@ enum {
 	dma_debug_coherent,
 };
 
+#define DMA_DEBUG_STACKTRACE_ENTRIES 5
+
 struct dma_debug_entry {
 	struct list_head list;
 	struct device    *dev;
@@ -47,6 +50,10 @@ struct dma_debug_entry {
 	u64              dev_addr;
 	u64              size;
 	int              direction;
+#ifdef CONFIG_STACKTRACE
+	struct stack_trace stacktrace;
+	unsigned long	 st_entries[DMA_DEBUG_STACKTRACE_ENTRIES];
+#endif
 };
 
 struct hash_bucket {
@@ -106,13 +113,24 @@ static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
  *                    system log than the user configured. This variable is
  *                    writeable via debugfs.
  */
-#define err_printk(dev, format, arg...) do {			\
+static inline void dump_entry_trace(struct dma_debug_entry *entry)
+{
+#ifdef CONFIG_STACKTRACE 
+	if (entry) {
+		printk(KERN_WARNING "Mapped at:\n");
+		print_stack_trace(&entry->stacktrace, 0);
+	}
+#endif
+}
+
+#define err_printk(dev, entry, format, arg...) do {		\
 		error_count += 1;				\
 		if (show_all_errors || show_num_errors > 0) {	\
 			WARN(1, "%s %s: " format,		\
 			     dev_driver_string(dev),		\
 			     dev_name(dev) , ## arg);		\
 		}						\
+		dump_entry_trace(entry);			\
 		if (!show_all_errors && show_num_errors > 0)	\
 			show_num_errors -= 1;			\
 	} while (0);
@@ -258,6 +276,12 @@ static struct dma_debug_entry *dma_entry_alloc(void)
 	list_del(&entry->list);
 	memset(entry, 0, sizeof(*entry));
 
+#ifdef CONFIG_STACKTRACE
+	entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES;
+	entry->stacktrace.entries = entry->st_entries;
+	entry->stacktrace.skip = 1;
+	save_stack_trace(&entry->stacktrace);
+#endif
 	num_free_entries -= 1;
 	if (num_free_entries < min_free_entries)
 		min_free_entries = num_free_entries;
@@ -455,7 +479,7 @@ static void check_unmap(struct dma_debug_entry *ref)
 	entry = hash_bucket_find(bucket, ref);
 
 	if (!entry) {
-		err_printk(ref->dev, "DMA-API: device driver tries "
+		err_printk(ref->dev, NULL, "DMA-API: device driver tries "
 			   "to free DMA memory it has not allocated "
 			   "[device address=0x%016llx] [size=%llu bytes]\n",
 			   ref->dev_addr, ref->size);
@@ -463,7 +487,7 @@ static void check_unmap(struct dma_debug_entry *ref)
 	}
 
 	if (ref->size != entry->size) {
-		err_printk(ref->dev, "DMA-API: device driver frees "
+		err_printk(ref->dev, entry, "DMA-API: device driver frees "
 			   "DMA memory with different size "
 			   "[device address=0x%016llx] [map size=%llu bytes] "
 			   "[unmap size=%llu bytes]\n",
@@ -471,7 +495,7 @@ static void check_unmap(struct dma_debug_entry *ref)
 	}
 
 	if (ref->type != entry->type) {
-		err_printk(ref->dev, "DMA-API: device driver frees "
+		err_printk(ref->dev, entry, "DMA-API: device driver frees "
 			   "DMA memory with wrong function "
 			   "[device address=0x%016llx] [size=%llu bytes] "
 			   "[mapped as %s] [unmapped as %s]\n",
@@ -479,7 +503,7 @@ static void check_unmap(struct dma_debug_entry *ref)
 			   type2name[entry->type], type2name[ref->type]);
 	} else if ((entry->type == dma_debug_coherent) &&
 		   (ref->paddr != entry->paddr)) {
-		err_printk(ref->dev, "DMA-API: device driver frees "
+		err_printk(ref->dev, entry, "DMA-API: device driver frees "
 			   "DMA memory with different CPU address "
 			   "[device address=0x%016llx] [size=%llu bytes] "
 			   "[cpu alloc address=%p] [cpu free address=%p]",
@@ -492,7 +516,7 @@ static void check_unmap(struct dma_debug_entry *ref)
 	 * DMA API don't handle this properly, so check for it here
 	 */
 	if (ref->direction != entry->direction) {
-		err_printk(ref->dev, "DMA-API: device driver frees "
+		err_printk(ref->dev, entry, "DMA-API: device driver frees "
 			   "DMA memory with different direction "
 			   "[device address=0x%016llx] [size=%llu bytes] "
 			   "[mapped with %s] [unmapped with %s]\n",
@@ -511,8 +535,8 @@ out:
 static void check_for_stack(struct device *dev, void *addr)
 {
 	if (object_is_on_stack(addr))
-		err_printk(dev, "DMA-API: device driver maps memory from stack"
-				" [addr=%p]\n", addr);
+		err_printk(dev, NULL, "DMA-API: device driver maps memory from"
+				"stack [addr=%p]\n", addr);
 }
 
 static void check_sync(struct device *dev, dma_addr_t addr,
@@ -533,7 +557,7 @@ static void check_sync(struct device *dev, dma_addr_t addr,
 	entry = hash_bucket_find(bucket, &ref);
 
 	if (!entry) {
-		err_printk(dev, "DMA-API: device driver tries "
+		err_printk(dev, NULL, "DMA-API: device driver tries "
 				"to sync DMA memory it has not allocated "
 				"[device address=0x%016llx] [size=%llu bytes]\n",
 				addr, size);
@@ -541,7 +565,7 @@ static void check_sync(struct device *dev, dma_addr_t addr,
 	}
 
 	if ((offset + size) > entry->size) {
-		err_printk(dev, "DMA-API: device driver syncs"
+		err_printk(dev, entry, "DMA-API: device driver syncs"
 				" DMA memory outside allocated range "
 				"[device address=0x%016llx] "
 				"[allocation size=%llu bytes] [sync offset=%llu] "
@@ -550,7 +574,7 @@ static void check_sync(struct device *dev, dma_addr_t addr,
 	}
 
 	if (direction != entry->direction) {
-		err_printk(dev, "DMA-API: device driver syncs "
+		err_printk(dev, entry, "DMA-API: device driver syncs "
 				"DMA memory with different direction "
 				"[device address=0x%016llx] [size=%llu bytes] "
 				"[mapped with %s] [synced with %s]\n",
@@ -564,7 +588,7 @@ static void check_sync(struct device *dev, dma_addr_t addr,
 
 	if (to_cpu && !(entry->direction == DMA_FROM_DEVICE) &&
 		      !(direction == DMA_TO_DEVICE))
-		err_printk(dev, "DMA-API: device driver syncs "
+		err_printk(dev, entry, "DMA-API: device driver syncs "
 				"device read-only DMA memory for cpu "
 				"[device address=0x%016llx] [size=%llu bytes] "
 				"[mapped with %s] [synced with %s]\n",
@@ -574,7 +598,7 @@ static void check_sync(struct device *dev, dma_addr_t addr,
 
 	if (!to_cpu && !(entry->direction == DMA_TO_DEVICE) &&
 		       !(direction == DMA_FROM_DEVICE))
-		err_printk(dev, "DMA-API: device driver syncs "
+		err_printk(dev, entry, "DMA-API: device driver syncs "
 				"device write-only DMA memory to device "
 				"[device address=0x%016llx] [size=%llu bytes] "
 				"[mapped with %s] [synced with %s]\n",

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation


  parent reply	other threads:[~2009-02-25  7:33 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-19 14:46 [PATCH 0/16] DMA-API debugging facility v3 Joerg Roedel
2009-01-19 14:46 ` [PATCH 01/16] dma-debug: add Kconfig entry Joerg Roedel
2009-01-19 14:46 ` [PATCH 02/16] dma-debug: add header file and core data structures Joerg Roedel
2009-01-19 14:46 ` [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Joerg Roedel
2009-01-19 14:46 ` [PATCH 04/16] dma-debug: add allocator code Joerg Roedel
2009-01-19 14:46 ` [PATCH 05/16] dma-debug: add initialization code Joerg Roedel
2009-01-19 14:46 ` [PATCH 06/16] dma-debug: add kernel command line parameters Joerg Roedel
2009-01-19 14:46 ` [PATCH 07/16] dma-debug: add debugfs interface Joerg Roedel
2009-01-19 14:46 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
2009-02-05 21:07   ` David Woodhouse
2009-02-12 14:49     ` Joerg Roedel
2009-02-13 19:48       ` Jesse Brandeburg
2009-01-19 14:46 ` [PATCH 09/16] dma-debug: add checking for map/unmap_page/single Joerg Roedel
2009-01-21  0:17   ` Arnd Bergmann
2009-01-23 10:28     ` Joerg Roedel
2009-01-25 13:17       ` FUJITA Tomonori
2009-01-25 13:51         ` Joerg Roedel
2009-02-05 21:06   ` David Woodhouse
2009-02-12 14:52     ` Joerg Roedel
2009-01-19 14:46 ` [PATCH 10/16] dma-debug: add add checking for map/unmap_sg Joerg Roedel
2009-02-05 22:30   ` David Woodhouse
2009-02-12 14:54     ` Joerg Roedel
2009-01-19 14:46 ` [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent Joerg Roedel
2009-01-19 14:46 ` [PATCH 12/16] dma-debug: add checks for sync_single_* Joerg Roedel
2009-01-19 14:47 ` [PATCH 13/16] dma-debug: add checks for sync_single_range_* Joerg Roedel
2009-01-19 14:47 ` [PATCH 14/16] dma-debug: add checks for sync_single_sg_* Joerg Roedel
2009-01-19 14:47 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
2009-02-22  6:50   ` FUJITA Tomonori
2009-02-25 11:14     ` Joerg Roedel
2009-01-19 14:47 ` [PATCH 16/16] dma-debug: Documentation update Joerg Roedel
2009-02-25  7:33 ` David Woodhouse [this message]
2009-02-25 10:57   ` [PATCH 0/16] DMA-API debugging facility v3 Joerg Roedel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1235547199.519.36.camel@macbook.infradead.org \
    --to=dwmw2@infradead.org \
    --cc=fujita.tomonori@lab.ntt.co.jp \
    --cc=iommu@lists.linux-foundation.org \
    --cc=joerg.roedel@amd.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.