From: "Roedel, Joerg" <Joerg.Roedel@amd.com>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
David Woodhouse <dwmw2@infradead.org>
Subject: Re: [PATCH v3] dma-debug: print some unfreed allocations
Date: Mon, 23 May 2011 14:35:08 +0200 [thread overview]
Message-ID: <20110523123508.GC27867@amd.com> (raw)
In-Reply-To: <1305909418.4640.13.camel@jlt3.sipsolutions.net>
On Fri, May 20, 2011 at 12:36:58PM -0400, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> #define NAME_MAX_LEN 64
> @@ -641,6 +647,14 @@ static int dma_debug_fs_init(void)
> if (!filter_dent)
> goto out_err;
>
> +#ifdef CONFIG_STACKTRACE
> + num_show_pending_dent = debugfs_create_u32("num_show_pending", 0644,
> + dma_debug_dent,
> + &num_show_pending);
> + if (!num_show_pending_dent)
> + goto out_err;
> +#endif
Hmm, thinking more about this, do we need to introduce a new variable at
all? It should fit well into the dma-api/all_errors and
dma-api/num_errors configurables.
> +#ifdef CONFIG_STACKTRACE
> + if (count > 1 && num_show_pending > 0) {
> + count = 0;
> + /*
> + * If we have, print out some stack traces for the allocations.
> + * In case of module unload, the stack traces will be useless,
> + * but instead of unloading the module you can manually unbind
> + * the driver instead and get useful traces.
> + */
> + printk(KERN_WARNING "Showing traces for %d allocations:\n",
> + num_show_pending);
> +
> + for (i = 0; i < HASH_SIZE; ++i) {
> + spin_lock(&dma_entry_hash[i].lock);
> + list_for_each_entry(entry, &dma_entry_hash[i].list,
> + list) {
> + if (entry->dev != dev)
> + continue;
> + count += 1;
> + if (count > num_show_pending)
> + break;
> + dump_entry_trace(entry);
> + }
> + spin_unlock(&dma_entry_hash[i].lock);
> +
> + if (count > num_show_pending)
> + break;
> + }
> + }
> +#endif
This duplicates the loop above. The prints can be folded into one loop.
How about doing it this way (patch is only compile-tested):
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index db07bfd..ee21ef0 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -187,11 +187,14 @@ static bool driver_filter(struct device *dev)
return ret;
}
-#define err_printk(dev, entry, format, arg...) do { \
+#define err_warn(format, arg...) WARN(1, format, ## arg)
+#define err_no_warn(format, arg...) pr_err(format, ## arg)
+
+#define __err_printk(func, dev, entry, format, arg...) do { \
error_count += 1; \
if (driver_filter(dev) && \
(show_all_errors || show_num_errors > 0)) { \
- WARN(1, "%s %s: " format, \
+ func("%s %s: " format, \
dev ? dev_driver_string(dev) : "NULL", \
dev ? dev_name(dev) : "NULL", ## arg); \
dump_entry_trace(entry); \
@@ -200,6 +203,12 @@ static bool driver_filter(struct device *dev)
show_num_errors -= 1; \
} while (0);
+#define err_printk(dev, entry, format, arg...) \
+ __err_printk(err_warn, dev, entry, format, ## arg)
+
+#define err_printk_no_warn(dev, entry, format, arg...) \
+ __err_printk(err_no_warn, dev, entry, format, ## arg)
+
/*
* Hash related functions
*
@@ -649,52 +658,38 @@ out_err:
return -ENOMEM;
}
-static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry)
+static void check_device_dma_allocations(struct device *dev)
{
struct dma_debug_entry *entry;
unsigned long flags;
- int count = 0, i;
+ int i;
local_irq_save(flags);
for (i = 0; i < HASH_SIZE; ++i) {
spin_lock(&dma_entry_hash[i].lock);
list_for_each_entry(entry, &dma_entry_hash[i].list, list) {
- if (entry->dev == dev) {
- count += 1;
- *out_entry = entry;
- }
+ if (entry->dev != dev)
+ continue;
+ err_printk_no_warn(dev, entry,
+ "DMA-API: device driver has pending DMA allocation\n");
}
spin_unlock(&dma_entry_hash[i].lock);
}
local_irq_restore(flags);
-
- return count;
}
static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data)
{
struct device *dev = data;
- struct dma_debug_entry *uninitialized_var(entry);
- int count;
if (global_disable)
return 0;
switch (action) {
case BUS_NOTIFY_UNBOUND_DRIVER:
- count = device_dma_allocations(dev, &entry);
- if (count == 0)
- break;
- err_printk(dev, entry, "DMA-API: device driver has pending "
- "DMA allocations while released from device "
- "[count=%d]\n"
- "One of leaked entries details: "
- "[device address=0x%016llx] [size=%llu bytes] "
- "[mapped with %s] [mapped as %s]\n",
- count, entry->dev_addr, entry->size,
- dir2name[entry->direction], type2name[entry->type]);
+ check_device_dma_allocations(dev);
break;
default:
break;
next prev parent reply other threads:[~2011-05-23 12:35 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-10 18:42 [PATCH] dma-debug: print some unfreed allocations Johannes Berg
2011-05-11 12:47 ` [PATCH v2] " Johannes Berg
2011-05-16 11:00 ` Roedel, Joerg
2011-05-18 22:48 ` Johannes Berg
2011-05-19 8:19 ` Roedel, Joerg
2011-05-20 16:36 ` [PATCH v3] " Johannes Berg
2011-05-23 12:35 ` Roedel, Joerg [this message]
2011-06-08 11:03 ` Johannes Berg
2011-06-08 12:16 ` Roedel, Joerg
2011-06-08 12:26 ` Johannes Berg
2011-06-08 12:37 ` Roedel, Joerg
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=20110523123508.GC27867@amd.com \
--to=joerg.roedel@amd.com \
--cc=dwmw2@infradead.org \
--cc=johannes@sipsolutions.net \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox