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 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.