linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/16] DMA-API debugging facility v2
@ 2009-01-09 16:19 Joerg Roedel
  2009-01-09 16:19 ` [PATCH 01/16] dma-debug: add Kconfig entry Joerg Roedel
                   ` (18 more replies)
  0 siblings, 19 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu

Hi,

this is version 2 of the patchset which introduces code to debug drivers
usage of the DMA-API. Many thanks to all the reviewers and the useful
comments on the fist version of this patchset. Tests with hardware
IOMMUs have shown several bugs in drivers regarding the usage of that
API.  Problems were found especially in network card drivers.

These bugs often don't show up or have any negative impact if there is
no hardware IOMMU in use in the system. But with an hardware IOMMU these
bugs turn the hardware unusable or, in the worst case, cause data
corruption on devices which are managed by other (good) drivers.

With the code these patches introduce driver developers can find several
bugs of misusing the DMA-API in their drivers. But be aware, it can not
find all possible bugs. If it finds a problem it prints out messages
like

------------[ cut here ]------------
WARNING: at /data2/repos/linux.trees.git/lib/dma-debug.c:231 check_unmap+0xab/0x3d9()
Hardware name: Toonie
bnx2 0000:01:00.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x00000000011]
Modules linked in:
Pid: 0, comm: swapper Not tainted 2.6.28 #174
Call Trace:
 <IRQ>  [<ffffffff8105af3a>] warn_slowpath+0xd3/0xf2
 [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
 [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
 [<ffffffff812efd16>] ? usb_hcd_link_urb_to_ep+0x94/0xa0
 [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
 [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
 [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
 [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
 [<ffffffff814b25a5>] ? _spin_lock_irqsave+0x69/0x75
 [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
 [<ffffffff811e2ff2>] check_unmap+0xab/0x3d9
 [<ffffffff8107c9ed>] ? trace_hardirqs_on_caller+0x108/0x14a
 [<ffffffff8107ca3c>] ? trace_hardirqs_on+0xd/0xf
 [<ffffffff811e3433>] debug_unmap_single+0x3e/0x40
 [<ffffffff8128d2d8>] dma_unmap_single+0x3d/0x60
 [<ffffffff8128d335>] pci_unmap_page+0x1c/0x1e
 [<ffffffff81290759>] bnx2_poll_work+0x626/0x8cb
 [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
 [<ffffffff81070100>] ? run_posix_cpu_timers+0x49c/0x603
 [<ffffffff81070000>] ? run_posix_cpu_timers+0x39c/0x603
 [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
 [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
 [<ffffffff81292804>] bnx2_poll_msix+0x33/0x81
 [<ffffffff813b6478>] net_rx_action+0x8a/0x139
 [<ffffffff8105ff39>] __do_softirq+0x8b/0x147
 [<ffffffff8102933c>] call_softirq+0x1c/0x34
 [<ffffffff8102a611>] do_softirq+0x39/0x90
 [<ffffffff8105fde8>] irq_exit+0x4e/0x98
 [<ffffffff8102a5c2>] do_IRQ+0x11f/0x135
 [<ffffffff81028b93>] ret_from_intr+0x0/0xf
 <EOI> <4>---[ end trace 4339d58302097423 ]---

This way driver developers get an idea where the problem is in their
code.

I hope I addressed most of the review comments and objections from the
first version. Please give this version also a good review and send me
your comments.

Thanks,

Joerg


Changes from v1 -> v2:

- moved code to lib/ and include/linux to make it usable for all
  architectures
- more fine grained hash locking (locking is now per hash bucket, no
  global lock anymore)
- dma_debug_entries are preallocated
- per default the code will only print one warning and is silent then
- added a debugfs interface to see some statistics and to enable more
  verbose error reporting in the kernel log
- added command line parameter to disable debugging code
- allocation errors are now handled correctly
- added documentation about this facility for driver developers

diffstat:

 Documentation/DMA-API.txt           |  117 ++++++
 Documentation/kernel-parameters.txt |   10 +
 arch/Kconfig                        |    2 +
 arch/x86/Kconfig                    |    1 +
 arch/x86/include/asm/dma-mapping.h  |   30 ++-
 arch/x86/kernel/pci-dma.c           |    5 +
 include/linux/dma-debug.h           |  154 ++++++++
 lib/Kconfig.debug                   |   11 +
 lib/Makefile                        |    2 +
 lib/dma-debug.c                     |  726 +++++++++++++++++++++++++++++++++++
 10 files changed, 1054 insertions(+), 4 deletions(-)




^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 01/16] dma-debug: add Kconfig entry
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 20:12   ` Randy Dunlap
  2009-01-09 16:19 ` [PATCH 02/16] dma-debug: add header file and core data structures Joerg Roedel
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add a Kconfig entry for DMA-API debugging

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/Kconfig      |    2 ++
 lib/Kconfig.debug |   11 +++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 2e13aa2..068554c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -103,3 +103,5 @@ config HAVE_CLK
 	  The <linux/clk.h> calls support software clock gating and
 	  thus are a key power management tool on many systems.
 
+config HAVE_DMA_API_DEBUG
+	bool
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2e75478..cba5778 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -899,6 +899,17 @@ config DYNAMIC_PRINTK_DEBUG
 	  debugging for all modules. This mode can be turned off via the above
 	  disable command.
 
+config DMA_API_DEBUG
+	bool "Enable debugging of DMA-API usage"
+	depends on HAVE_DMA_API_DEBUG
+	help
+	  Enable this option to debug the use of the DMA API by device drivers.
+	  With this option you will be able to detect common bugs in device
+	  drivers like double-freeing of DMA mappings or freeing mappings that
+	  were never allocated.
+	  This option causes a performance degredation.  Use only if you want
+	  to debug device drivers. If unsure, say N.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 02/16] dma-debug: add header file and core data structures
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
  2009-01-09 16:19 ` [PATCH 01/16] dma-debug: add Kconfig entry Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-11  6:25   ` FUJITA Tomonori
  2009-01-09 16:19 ` [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Joerg Roedel
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add groundwork for DMA-API debugging

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   25 +++++++++++++++++++++++++
 lib/Makefile              |    2 ++
 lib/dma-debug.c           |   39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/dma-debug.h
 create mode 100644 lib/dma-debug.c

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
new file mode 100644
index 0000000..ce4ace7
--- /dev/null
+++ b/include/linux/dma-debug.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Author: Joerg Roedel <joerg.roedel@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef __DMA_DEBUG_H
+#define __DMA_DEBUG_H
+
+struct device;
+
+#endif /* __DMA_DEBUG_H */
diff --git a/lib/Makefile b/lib/Makefile
index 32b0e64..50b48cf 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -84,6 +84,8 @@ obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
 
 obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
 
+obj-$(CONFIG_DMA_API_DEBUG) += dma-debug.o
+
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
new file mode 100644
index 0000000..d04f8b6
--- /dev/null
+++ b/lib/dma-debug.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Author: Joerg Roedel <joerg.roedel@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/dma-debug.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+enum {
+	dma_debug_single,
+	dma_debug_sg,
+	dma_debug_coherent,
+};
+
+struct dma_debug_entry {
+	struct list_head list;
+	struct device    *dev;
+	int              type;
+	void             *cpu_addr;
+	u64              dev_addr;
+	u64              size;
+	int              direction;
+};
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
  2009-01-09 16:19 ` [PATCH 01/16] dma-debug: add Kconfig entry Joerg Roedel
  2009-01-09 16:19 ` [PATCH 02/16] dma-debug: add header file and core data structures Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 17:55   ` Evgeniy Polyakov
  2009-01-13  8:51   ` Andrew Morton
  2009-01-09 16:19 ` [PATCH 04/16] dma-debug: add allocator code Joerg Roedel
                   ` (15 subsequent siblings)
  18 siblings, 2 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: implement necessary functions for the core hash

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 lib/dma-debug.c |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index d04f8b6..74a0f36 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -18,9 +18,14 @@
  */
 
 #include <linux/dma-debug.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/list.h>
 
+#define HASH_SIZE       256
+#define HASH_FN_SHIFT   20
+#define HASH_FN_MASK    0xffULL
+
 enum {
 	dma_debug_single,
 	dma_debug_sg,
@@ -37,3 +42,99 @@ struct dma_debug_entry {
 	int              direction;
 };
 
+struct hash_bucket {
+	struct list_head list;
+	spinlock_t lock;
+} ____cacheline_aligned;
+
+/* Hash list to save the allocated dma addresses */
+static struct hash_bucket dma_entry_hash[HASH_SIZE];
+
+/*
+ * Hash related functions
+ *
+ * Every DMA-API request is saved into a struct dma_debug_entry. To
+ * have quick access to these structs they are stored into a hash.
+ */
+static int hash_fn(struct dma_debug_entry *entry)
+{
+	/*
+	 * Hash function is based on the dma address.
+	 * We use bits 20-27 here as the index into the hash
+	 */
+	return (entry->dev_addr >> HASH_FN_SHIFT) & HASH_FN_MASK;
+}
+
+/*
+ * Request exclusive access to a hash bucket for a given dma_debug_entry.
+ */
+static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry,
+					   unsigned long *flags)
+{
+	int idx = hash_fn(entry);
+	unsigned long __flags;
+
+	spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags);
+	*flags = __flags;
+	return &dma_entry_hash[idx];
+}
+
+/*
+ * Give up exclusive access to the hash bucket
+ */
+static void put_hash_bucket(struct hash_bucket *bucket,
+			    unsigned long *flags)
+{
+	unsigned long __flags = *flags;
+
+	spin_unlock_irqrestore(&bucket->lock, __flags);
+}
+
+/*
+ * Search a given entry in the hash bucket list
+ */
+static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket,
+						struct dma_debug_entry *ref)
+{
+	struct dma_debug_entry *entry;
+
+	list_for_each_entry(entry, &bucket->list, list) {
+		if ((entry->dev_addr == ref->dev_addr) &&
+		    (entry->dev == ref->dev))
+			return entry;
+	}
+
+	return NULL;
+}
+
+/*
+ * Add an entry to a hash bucket
+ */
+static void hash_bucket_add(struct hash_bucket *bucket,
+			    struct dma_debug_entry *entry)
+{
+	list_add_tail(&entry->list, &bucket->list);
+}
+
+/*
+ * Remove entry from a hash bucket list
+ */
+static void hash_bucket_del(struct dma_debug_entry *entry)
+{
+	list_del(&entry->list);
+}
+
+/*
+ * Wrapper function for adding an entry to the hash.
+ * This function takes care of locking itself.
+ */
+static void add_dma_entry(struct dma_debug_entry *entry)
+{
+	struct hash_bucket *bucket;
+	unsigned long flags;
+
+	bucket = get_hash_bucket(entry, &flags);
+	hash_bucket_add(bucket, entry);
+	put_hash_bucket(bucket, &flags);
+}
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 04/16] dma-debug: add allocator code
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (2 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-10 23:43   ` Ingo Molnar
  2009-01-09 16:19 ` [PATCH 05/16] dma-debug: add initialization code Joerg Roedel
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add allocator code for struct dma_debug_entry

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 lib/dma-debug.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 74a0f36..c5444d4 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -49,6 +49,16 @@ struct hash_bucket {
 
 /* Hash list to save the allocated dma addresses */
 static struct hash_bucket dma_entry_hash[HASH_SIZE];
+/* List of pre-allocated dma_debug_entry's */
+static LIST_HEAD(free_entries);
+/* Lock for the list above */
+static DEFINE_SPINLOCK(free_entries_lock);
+
+/* Global disable flag - will be set in case of an error */
+static bool global_disable __read_mostly;
+
+static u32 num_free_entries;
+static u32 min_free_entries;
 
 /*
  * Hash related functions
@@ -138,3 +148,50 @@ static void add_dma_entry(struct dma_debug_entry *entry)
 	put_hash_bucket(bucket, &flags);
 }
 
+/* struct dma_entry allocator
+ *
+ * The next two functions implement the allocator for
+ * struct dma_debug_entries.
+ */
+static struct dma_debug_entry *dma_entry_alloc(void)
+{
+	struct dma_debug_entry *entry = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&free_entries_lock, flags);
+
+	if (list_empty(&free_entries)) {
+		printk(KERN_ERR "DMA-API: debugging out of memory "
+				"- disabling\n");
+		global_disable = true;
+		goto out;
+	}
+
+	entry = list_entry(free_entries.next, struct dma_debug_entry, list);
+	list_del(&entry->list);
+	memset(entry, 0, sizeof(*entry));
+
+	num_free_entries -= 1;
+	if (num_free_entries < min_free_entries)
+		min_free_entries = num_free_entries;
+
+out:
+	spin_unlock_irqrestore(&free_entries_lock, flags);
+
+	return entry;
+}
+
+static void dma_entry_free(struct dma_debug_entry *entry)
+{
+	unsigned long flags;
+
+	/*
+	 * add to beginning of the list - this way the entries are
+	 * more likely cache hot when they are reallocated.
+	 */
+	spin_lock_irqsave(&free_entries_lock, flags);
+	list_add(&entry->list, &free_entries);
+	num_free_entries += 1;
+	spin_unlock_irqrestore(&free_entries_lock, flags);
+}
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 05/16] dma-debug: add initialization code
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (3 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 04/16] dma-debug: add allocator code Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 17:58   ` Evgeniy Polyakov
  2009-01-09 16:19 ` [PATCH 06/16] dma-debug: add kernel command line parameters Joerg Roedel
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add code to initialize dma-debug core data structures

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   14 +++++++++
 lib/dma-debug.c           |   66 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index ce4ace7..345d538 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -20,6 +20,20 @@
 #ifndef __DMA_DEBUG_H
 #define __DMA_DEBUG_H
 
+#include <linux/types.h>
+
 struct device;
 
+#ifdef CONFIG_DMA_API_DEBUG
+
+extern void dma_debug_init(u32 num_entries);
+
+#else /* CONFIG_DMA_API_DEBUG */
+
+static inline void dma_debug_init(u32 num_entries)
+{
+}
+
+#endif /* CONFIG_DMA_API_DEBUG */
+
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index c5444d4..b932f15 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -21,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #define HASH_SIZE       256
 #define HASH_FN_SHIFT   20
@@ -195,3 +196,68 @@ static void dma_entry_free(struct dma_debug_entry *entry)
 	spin_unlock_irqrestore(&free_entries_lock, flags);
 }
 
+/*
+ * DMA-API debugging init code
+ *
+ * The init code does two things:
+ *   1. Initialize core data structures
+ *   2. Preallocate a given number of dma_debug_entry structs
+ */
+
+static int prealloc_memory(u32 num_entries)
+{
+	struct dma_debug_entry *entry, *next_entry;
+	int i;
+
+	for (i = 0; i < num_entries; ++i) {
+		entry = kmalloc(sizeof(*entry), GFP_KERNEL | __GFP_ZERO);
+		if (!entry)
+			goto out_err;
+
+		list_add_tail(&entry->list, &free_entries);
+	}
+
+	num_free_entries = num_entries;
+	min_free_entries = num_entries;
+
+	printk(KERN_INFO "DMA-API: preallocated %d debug entries\n",
+			num_entries);
+
+	return 0;
+
+out_err:
+
+	list_for_each_entry_safe(entry, next_entry, &free_entries, list) {
+		list_del(&entry->list);
+		kfree(entry);
+	}
+
+	return -ENOMEM;
+}
+
+/*
+ * Let the architectures decide how many entries should be preallocated.
+ */
+void dma_debug_init(u32 num_entries)
+{
+	int i;
+
+	if (global_disable)
+		return;
+
+	for (i = 0; i < HASH_SIZE; ++i) {
+		INIT_LIST_HEAD(&dma_entry_hash[i].list);
+		dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED;
+	}
+
+	if (prealloc_memory(num_entries) != 0) {
+		printk(KERN_ERR "DMA-API: debugging out of memory error "
+				"- disabled\n");
+		global_disable = true;
+
+		return;
+	}
+
+	printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n");
+}
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 06/16] dma-debug: add kernel command line parameters
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (4 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 05/16] dma-debug: add initialization code Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 16:19 ` [PATCH 07/16] dma-debug: add debugfs interface Joerg Roedel
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add dma_debug= and dma_debug_entries= kernel parameters

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 Documentation/kernel-parameters.txt |   10 +++++++++
 lib/dma-debug.c                     |   38 +++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index fb84902..4045f76 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -486,6 +486,16 @@ and is between 256 and 4096 characters. It is defined in the file
 			Range: 0 - 8192
 			Default: 64
 
+	dma_debug=off	If the kernel is compiled with DMA_API_DEBUG support
+			this option disables the debugging code at boot.
+
+	dma_debug_entries=<number>
+			This option allows to tune the number of preallocated
+			entries for DMA-API debugging code. One entry is
+			required per DMA-API allocation. Use this if the
+			DMA-API debugging code disables itself because the
+			architectural default is too low.
+
 	hpet=		[X86-32,HPET] option to control HPET usage
 			Format: { enable (default) | disable | force }
 			disable: disable HPET and use PIT instead
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index b932f15..4e58d09 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -61,6 +61,9 @@ static bool global_disable __read_mostly;
 static u32 num_free_entries;
 static u32 min_free_entries;
 
+/* number of preallocated entries requested by kernel cmdline */
+static u32 req_entries;
+
 /*
  * Hash related functions
  *
@@ -250,6 +253,9 @@ void dma_debug_init(u32 num_entries)
 		dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED;
 	}
 
+	if (req_entries)
+		num_entries = req_entries;
+
 	if (prealloc_memory(num_entries) != 0) {
 		printk(KERN_ERR "DMA-API: debugging out of memory error "
 				"- disabled\n");
@@ -261,3 +267,35 @@ void dma_debug_init(u32 num_entries)
 	printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n");
 }
 
+static __init int dma_debug_cmdline(char *str)
+{
+	if (!str)
+		return -EINVAL;
+
+	if (strncmp(str, "off", 3) == 0) {
+		printk(KERN_INFO "DMA-API: debugging disabled on kernel "
+				 "command line\n");
+		global_disable = true;
+	}
+
+	return 0;
+}
+
+static __init int dma_debug_entries_cmdline(char *str)
+{
+	int res;
+
+	if (!str)
+		return -EINVAL;
+
+	res = get_option(&str, &req_entries);
+
+	if (!res)
+		req_entries = 0;
+
+	return 0;
+}
+
+__setup("dma_debug=", dma_debug_cmdline);
+__setup("dma_debug_entries=", dma_debug_entries_cmdline);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 07/16] dma-debug: add debugfs interface
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (5 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 06/16] dma-debug: add kernel command line parameters Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-10 23:08   ` Ingo Molnar
  2009-01-10 23:15   ` Ingo Molnar
  2009-01-09 16:19 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
                   ` (11 subsequent siblings)
  18 siblings, 2 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debugfs interface for configuring DMA-API debugging

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 lib/dma-debug.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 4e58d09..ca0ccb1 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -19,6 +19,7 @@
 
 #include <linux/dma-debug.h>
 #include <linux/spinlock.h>
+#include <linux/debugfs.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -58,12 +59,29 @@ static DEFINE_SPINLOCK(free_entries_lock);
 /* Global disable flag - will be set in case of an error */
 static bool global_disable __read_mostly;
 
+/* Global error count */
+static u32 error_count;
+
+/* Global error show enable*/
+static u32 show_all_errors __read_mostly;
+/* Number of errors to show */
+static u32 show_num_errors = 1;
+
 static u32 num_free_entries;
 static u32 min_free_entries;
 
 /* number of preallocated entries requested by kernel cmdline */
 static u32 req_entries;
 
+/* debugfs dentry's for the stuff above */
+static struct dentry *dma_debug_dent;
+static struct dentry *global_disable_dent;
+static struct dentry *error_count_dent;
+static struct dentry *show_all_errors_dent;
+static struct dentry *show_num_errors_dent;
+static struct dentry *num_free_entries_dent;
+static struct dentry *min_free_entries_dent;
+
 /*
  * Hash related functions
  *
@@ -238,6 +256,58 @@ out_err:
 	return -ENOMEM;
 }
 
+static int dma_debug_fs_init(void)
+{
+	dma_debug_dent = debugfs_create_dir("dma-api", NULL);
+	if (!dma_debug_dent) {
+		printk(KERN_ERR "DMA-API: can not create debugfs directory\n");
+		return -ENOMEM;
+	}
+
+	global_disable_dent = debugfs_create_bool("disabled", 0444,
+			dma_debug_dent,
+			(u32 *)&global_disable);
+	if (!global_disable_dent)
+		goto out_err;
+
+	error_count_dent = debugfs_create_u32("error_count", 0444,
+			dma_debug_dent, &error_count);
+	if (!error_count_dent)
+		goto out_err;
+
+	show_all_errors_dent = debugfs_create_u32("all_errors", 0644,
+			dma_debug_dent,
+			&show_all_errors);
+	if (!show_all_errors_dent)
+		goto out_err;
+
+	show_num_errors_dent = debugfs_create_u32("num_errors", 0644,
+			dma_debug_dent,
+			&show_num_errors);
+	if (!show_num_errors_dent)
+		goto out_err;
+
+	num_free_entries_dent = debugfs_create_u32("num_free_entries", 0444,
+			dma_debug_dent,
+			&num_free_entries);
+	if (!num_free_entries_dent)
+		goto out_err;
+
+	min_free_entries_dent = debugfs_create_u32("min_free_entries", 0444,
+			dma_debug_dent,
+			&min_free_entries);
+	if (!min_free_entries_dent)
+		goto out_err;
+
+	return 0;
+
+out_err:
+	debugfs_remove_recursive(dma_debug_dent);
+
+	return -ENOMEM;
+}
+
+
 /*
  * Let the architectures decide how many entries should be preallocated.
  */
@@ -253,6 +323,14 @@ void dma_debug_init(u32 num_entries)
 		dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED;
 	}
 
+	if (dma_debug_fs_init() != 0) {
+		printk(KERN_ERR "DMA-API: error creating debugfs entries "
+				"- disabling\n");
+		global_disable = true;
+
+		return;
+	}
+
 	if (req_entries)
 		num_entries = req_entries;
 
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 08/16] dma-debug: add core checking functions
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (6 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 07/16] dma-debug: add debugfs interface Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-10 23:11   ` Ingo Molnar
                     ` (2 more replies)
  2009-01-09 16:19 ` [PATCH 09/16] dma-debug: add checking for map/unmap_single Joerg Roedel
                   ` (10 subsequent siblings)
  18 siblings, 3 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add functions to check on dma unmap and sync

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 lib/dma-debug.c |  133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index ca0ccb1..9f730a4 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -17,9 +17,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 #include <linux/spinlock.h>
 #include <linux/debugfs.h>
+#include <linux/device.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -82,6 +84,22 @@ static struct dentry *show_num_errors_dent;
 static struct dentry *num_free_entries_dent;
 static struct dentry *min_free_entries_dent;
 
+static char *type2name[3] = { "single", "scather-gather", "coherent" };
+
+static char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
+			     "DMA_FROM_DEVICE", "DMA_NONE" };
+
+#define err_printk(dev, 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);		\
+		}						\
+		if (!show_all_errors && show_num_errors > 0)	\
+			show_num_errors -= 1;			\
+	} while (0);
+
 /*
  * Hash related functions
  *
@@ -377,3 +395,118 @@ static __init int dma_debug_entries_cmdline(char *str)
 __setup("dma_debug=", dma_debug_cmdline);
 __setup("dma_debug_entries=", dma_debug_entries_cmdline);
 
+static void check_unmap(struct dma_debug_entry *ref)
+{
+	struct dma_debug_entry *entry;
+	struct hash_bucket *bucket;
+	unsigned long flags;
+
+	if (dma_mapping_error(ref->dev, ref->dev_addr))
+		return;
+
+	bucket = get_hash_bucket(ref, &flags);
+	entry = hash_bucket_find(bucket, ref);
+
+	if (!entry) {
+		err_printk(ref->dev, "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);
+		goto out;
+	}
+
+	if (ref->size != entry->size) {
+		err_printk(ref->dev, "DMA-API: device driver frees "
+			   "DMA memory with different size "
+			   "[device address=0x%016llx] [map size=%llu bytes] "
+			   "[unmap size=%llu bytes]\n",
+			   ref->dev_addr, entry->size, ref->size);
+	}
+
+	if (ref->type != entry->type) {
+		err_printk(ref->dev, "DMA-API: device driver frees "
+			   "DMA memory different that it was allocated "
+			   "[device address=0x%016llx] [size=%llu bytes] "
+			   "[mapped as %s] [unmapped as %s]\n",
+			   ref->dev_addr, ref->size,
+			   type2name[entry->type], type2name[ref->type]);
+	} else if ((entry->type == dma_debug_coherent) &&
+		   (ref->cpu_addr != entry->cpu_addr)) {
+		err_printk(ref->dev, "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]",
+			   ref->dev_addr, ref->size,
+			   entry->cpu_addr, ref->cpu_addr);
+	}
+
+	/*
+	 *          * This may be no bug in reality - but most implementations of the
+	 *                   * 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 "
+			   "DMA memory with different direction "
+			   "[device address=0x%016llx] [size=%llu bytes] "
+			   "[mapped with %s] [unmapped with %s]\n",
+			   ref->dev_addr, ref->size,
+			   dir2name[entry->direction],
+			   dir2name[ref->direction]);
+	}
+
+	hash_bucket_del(entry);
+	dma_entry_free(entry);
+
+out:
+	put_hash_bucket(bucket, &flags);
+}
+
+static void check_sync(struct device *dev, dma_addr_t addr,
+		       u64 size, u64 offset, int direction, bool to_cpu)
+{
+	struct dma_debug_entry ref = {
+		.dev            = dev,
+		.dev_addr       = addr,
+		.size           = size,
+		.direction      = direction,
+	};
+	struct dma_debug_entry *entry;
+	struct hash_bucket *bucket;
+	unsigned long flags;
+
+	bucket = get_hash_bucket(&ref, &flags);
+
+	entry = hash_bucket_find(bucket, &ref);
+
+	if (!entry) {
+		err_printk(dev, "DMA-API: device driver tries "
+				"to sync DMA memory it has not allocated "
+				"[device address=0x%016llx] [size=%llu bytes]\n",
+				addr, size);
+		goto out;
+	}
+
+	if ((offset + size) > entry->size) {
+		err_printk(dev, "DMA-API: device driver syncs"
+				" DMA memory outside allocated range "
+				"[device address=0x%016llx] "
+				"[allocation size=%llu bytes] [sync offset=%llu] "
+				"[sync size=%llu]\n", entry->dev_addr, entry->size,
+				offset, size);
+	}
+
+	if (direction != entry->direction) {
+		err_printk(dev, "DMA-API: device driver syncs "
+				"DMA memory with different direction "
+				"[device address=0x%016llx] [size=%llu bytes] "
+				"[mapped with %s] [synced with %s]\n",
+				addr, entry->size,
+				dir2name[entry->direction],
+				dir2name[direction]);
+	}
+
+out:
+	put_hash_bucket(bucket, &flags);
+
+}
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 09/16] dma-debug: add checking for map/unmap_single
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (7 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 16:19 ` [PATCH 10/16] dma-debug: add add checking for map/unmap_sg Joerg Roedel
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debug callbacks for dma_{un}map_single

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   19 +++++++++++++++++++
 lib/dma-debug.c           |   41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index 345d538..82ae9ca 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -28,12 +28,31 @@ struct device;
 
 extern void dma_debug_init(u32 num_entries);
 
+extern void debug_map_single(struct device *dev, void *ptr, size_t size,
+			     int direction, dma_addr_t dma_addr);
+
+extern void debug_unmap_single(struct device *dev, dma_addr_t addr,
+			       size_t size, int direction);
+
+
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_init(u32 num_entries)
 {
 }
 
+static inline void debug_map_single(struct device *dev, void *ptr,
+				    size_t size, int direction,
+				    dma_addr_t dma_addr)
+{
+}
+
+static inline void debug_unmap_single(struct device *dev, dma_addr_t addr,
+				      size_t size, int direction)
+{
+}
+
+
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 9f730a4..d4d14e5 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -510,3 +510,44 @@ out:
 
 }
 
+void debug_map_single(struct device *dev, void *ptr, size_t size,
+		      int direction, dma_addr_t dma_addr)
+{
+	struct dma_debug_entry *entry;
+
+	if (global_disable)
+		return;
+
+	entry = dma_entry_alloc();
+	if (!entry)
+		return;
+
+	entry->dev       = dev;
+	entry->type      = dma_debug_single;
+	entry->cpu_addr  = ptr;
+	entry->dev_addr  = dma_addr;
+	entry->size      = size;
+	entry->direction = direction;
+
+	add_dma_entry(entry);
+}
+EXPORT_SYMBOL(debug_map_single);
+
+void debug_unmap_single(struct device *dev, dma_addr_t addr,
+			size_t size, int direction)
+{
+	struct dma_debug_entry ref = {
+		.type           = dma_debug_single,
+		.dev            = dev,
+		.dev_addr       = addr,
+		.size           = size,
+		.direction      = direction,
+	};
+
+	if (global_disable)
+		return;
+
+	check_unmap(&ref);
+}
+EXPORT_SYMBOL(debug_unmap_single);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 10/16] dma-debug: add add checking for map/unmap_sg
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (8 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 09/16] dma-debug: add checking for map/unmap_single Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 18:08   ` Evgeniy Polyakov
  2009-01-09 16:19 ` [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent Joerg Roedel
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debug callbacks for dma_{un}map_sg

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   15 ++++++++++++
 lib/dma-debug.c           |   53 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index 82ae9ca..b2131f4 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -34,6 +34,11 @@ extern void debug_map_single(struct device *dev, void *ptr, size_t size,
 extern void debug_unmap_single(struct device *dev, dma_addr_t addr,
 			       size_t size, int direction);
 
+extern void debug_map_sg(struct device *dev, struct scatterlist *sg,
+			 int nents, int direction);
+
+extern void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
+			   int nelems, int dir);
 
 #else /* CONFIG_DMA_API_DEBUG */
 
@@ -52,6 +57,16 @@ static inline void debug_unmap_single(struct device *dev, dma_addr_t addr,
 {
 }
 
+static inline void debug_map_sg(struct device *dev, struct scatterlist *sg,
+				int nents, int direction)
+{
+}
+
+static inline void debug_unmap_sg(struct device *dev,
+				  struct scatterlist *sglist,
+				  int nelems, int dir)
+{
+}
 
 #endif /* CONFIG_DMA_API_DEBUG */
 
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index d4d14e5..e6d45f9 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 #include <linux/spinlock.h>
@@ -551,3 +552,55 @@ void debug_unmap_single(struct device *dev, dma_addr_t addr,
 }
 EXPORT_SYMBOL(debug_unmap_single);
 
+void debug_map_sg(struct device *dev, struct scatterlist *sg,
+		  int nents, int direction)
+{
+	struct dma_debug_entry *entry;
+	struct scatterlist *s;
+	int i;
+
+	if (global_disable)
+		return;
+
+	for_each_sg(sg, s, nents, i) {
+		entry = dma_entry_alloc();
+		if (!entry)
+			return;
+
+		entry->type      = dma_debug_sg;
+		entry->dev       = dev;
+		entry->cpu_addr  = sg_virt(s);
+		entry->size      = s->length;
+		entry->dev_addr  = s->dma_address;
+		entry->direction = direction;
+
+		add_dma_entry(entry);
+	}
+}
+EXPORT_SYMBOL(debug_map_sg);
+
+void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
+		    int nelems, int dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	if (global_disable)
+		return;
+
+	for_each_sg(sglist, s, nelems, i) {
+
+		struct dma_debug_entry ref = {
+			.type           = dma_debug_sg,
+			.dev            = dev,
+			.cpu_addr       = sg_virt(s),
+			.dev_addr       = s->dma_address,
+			.size           = s->length,
+			.direction      = dir,
+		};
+
+		check_unmap(&ref);
+	}
+}
+EXPORT_SYMBOL(debug_unmap_sg);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (9 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 10/16] dma-debug: add add checking for map/unmap_sg Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-11  6:25   ` FUJITA Tomonori
  2009-01-09 16:19 ` [PATCH 12/16] dma-debug: add checks for sync_single_* Joerg Roedel
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debug callbacks for dma_[alloc|free]_coherent

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   16 ++++++++++++++++
 lib/dma-debug.c           |   45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index b2131f4..a28a701 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -40,6 +40,12 @@ extern void debug_map_sg(struct device *dev, struct scatterlist *sg,
 extern void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
 			   int nelems, int dir);
 
+extern void debug_alloc_coherent(struct device *dev, size_t size,
+				 dma_addr_t dma_addr, void *virt);
+
+extern void debug_free_coherent(struct device *dev, size_t size,
+				void *virt, dma_addr_t addr);
+
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_init(u32 num_entries)
@@ -68,6 +74,16 @@ static inline void debug_unmap_sg(struct device *dev,
 {
 }
 
+static inline void debug_alloc_coherent(struct device *dev, size_t size,
+					dma_addr_t dma_addr, void *virt)
+{
+}
+
+static inline void debug_free_coherent(struct device *dev, size_t size,
+				       void *virt, dma_addr_t addr)
+{
+}
+
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index e6d45f9..a4a5b0f 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -604,3 +604,48 @@ void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
 }
 EXPORT_SYMBOL(debug_unmap_sg);
 
+void debug_alloc_coherent(struct device *dev, size_t size,
+			  dma_addr_t dma_addr, void *virt)
+{
+	struct dma_debug_entry *entry;
+
+	if (global_disable)
+		return;
+
+	if (dma_addr == bad_dma_address)
+		return;
+
+	entry = dma_entry_alloc();
+	if (!entry)
+		return;
+
+	entry->type      = dma_debug_coherent;
+	entry->dev       = dev;
+	entry->cpu_addr  = virt;
+	entry->size      = size;
+	entry->dev_addr  = dma_addr;
+	entry->direction = DMA_BIDIRECTIONAL;
+
+	add_dma_entry(entry);
+}
+EXPORT_SYMBOL(debug_alloc_coherent);
+
+void debug_free_coherent(struct device *dev, size_t size,
+			 void *virt, dma_addr_t addr)
+{
+	struct dma_debug_entry ref = {
+		.type           = dma_debug_coherent,
+		.dev            = dev,
+		.cpu_addr       = virt,
+		.dev_addr       = addr,
+		.size           = size,
+		.direction      = DMA_BIDIRECTIONAL,
+	};
+
+	if (global_disable)
+		return;
+
+	check_unmap(&ref);
+}
+EXPORT_SYMBOL(debug_free_coherent);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 12/16] dma-debug: add checks for sync_single_*
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (10 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 16:19 ` [PATCH 13/16] dma-debug: add checks for sync_single_range_* Joerg Roedel
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debug callbacks for dma_sync_single_for_* functions

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   20 ++++++++++++++++++++
 lib/dma-debug.c           |   20 ++++++++++++++++++++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index a28a701..f39c2a8 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -46,6 +46,14 @@ extern void debug_alloc_coherent(struct device *dev, size_t size,
 extern void debug_free_coherent(struct device *dev, size_t size,
 				void *virt, dma_addr_t addr);
 
+extern void debug_sync_single_for_cpu(struct device *dev,
+				      dma_addr_t dma_handle, size_t size,
+				      int direction);
+
+extern void debug_sync_single_for_device(struct device *dev,
+					 dma_addr_t dma_handle,
+					 size_t size, int direction);
+
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_init(u32 num_entries)
@@ -84,6 +92,18 @@ static inline void debug_free_coherent(struct device *dev, size_t size,
 {
 }
 
+static inline void debug_sync_single_for_cpu(struct device *dev,
+					     dma_addr_t dma_handle,
+					     size_t size, int direction)
+{
+}
+
+static inline void debug_sync_single_for_device(struct device *dev,
+						dma_addr_t dma_handle,
+						size_t size, int direction)
+{
+}
+
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index a4a5b0f..a7f2369 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -649,3 +649,23 @@ void debug_free_coherent(struct device *dev, size_t size,
 }
 EXPORT_SYMBOL(debug_free_coherent);
 
+void debug_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+			       size_t size, int direction)
+{
+	if (global_disable)
+		return;
+
+	check_sync(dev, dma_handle, size, 0, direction, true);
+}
+EXPORT_SYMBOL(debug_sync_single_for_cpu);
+
+void debug_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+				  size_t size, int direction)
+{
+	if (global_disable)
+		return;
+
+	check_sync(dev, dma_handle, size, 0, direction, false);
+}
+EXPORT_SYMBOL(debug_sync_single_for_device);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 13/16] dma-debug: add checks for sync_single_range_*
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (11 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 12/16] dma-debug: add checks for sync_single_* Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 16:19 ` [PATCH 14/16] dma-debug: add checks for sync_single_sg_* Joerg Roedel
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debug callbacks for dma_sync_single_range_for_* functions

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   26 ++++++++++++++++++++++++++
 lib/dma-debug.c           |   23 +++++++++++++++++++++++
 2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index f39c2a8..b9c221a 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -54,6 +54,16 @@ extern void debug_sync_single_for_device(struct device *dev,
 					 dma_addr_t dma_handle,
 					 size_t size, int direction);
 
+extern void debug_sync_single_range_for_cpu(struct device *dev,
+					    dma_addr_t dma_handle,
+					    unsigned long offset, size_t size,
+					    int direction);
+
+extern void debug_sync_single_range_for_device(struct device *dev,
+					       dma_addr_t dma_handle,
+					       unsigned long offset,
+					       size_t size, int direction);
+
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_init(u32 num_entries)
@@ -104,6 +114,22 @@ static inline void debug_sync_single_for_device(struct device *dev,
 {
 }
 
+static inline void debug_sync_single_range_for_cpu(struct device *dev,
+						   dma_addr_t dma_handle,
+						   unsigned long offset,
+						   size_t size,
+						   int direction)
+{
+}
+
+static inline void debug_sync_single_range_for_device(struct device *dev,
+						      dma_addr_t dma_handle,
+						      unsigned long offset,
+						      size_t size,
+						      int direction)
+{
+}
+
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index a7f2369..6f73bed 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -669,3 +669,26 @@ void debug_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
 }
 EXPORT_SYMBOL(debug_sync_single_for_device);
 
+void debug_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+				     unsigned long offset, size_t size,
+				     int direction)
+{
+	if (global_disable)
+		return;
+
+	check_sync(dev, dma_handle, size, offset, direction, true);
+}
+EXPORT_SYMBOL(debug_sync_single_range_for_cpu);
+
+void debug_sync_single_range_for_device(struct device *dev,
+					dma_addr_t dma_handle,
+					unsigned long offset,
+					size_t size, int direction)
+{
+	if (global_disable)
+		return;
+
+	check_sync(dev, dma_handle, size, offset, direction, false);
+}
+EXPORT_SYMBOL(debug_sync_single_range_for_device);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 14/16] dma-debug: add checks for sync_single_sg_*
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (12 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 13/16] dma-debug: add checks for sync_single_range_* Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-10 23:46   ` Ingo Molnar
  2009-01-09 16:19 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add debug callbacks for dma_sync_sg_* functions

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 include/linux/dma-debug.h |   19 +++++++++++++++++++
 lib/dma-debug.c           |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index b9c221a..bdba8c8 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -64,6 +64,13 @@ extern void debug_sync_single_range_for_device(struct device *dev,
 					       unsigned long offset,
 					       size_t size, int direction);
 
+extern void debug_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+				  int nelems, int direction);
+
+extern void debug_sync_sg_for_device(struct device *dev,
+				     struct scatterlist *sg,
+				     int nelems, int direction);
+
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_init(u32 num_entries)
@@ -130,6 +137,18 @@ static inline void debug_sync_single_range_for_device(struct device *dev,
 {
 }
 
+static inline void debug_sync_sg_for_cpu(struct device *dev,
+					 struct scatterlist *sg,
+					 int nelems, int direction)
+{
+}
+
+static inline void debug_sync_sg_for_device(struct device *dev,
+					    struct scatterlist *sg,
+					    int nelems, int direction)
+{
+}
+
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 6f73bed..e40c88c 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -692,3 +692,35 @@ void debug_sync_single_range_for_device(struct device *dev,
 }
 EXPORT_SYMBOL(debug_sync_single_range_for_device);
 
+void debug_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+			   int nelems, int direction)
+{
+	struct scatterlist *s;
+	int i;
+
+	if (global_disable)
+		return;
+
+	for_each_sg(sg, s, nelems, i) {
+		check_sync(dev, s->dma_address, s->dma_length, 0,
+				direction, true);
+	}
+}
+EXPORT_SYMBOL(debug_sync_sg_for_cpu);
+
+void debug_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			      int nelems, int direction)
+{
+	struct scatterlist *s;
+	int i;
+
+	if (global_disable)
+		return;
+
+	for_each_sg(sg, s, nelems, i) {
+		check_sync(dev, s->dma_address, s->dma_length, 0,
+				direction, false);
+	}
+}
+EXPORT_SYMBOL(debug_sync_sg_for_device);
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 15/16] dma-debug: x86 architecture bindings
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (13 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 14/16] dma-debug: add checks for sync_single_sg_* Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-10 23:04   ` Ingo Molnar
                     ` (2 more replies)
  2009-01-09 16:19 ` [PATCH 16/16] dma-debug: Documentation update Joerg Roedel
                   ` (3 subsequent siblings)
  18 siblings, 3 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: make use of DMA-API debugging code in x86

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/Kconfig                   |    1 +
 arch/x86/include/asm/dma-mapping.h |   30 ++++++++++++++++++++++++++----
 arch/x86/kernel/pci-dma.c          |    5 +++++
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 862adb9..68a806c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -39,6 +39,7 @@ config X86
 	select HAVE_GENERIC_DMA_COHERENT if X86_32
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
 	select USER_STACKTRACE_SUPPORT
+	select HAVE_DMA_API_DEBUG
 
 config ARCH_DEFCONFIG
 	string
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 4035357..939d5b3 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -7,6 +7,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
 #include <asm/io.h>
 #include <asm/swiotlb.h>
 #include <asm-generic/dma-coherent.h>
@@ -93,9 +94,12 @@ dma_map_single(struct device *hwdev, void *ptr, size_t size,
 	       int direction)
 {
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	dma_addr_t addr;
 
 	BUG_ON(!valid_dma_direction(direction));
-	return ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
+	addr = ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
+	debug_map_single(hwdev, ptr, size, direction, addr);
+	return addr;
 }
 
 static inline void
@@ -105,6 +109,7 @@ dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size,
 	struct dma_mapping_ops *ops = get_dma_ops(dev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_unmap_single(dev, addr, size, direction);
 	if (ops->unmap_single)
 		ops->unmap_single(dev, addr, size, direction);
 }
@@ -114,9 +119,13 @@ dma_map_sg(struct device *hwdev, struct scatterlist *sg,
 	   int nents, int direction)
 {
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	int ret;
 
 	BUG_ON(!valid_dma_direction(direction));
-	return ops->map_sg(hwdev, sg, nents, direction);
+	ret = ops->map_sg(hwdev, sg, nents, direction);
+	debug_map_sg(hwdev, sg, ret, direction);
+
+	return ret;
 }
 
 static inline void
@@ -126,6 +135,7 @@ dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_unmap_sg(hwdev, sg, nents, direction);
 	if (ops->unmap_sg)
 		ops->unmap_sg(hwdev, sg, nents, direction);
 }
@@ -137,6 +147,7 @@ dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_sync_single_for_cpu(hwdev, dma_handle, size, direction);
 	if (ops->sync_single_for_cpu)
 		ops->sync_single_for_cpu(hwdev, dma_handle, size, direction);
 	flush_write_buffers();
@@ -149,6 +160,7 @@ dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_sync_single_for_device(hwdev, dma_handle, size, direction);
 	if (ops->sync_single_for_device)
 		ops->sync_single_for_device(hwdev, dma_handle, size, direction);
 	flush_write_buffers();
@@ -161,6 +173,8 @@ dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_sync_single_range_for_cpu(hwdev, dma_handle, offset, size,
+					direction);
 	if (ops->sync_single_range_for_cpu)
 		ops->sync_single_range_for_cpu(hwdev, dma_handle, offset,
 					       size, direction);
@@ -175,6 +189,8 @@ dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+        debug_sync_single_range_for_device(hwdev, dma_handle, offset,
+					   size, direction);
 	if (ops->sync_single_range_for_device)
 		ops->sync_single_range_for_device(hwdev, dma_handle,
 						  offset, size, direction);
@@ -188,6 +204,7 @@ dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_sync_sg_for_cpu(hwdev, sg, nelems, direction);
 	if (ops->sync_sg_for_cpu)
 		ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
 	flush_write_buffers();
@@ -200,6 +217,7 @@ dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
 	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
 
 	BUG_ON(!valid_dma_direction(direction));
+	debug_sync_sg_for_device(hwdev, sg, nelems, direction);
 	if (ops->sync_sg_for_device)
 		ops->sync_sg_for_device(hwdev, sg, nelems, direction);
 
@@ -267,7 +285,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		gfp_t gfp)
 {
 	struct dma_mapping_ops *ops = get_dma_ops(dev);
-	void *memory;
+	void *memory, *addr;
 
 	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
 
@@ -285,8 +303,11 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
 	if (!ops->alloc_coherent)
 		return NULL;
 
-	return ops->alloc_coherent(dev, size, dma_handle,
+	addr = ops->alloc_coherent(dev, size, dma_handle,
 				   dma_alloc_coherent_gfp_flags(dev, gfp));
+	debug_alloc_coherent(dev, size, *dma_handle, addr);
+
+	return addr;
 }
 
 static inline void dma_free_coherent(struct device *dev, size_t size,
@@ -299,6 +320,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 	if (dma_release_from_coherent(dev, get_order(size), vaddr))
 		return;
 
+	debug_free_coherent(dev, size, vaddr, bus);
 	if (ops->free_coherent)
 		ops->free_coherent(dev, size, vaddr, bus);
 }
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index b254285..c8efbcc 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -44,6 +44,9 @@ struct device x86_dma_fallback_dev = {
 };
 EXPORT_SYMBOL(x86_dma_fallback_dev);
 
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_ENTRIES	8192	/* needs 512kb */
+
 int dma_set_mask(struct device *dev, u64 mask)
 {
 	if (!dev->dma_mask || !dma_supported(dev, mask))
@@ -265,6 +268,8 @@ EXPORT_SYMBOL(dma_supported);
 
 static int __init pci_iommu_init(void)
 {
+	dma_debug_init(PREALLOC_ENTRIES);
+
 	calgary_iommu_init();
 
 	intel_iommu_init();
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 16/16] dma-debug: Documentation update
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (14 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
@ 2009-01-09 16:19 ` Joerg Roedel
  2009-01-09 21:24 ` [PATCH 0/16] DMA-API debugging facility v2 Michael Chan
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 16:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, dwmw2, fujita.tomonori, netdev, iommu, Joerg Roedel

Impact: add documentation about DMA-API debugging to DMA-API.txt

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 Documentation/DMA-API.txt |  117 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index b462bb1..e36e85a 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -610,3 +610,120 @@ size is the size (and should be a page-sized multiple).
 The return value will be either a pointer to the processor virtual
 address of the memory, or an error (via PTR_ERR()) if any part of the
 region is occupied.
+
+Part III - Debug drivers use of the DMA-API
+-------------------------------------------
+
+The DMA-API as described above as some constraints. DMA addresses must be
+released with the corresponding function with the same size for example. With
+the advent of hardware IOMMUs it becomes more and more important that drivers
+do not violate those constraints. In the worst case such a violation can
+result in data corruption up to destroyed filesystems.
+
+To debug drivers and find bugs in the usage of the DMA-API checking code can
+be compiled into the kernel which will tell the developer about those
+violations. If your architecture supports it you can select the "Enable
+debugging of DMA-API usage" option in your kernel configuration. Enabling this
+option has a performance impact. Do not enable it in production kernels.
+
+If you boot the resulting kernel will contain code which does some bookkeeping
+about what DMA memory was allocated for which device. If this code detects an
+error it prints a warning message with some details into your kernel log. An
+example warning message may look like this:
+
+------------[ cut here ]------------
+WARNING: at /data2/repos/linux.trees.git/lib/dma-debug.c:231
+	check_unmap+0xab/0x3d9()
+Hardware name: Toonie
+bnx2 0000:01:00.0: DMA-API: device driver tries to free DMA
+	memory it has not allocated [device address=0x00000000011]
+Modules linked in:
+Pid: 0, comm: swapper Not tainted 2.6.28 #174
+Call Trace:
+ <IRQ>  [<ffffffff8105af3a>] warn_slowpath+0xd3/0xf2
+ [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
+ [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
+ [<ffffffff812efd16>] ? usb_hcd_link_urb_to_ep+0x94/0xa0
+ [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
+ [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
+ [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
+ [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
+ [<ffffffff814b25a5>] ? _spin_lock_irqsave+0x69/0x75
+ [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
+ [<ffffffff811e2ff2>] check_unmap+0xab/0x3d9
+ [<ffffffff8107c9ed>] ? trace_hardirqs_on_caller+0x108/0x14a
+ [<ffffffff8107ca3c>] ? trace_hardirqs_on+0xd/0xf
+ [<ffffffff811e3433>] debug_unmap_single+0x3e/0x40
+ [<ffffffff8128d2d8>] dma_unmap_single+0x3d/0x60
+ [<ffffffff8128d335>] pci_unmap_page+0x1c/0x1e
+ [<ffffffff81290759>] bnx2_poll_work+0x626/0x8cb
+ [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
+ [<ffffffff81070100>] ? run_posix_cpu_timers+0x49c/0x603
+ [<ffffffff81070000>] ? run_posix_cpu_timers+0x39c/0x603
+ [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
+ [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
+ [<ffffffff81292804>] bnx2_poll_msix+0x33/0x81
+ [<ffffffff813b6478>] net_rx_action+0x8a/0x139
+ [<ffffffff8105ff39>] __do_softirq+0x8b/0x147
+ [<ffffffff8102933c>] call_softirq+0x1c/0x34
+ [<ffffffff8102a611>] do_softirq+0x39/0x90
+ [<ffffffff8105fde8>] irq_exit+0x4e/0x98
+ [<ffffffff8102a5c2>] do_IRQ+0x11f/0x135
+ [<ffffffff81028b93>] ret_from_intr+0x0/0xf
+ <EOI> <4>---[ end trace 4339d58302097423 ]---
+
+The driver developer can find the driver and the device including a stacktrace
+of the DMA-API call which caused this warning.
+
+Per default only the first error will result in a warning message. All other
+errors will only silently counted. This limitation exist to prevent the code
+from flooding your kernel log. To support debugging a device driver this can
+be disabled via debugfs. See the debugfs interface documentation below for
+details.
+
+The debugfs directory for the DMA-API debugging code is called dma-api/. In
+this directory the following files can currently be found:
+
+	dma-api/all_errors	This file contains a numeric value. If this
+				value is not equal to zero the debugging code
+				will print a warning for every error it finds
+				into the kernel log. Be carefull with this
+				option. It can easily flood your logs.
+	
+	dma-api/disabled	This read-only file contains the character 'Y'
+				if the debugging code is disabled. This can
+				happen when it runs out of memory or if it was
+				disabled at boot time
+
+	dma-api/error_count	This file is read-only and shows the total
+				numbers of errors found.
+
+	dma-api/num_errors	The number in this file shows how many
+				warnings will be printed to the kernel log
+				before it stops. This number is initialized to
+				one at system boot and be set by writing into
+				this file
+
+	dma-api/min_free_entries
+				This read-only file can be read to get the
+				minimum number of free dma_debug_entries the
+				allocator has ever seen. If this value goes
+				down to zero the code will disable itself
+				because it is not longer reliable.
+
+	dma-api/num_free_entries
+				The current number of free dma_debug_entries
+				in the allocator.
+
+If you have this code compiled into your kernel it will be enabled by default.
+If you want to boot without the bookkeeping anyway you can provide
+'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
+Notice that you can not enable it again at runtime. You have to reboot to do
+so.
+
+When the code disables itself at runtime this is most likely because it ran
+out of dma_debug_entries. These entries are preallocated at boot. The number
+of preallocated entries is defined per architecture. If it is too low for you
+boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
+architectural default.
+
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-09 16:19 ` [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Joerg Roedel
@ 2009-01-09 17:55   ` Evgeniy Polyakov
  2009-01-09 18:14     ` Joerg Roedel
  2009-01-13  8:51   ` Andrew Morton
  1 sibling, 1 reply; 72+ messages in thread
From: Evgeniy Polyakov @ 2009-01-09 17:55 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

Hi Joerg.

On Fri, Jan 09, 2009 at 05:19:17PM +0100, Joerg Roedel (joerg.roedel@amd.com) wrote:
> +/*
> + * Request exclusive access to a hash bucket for a given dma_debug_entry.
> + */
> +static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry,
> +					   unsigned long *flags)
> +{
> +	int idx = hash_fn(entry);
> +	unsigned long __flags;
> +
> +	spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags);
> +	*flags = __flags;
> +	return &dma_entry_hash[idx];
> +}
> +
> +/*
> + * Give up exclusive access to the hash bucket
> + */
> +static void put_hash_bucket(struct hash_bucket *bucket,
> +			    unsigned long *flags)
> +{
> +	unsigned long __flags = *flags;
> +
> +	spin_unlock_irqrestore(&bucket->lock, __flags);
> +}

Why do you need such ugly helpers?

> + * Add an entry to a hash bucket
> + */
> +static void hash_bucket_add(struct hash_bucket *bucket,
> +			    struct dma_debug_entry *entry)
> +{
> +	list_add_tail(&entry->list, &bucket->list);
> +}

> +/*
> + * Remove entry from a hash bucket list
> + */
> +static void hash_bucket_del(struct dma_debug_entry *entry)
> +{
> +	list_del(&entry->list);
> +}

Do you really need this getting they are called only from single place?

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 05/16] dma-debug: add initialization code
  2009-01-09 16:19 ` [PATCH 05/16] dma-debug: add initialization code Joerg Roedel
@ 2009-01-09 17:58   ` Evgeniy Polyakov
  2009-01-09 18:17     ` Joerg Roedel
  0 siblings, 1 reply; 72+ messages in thread
From: Evgeniy Polyakov @ 2009-01-09 17:58 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, Jan 09, 2009 at 05:19:19PM +0100, Joerg Roedel (joerg.roedel@amd.com) wrote:
 +static int prealloc_memory(u32 num_entries)
> +{
> +	struct dma_debug_entry *entry, *next_entry;
> +	int i;
> +
> +	for (i = 0; i < num_entries; ++i) {
> +		entry = kmalloc(sizeof(*entry), GFP_KERNEL | __GFP_ZERO);

kzalloc?


-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 10/16] dma-debug: add add checking for map/unmap_sg
  2009-01-09 16:19 ` [PATCH 10/16] dma-debug: add add checking for map/unmap_sg Joerg Roedel
@ 2009-01-09 18:08   ` Evgeniy Polyakov
  2009-01-09 18:11     ` Joerg Roedel
  0 siblings, 1 reply; 72+ messages in thread
From: Evgeniy Polyakov @ 2009-01-09 18:08 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, Jan 09, 2009 at 05:19:24PM +0100, Joerg Roedel (joerg.roedel@amd.com) wrote:
> +void debug_map_sg(struct device *dev, struct scatterlist *sg,
> +		  int nents, int direction)
> +{
> +	struct dma_debug_entry *entry;
> +	struct scatterlist *s;
> +	int i;
> +
> +	if (global_disable)
> +		return;
> +
> +	for_each_sg(sg, s, nents, i) {
> +		entry = dma_entry_alloc();
> +		if (!entry)
> +			return;
> +
> +		entry->type      = dma_debug_sg;
> +		entry->dev       = dev;
> +		entry->cpu_addr  = sg_virt(s);
> +		entry->size      = s->length;
> +		entry->dev_addr  = s->dma_address;
> +		entry->direction = direction;
> +
> +		add_dma_entry(entry);
> +	}
> +}
> +EXPORT_SYMBOL(debug_map_sg);
> +
> +void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
> +		    int nelems, int dir)
> +{
> +	struct scatterlist *s;
> +	int i;
> +
> +	if (global_disable)
> +		return;
> +
> +	for_each_sg(sglist, s, nelems, i) {
> +
> +		struct dma_debug_entry ref = {
> +			.type           = dma_debug_sg,
> +			.dev            = dev,
> +			.cpu_addr       = sg_virt(s),
> +			.dev_addr       = s->dma_address,
> +			.size           = s->length,
> +			.direction      = dir,
> +		};
> +
> +		check_unmap(&ref);

Will this print false errors if above map debug failed to add an entry
into the list?

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 10/16] dma-debug: add add checking for map/unmap_sg
  2009-01-09 18:08   ` Evgeniy Polyakov
@ 2009-01-09 18:11     ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 18:11 UTC (permalink / raw)
  To: Evgeniy Polyakov; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Fri, Jan 09, 2009 at 09:08:36PM +0300, Evgeniy Polyakov wrote:
> On Fri, Jan 09, 2009 at 05:19:24PM +0100, Joerg Roedel (joerg.roedel@amd.com) wrote:
> > +void debug_map_sg(struct device *dev, struct scatterlist *sg,
> > +		  int nents, int direction)
> > +{
> > +	struct dma_debug_entry *entry;
> > +	struct scatterlist *s;
> > +	int i;
> > +
> > +	if (global_disable)
> > +		return;
> > +
> > +	for_each_sg(sg, s, nents, i) {
> > +		entry = dma_entry_alloc();
> > +		if (!entry)
> > +			return;
> > +
> > +		entry->type      = dma_debug_sg;
> > +		entry->dev       = dev;
> > +		entry->cpu_addr  = sg_virt(s);
> > +		entry->size      = s->length;
> > +		entry->dev_addr  = s->dma_address;
> > +		entry->direction = direction;
> > +
> > +		add_dma_entry(entry);
> > +	}
> > +}
> > +EXPORT_SYMBOL(debug_map_sg);
> > +
> > +void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
> > +		    int nelems, int dir)
> > +{
> > +	struct scatterlist *s;
> > +	int i;
> > +
> > +	if (global_disable)
> > +		return;
> > +
> > +	for_each_sg(sglist, s, nelems, i) {
> > +
> > +		struct dma_debug_entry ref = {
> > +			.type           = dma_debug_sg,
> > +			.dev            = dev,
> > +			.cpu_addr       = sg_virt(s),
> > +			.dev_addr       = s->dma_address,
> > +			.size           = s->length,
> > +			.direction      = dir,
> > +		};
> > +
> > +		check_unmap(&ref);
> 
> Will this print false errors if above map debug failed to add an entry
> into the list?

No. The code disables itself if adding an entry fails. This can only
happen when we run out of preallocated dma_debug_entries.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-09 17:55   ` Evgeniy Polyakov
@ 2009-01-09 18:14     ` Joerg Roedel
  2009-01-09 18:23       ` Evgeniy Polyakov
  0 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 18:14 UTC (permalink / raw)
  To: Evgeniy Polyakov; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Fri, Jan 09, 2009 at 08:55:42PM +0300, Evgeniy Polyakov wrote:
> Hi Joerg.
> 
> On Fri, Jan 09, 2009 at 05:19:17PM +0100, Joerg Roedel (joerg.roedel@amd.com) wrote:
> > +/*
> > + * Request exclusive access to a hash bucket for a given dma_debug_entry.
> > + */
> > +static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry,
> > +					   unsigned long *flags)
> > +{
> > +	int idx = hash_fn(entry);
> > +	unsigned long __flags;
> > +
> > +	spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags);
> > +	*flags = __flags;
> > +	return &dma_entry_hash[idx];
> > +}
> > +
> > +/*
> > + * Give up exclusive access to the hash bucket
> > + */
> > +static void put_hash_bucket(struct hash_bucket *bucket,
> > +			    unsigned long *flags)
> > +{
> > +	unsigned long __flags = *flags;
> > +
> > +	spin_unlock_irqrestore(&bucket->lock, __flags);
> > +}
> 
> Why do you need such ugly helpers?

Because everything else I thought about here was even more ugly. But
maybe you have a better idea? I tried to lock directly in the debug_
functions. But this is ugly and unnecessary code duplication.

> 
> > + * Add an entry to a hash bucket
> > + */
> > +static void hash_bucket_add(struct hash_bucket *bucket,
> > +			    struct dma_debug_entry *entry)
> > +{
> > +	list_add_tail(&entry->list, &bucket->list);
> > +}
> 
> > +/*
> > + * Remove entry from a hash bucket list
> > + */
> > +static void hash_bucket_del(struct dma_debug_entry *entry)
> > +{
> > +	list_del(&entry->list);
> > +}
> 
> Do you really need this getting they are called only from single place?

Hmm, true. I will inline these functions.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 05/16] dma-debug: add initialization code
  2009-01-09 17:58   ` Evgeniy Polyakov
@ 2009-01-09 18:17     ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 18:17 UTC (permalink / raw)
  To: Evgeniy Polyakov; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Fri, Jan 09, 2009 at 08:58:42PM +0300, Evgeniy Polyakov wrote:
> On Fri, Jan 09, 2009 at 05:19:19PM +0100, Joerg Roedel (joerg.roedel@amd.com) wrote:
>  +static int prealloc_memory(u32 num_entries)
> > +{
> > +	struct dma_debug_entry *entry, *next_entry;
> > +	int i;
> > +
> > +	for (i = 0; i < num_entries; ++i) {
> > +		entry = kmalloc(sizeof(*entry), GFP_KERNEL | __GFP_ZERO);
> 
> kzalloc?

True. kzalloc is better. I will change that.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-09 18:14     ` Joerg Roedel
@ 2009-01-09 18:23       ` Evgeniy Polyakov
  2009-01-09 18:40         ` Joerg Roedel
  0 siblings, 1 reply; 72+ messages in thread
From: Evgeniy Polyakov @ 2009-01-09 18:23 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Fri, Jan 09, 2009 at 07:14:46PM +0100, Joerg Roedel (joro@8bytes.org) wrote:
> > > +static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry,
> > > +					   unsigned long *flags)
> > > +{
> > > +	int idx = hash_fn(entry);
> > > +	unsigned long __flags;
> > > +
> > > +	spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags);
> > > +	*flags = __flags;
> > > +	return &dma_entry_hash[idx];
> > > +}
> > > +
> > > +/*
> > > + * Give up exclusive access to the hash bucket
> > > + */
> > > +static void put_hash_bucket(struct hash_bucket *bucket,
> > > +			    unsigned long *flags)
> > > +{
> > > +	unsigned long __flags = *flags;
> > > +
> > > +	spin_unlock_irqrestore(&bucket->lock, __flags);
> > > +}
> > 
> > Why do you need such ugly helpers?
> 
> Because everything else I thought about here was even more ugly. But
> maybe you have a better idea? I tried to lock directly in the debug_
> functions. But this is ugly and unnecessary code duplication.

I believe that having direct locking in the debug_ functions is not a
duplication, anyone will have a direct vision on the locking and hash
array dereference, and this will be just one additional line compared to
the get_* call and the same number of lines for the put :)

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-09 18:23       ` Evgeniy Polyakov
@ 2009-01-09 18:40         ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 18:40 UTC (permalink / raw)
  To: Evgeniy Polyakov; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Fri, Jan 09, 2009 at 09:23:39PM +0300, Evgeniy Polyakov wrote:
> On Fri, Jan 09, 2009 at 07:14:46PM +0100, Joerg Roedel (joro@8bytes.org) wrote:
> > > > +static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry,
> > > > +					   unsigned long *flags)
> > > > +{
> > > > +	int idx = hash_fn(entry);
> > > > +	unsigned long __flags;
> > > > +
> > > > +	spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags);
> > > > +	*flags = __flags;
> > > > +	return &dma_entry_hash[idx];
> > > > +}
> > > > +
> > > > +/*
> > > > + * Give up exclusive access to the hash bucket
> > > > + */
> > > > +static void put_hash_bucket(struct hash_bucket *bucket,
> > > > +			    unsigned long *flags)
> > > > +{
> > > > +	unsigned long __flags = *flags;
> > > > +
> > > > +	spin_unlock_irqrestore(&bucket->lock, __flags);
> > > > +}
> > > 
> > > Why do you need such ugly helpers?
> > 
> > Because everything else I thought about here was even more ugly. But
> > maybe you have a better idea? I tried to lock directly in the debug_
> > functions. But this is ugly and unnecessary code duplication.
> 
> I believe that having direct locking in the debug_ functions is not a
> duplication, anyone will have a direct vision on the locking and hash
> array dereference, and this will be just one additional line compared to
> the get_* call and the same number of lines for the put :)

Even more additional lines because of the additional variables needed in
every function. Anyway, I try it and if it does not look good I will
keep that change ;)

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 01/16] dma-debug: add Kconfig entry
  2009-01-09 16:19 ` [PATCH 01/16] dma-debug: add Kconfig entry Joerg Roedel
@ 2009-01-09 20:12   ` Randy Dunlap
  0 siblings, 0 replies; 72+ messages in thread
From: Randy Dunlap @ 2009-01-09 20:12 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, 9 Jan 2009 17:19:15 +0100 Joerg Roedel wrote:

> Impact: add a Kconfig entry for DMA-API debugging

Surely Impact: is (meant to be) different from the actual patch description... ?


> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
>  arch/Kconfig      |    2 ++
>  lib/Kconfig.debug |   11 +++++++++++
>  2 files changed, 13 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 2e13aa2..068554c 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -103,3 +103,5 @@ config HAVE_CLK
>  	  The <linux/clk.h> calls support software clock gating and
>  	  thus are a key power management tool on many systems.
>  
> +config HAVE_DMA_API_DEBUG
> +	bool
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 2e75478..cba5778 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -899,6 +899,17 @@ config DYNAMIC_PRINTK_DEBUG
>  	  debugging for all modules. This mode can be turned off via the above
>  	  disable command.
>  
> +config DMA_API_DEBUG
> +	bool "Enable debugging of DMA-API usage"
> +	depends on HAVE_DMA_API_DEBUG
> +	help
> +	  Enable this option to debug the use of the DMA API by device drivers.
> +	  With this option you will be able to detect common bugs in device
> +	  drivers like double-freeing of DMA mappings or freeing mappings that
> +	  were never allocated.
> +	  This option causes a performance degredation.  Use only if you want
> +	  to debug device drivers. If unsure, say N.
> +
>  source "samples/Kconfig"
>  
>  source "lib/Kconfig.kgdb"
> -- 

---
~Randy

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (15 preceding siblings ...)
  2009-01-09 16:19 ` [PATCH 16/16] dma-debug: Documentation update Joerg Roedel
@ 2009-01-09 21:24 ` Michael Chan
  2009-01-09 22:33   ` Joerg Roedel
  2009-01-10 23:54 ` Ingo Molnar
  2009-02-05 22:52 ` David Woodhouse
  18 siblings, 1 reply; 72+ messages in thread
From: Michael Chan @ 2009-01-09 21:24 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


On Fri, 2009-01-09 at 08:19 -0800, Joerg Roedel wrote:
> 
> With the code these patches introduce driver developers can find several
> bugs of misusing the DMA-API in their drivers. But be aware, it can not
> find all possible bugs. If it finds a problem it prints out messages
> like
> 
> ------------[ cut here ]------------
> WARNING: at /data2/repos/linux.trees.git/lib/dma-debug.c:231 check_unmap+0xab/0x3d9()
> Hardware name: Toonie
> bnx2 0000:01:00.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x00000000011]
> Modules linked in:
> Pid: 0, comm: swapper Not tainted 2.6.28 #174
> Call Trace:
>  <IRQ>  [<ffffffff8105af3a>] warn_slowpath+0xd3/0xf2
>  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
>  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
>  [<ffffffff812efd16>] ? usb_hcd_link_urb_to_ep+0x94/0xa0
>  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
>  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
>  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
>  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
>  [<ffffffff814b25a5>] ? _spin_lock_irqsave+0x69/0x75
>  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
>  [<ffffffff811e2ff2>] check_unmap+0xab/0x3d9
>  [<ffffffff8107c9ed>] ? trace_hardirqs_on_caller+0x108/0x14a
>  [<ffffffff8107ca3c>] ? trace_hardirqs_on+0xd/0xf
>  [<ffffffff811e3433>] debug_unmap_single+0x3e/0x40
>  [<ffffffff8128d2d8>] dma_unmap_single+0x3d/0x60
>  [<ffffffff8128d335>] pci_unmap_page+0x1c/0x1e
>  [<ffffffff81290759>] bnx2_poll_work+0x626/0x8cb
>  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
>  [<ffffffff81070100>] ? run_posix_cpu_timers+0x49c/0x603
>  [<ffffffff81070000>] ? run_posix_cpu_timers+0x39c/0x603
>  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
>  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
>  [<ffffffff81292804>] bnx2_poll_msix+0x33/0x81
>  [<ffffffff813b6478>] net_rx_action+0x8a/0x139
>  [<ffffffff8105ff39>] __do_softirq+0x8b/0x147
>  [<ffffffff8102933c>] call_softirq+0x1c/0x34
>  [<ffffffff8102a611>] do_softirq+0x39/0x90
>  [<ffffffff8105fde8>] irq_exit+0x4e/0x98
>  [<ffffffff8102a5c2>] do_IRQ+0x11f/0x135
>  [<ffffffff81028b93>] ret_from_intr+0x0/0xf
>  <EOI> <4>---[ end trace 4339d58302097423 ]---
> 
This was triggered during pci_unmap_page() -> dma_unmap_single() where
check_unmap() did not find the entry.

The original mapping was done in bnx2 using pci_map_page().  I did not
see how the debug entry was added to the hash during the call to
pci_map_page() -> dma_map_page().  Did I miss something?

Thanks.



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-09 21:24 ` [PATCH 0/16] DMA-API debugging facility v2 Michael Chan
@ 2009-01-09 22:33   ` Joerg Roedel
  2009-01-09 22:37     ` Joerg Roedel
  0 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 22:33 UTC (permalink / raw)
  To: Michael Chan; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Fri, Jan 09, 2009 at 01:24:24PM -0800, Michael Chan wrote:
> 
> On Fri, 2009-01-09 at 08:19 -0800, Joerg Roedel wrote:
> > 
> > With the code these patches introduce driver developers can find several
> > bugs of misusing the DMA-API in their drivers. But be aware, it can not
> > find all possible bugs. If it finds a problem it prints out messages
> > like
> > 
> > ------------[ cut here ]------------
> > WARNING: at /data2/repos/linux.trees.git/lib/dma-debug.c:231 check_unmap+0xab/0x3d9()
> > Hardware name: Toonie
> > bnx2 0000:01:00.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x00000000011]
> > Modules linked in:
> > Pid: 0, comm: swapper Not tainted 2.6.28 #174
> > Call Trace:
> >  <IRQ>  [<ffffffff8105af3a>] warn_slowpath+0xd3/0xf2
> >  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
> >  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
> >  [<ffffffff812efd16>] ? usb_hcd_link_urb_to_ep+0x94/0xa0
> >  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
> >  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
> >  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
> >  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
> >  [<ffffffff814b25a5>] ? _spin_lock_irqsave+0x69/0x75
> >  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
> >  [<ffffffff811e2ff2>] check_unmap+0xab/0x3d9
> >  [<ffffffff8107c9ed>] ? trace_hardirqs_on_caller+0x108/0x14a
> >  [<ffffffff8107ca3c>] ? trace_hardirqs_on+0xd/0xf
> >  [<ffffffff811e3433>] debug_unmap_single+0x3e/0x40
> >  [<ffffffff8128d2d8>] dma_unmap_single+0x3d/0x60
> >  [<ffffffff8128d335>] pci_unmap_page+0x1c/0x1e
> >  [<ffffffff81290759>] bnx2_poll_work+0x626/0x8cb
> >  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
> >  [<ffffffff81070100>] ? run_posix_cpu_timers+0x49c/0x603
> >  [<ffffffff81070000>] ? run_posix_cpu_timers+0x39c/0x603
> >  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
> >  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
> >  [<ffffffff81292804>] bnx2_poll_msix+0x33/0x81
> >  [<ffffffff813b6478>] net_rx_action+0x8a/0x139
> >  [<ffffffff8105ff39>] __do_softirq+0x8b/0x147
> >  [<ffffffff8102933c>] call_softirq+0x1c/0x34
> >  [<ffffffff8102a611>] do_softirq+0x39/0x90
> >  [<ffffffff8105fde8>] irq_exit+0x4e/0x98
> >  [<ffffffff8102a5c2>] do_IRQ+0x11f/0x135
> >  [<ffffffff81028b93>] ret_from_intr+0x0/0xf
> >  <EOI> <4>---[ end trace 4339d58302097423 ]---
> > 
> This was triggered during pci_unmap_page() -> dma_unmap_single() where
> check_unmap() did not find the entry.
> 
> The original mapping was done in bnx2 using pci_map_page().  I did not
> see how the debug entry was added to the hash during the call to
> pci_map_page() -> dma_map_page().  Did I miss something?

dma_map_page() results in dma_map_single() -> debug_map_single() call on
x86. This way the entry would be added. Maybe the error from a double
free?

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-09 22:33   ` Joerg Roedel
@ 2009-01-09 22:37     ` Joerg Roedel
  2009-01-11  6:25       ` FUJITA Tomonori
  0 siblings, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-09 22:37 UTC (permalink / raw)
  To: Michael Chan; +Cc: iommu, mingo, linux-kernel, netdev

On Fri, Jan 09, 2009 at 11:33:27PM +0100, Joerg Roedel wrote:
> > This was triggered during pci_unmap_page() -> dma_unmap_single() where
> > check_unmap() did not find the entry.
> > 
> > The original mapping was done in bnx2 using pci_map_page().  I did not
> > see how the debug entry was added to the hash during the call to
> > pci_map_page() -> dma_map_page().  Did I miss something?
> 
> dma_map_page() results in dma_map_single() -> debug_map_single() call on
> x86. This way the entry would be added. Maybe the error from a double
> free?

Ah, it only calls ops->map_single. Thanks for pointing that out. I will
add a call to debug_map_single to dma_map_page too. So the error above
may be a false positive.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/16] dma-debug: x86 architecture bindings
  2009-01-09 16:19 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
@ 2009-01-10 23:04   ` Ingo Molnar
  2009-01-10 23:48   ` Ingo Molnar
  2009-01-11  6:25   ` FUJITA Tomonori
  2 siblings, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:04 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> @@ -105,6 +109,7 @@ dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size,
>  	struct dma_mapping_ops *ops = get_dma_ops(dev);
>  
>  	BUG_ON(!valid_dma_direction(direction));
> +	debug_unmap_single(dev, addr, size, direction);

It all looks very nice, i've got one small namespace structure request: 
could you please name all the callbacks in a consistent way, so that they 
mirror the method they instrument - with a "debug_" prefix?

I.e. the above one would be: debug_dma_unmap_single().

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/16] dma-debug: add debugfs interface
  2009-01-09 16:19 ` [PATCH 07/16] dma-debug: add debugfs interface Joerg Roedel
@ 2009-01-10 23:08   ` Ingo Molnar
  2009-01-11  7:52     ` Joerg Roedel
  2009-01-14 15:22     ` Joerg Roedel
  2009-01-10 23:15   ` Ingo Molnar
  1 sibling, 2 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:08 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +/* Global error count */
> +static u32 error_count;
> +
> +/* Global error show enable*/
> +static u32 show_all_errors __read_mostly;
> +/* Number of errors to show */
> +static u32 show_num_errors = 1;
> +
>  static u32 num_free_entries;
>  static u32 min_free_entries;

Small detail: please use native C types for non-hardware variables - 
'unsigned int', 'unsigned long', etc.

u32/u64 is typically used for variables where there is a real significance 
to the precise width of the variable: there's either a hardware or a 
user-space ABI involved.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-09 16:19 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
@ 2009-01-10 23:11   ` Ingo Molnar
  2009-01-11  7:57     ` Joerg Roedel
  2009-01-14 11:44     ` Joerg Roedel
  2009-01-10 23:12   ` Ingo Molnar
  2009-01-10 23:13   ` Ingo Molnar
  2 siblings, 2 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:11 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +#define err_printk(dev, 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);		\
> +		}						\
> +		if (!show_all_errors && show_num_errors > 0)	\
> +			show_num_errors -= 1;			\

Note that the arithmetics here is SMP-unsafe: we only hold the hash bucket 
so if two errors hit at once on two CPUs then the error tracking variables 
can be accessed at once.

I'd suggest a simple global lock for this error case (taken inside the 
hash bucket lock), to be on the safe side.

Also, please dont use a macro for this - printk details can be passed in 
to helper inlines/functions too.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-09 16:19 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
  2009-01-10 23:11   ` Ingo Molnar
@ 2009-01-10 23:12   ` Ingo Molnar
  2009-01-11  7:54     ` Joerg Roedel
  2009-01-10 23:13   ` Ingo Molnar
  2 siblings, 1 reply; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:12 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +	/*
> +	 *          * This may be no bug in reality - but most implementations of the
> +	 *                   * DMA API don't handle this properly, so check for it here
> +	 *                            */

You must be using Vim and copy & paste messed up? :)

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-09 16:19 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
  2009-01-10 23:11   ` Ingo Molnar
  2009-01-10 23:12   ` Ingo Molnar
@ 2009-01-10 23:13   ` Ingo Molnar
  2 siblings, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:13 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +static char *type2name[3] = { "single", "scather-gather", "coherent" };
> +
> +static char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
> +			     "DMA_FROM_DEVICE", "DMA_NONE" };

Should be const i guess.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/16] dma-debug: add debugfs interface
  2009-01-09 16:19 ` [PATCH 07/16] dma-debug: add debugfs interface Joerg Roedel
  2009-01-10 23:08   ` Ingo Molnar
@ 2009-01-10 23:15   ` Ingo Molnar
  1 sibling, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:15 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +/* debugfs dentry's for the stuff above */
> +static struct dentry *dma_debug_dent;
> +static struct dentry *global_disable_dent;
> +static struct dentry *error_count_dent;
> +static struct dentry *show_all_errors_dent;
> +static struct dentry *show_num_errors_dent;
> +static struct dentry *num_free_entries_dent;
> +static struct dentry *min_free_entries_dent;

should all be __read_mostly.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 04/16] dma-debug: add allocator code
  2009-01-09 16:19 ` [PATCH 04/16] dma-debug: add allocator code Joerg Roedel
@ 2009-01-10 23:43   ` Ingo Molnar
  0 siblings, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:43 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +		printk(KERN_ERR "DMA-API: debugging out of memory "
> +				"- disabling\n");

btw., i'd suggest to not break kernel messages mid-string, but do 
something like this instead:

> +		printk(KERN_ERR
		 "DMA-API: debugging out of memory - disabling\n");

Also, i'd use WARN() - it might be useful to see what callsite depleted 
the pool.

> +	entry = list_entry(free_entries.next, struct dma_debug_entry, list);
> +	list_del(&entry->list);
> +	memset(entry, 0, sizeof(*entry));
> +
> +	num_free_entries -= 1;
> +	if (num_free_entries < min_free_entries)
> +		min_free_entries = num_free_entries;

unlikely() i guess.

Regarding the entry pool locking:

> +static void dma_entry_free(struct dma_debug_entry *entry)
> +{
> +	unsigned long flags;
> +
> +	/*
> +	 * add to beginning of the list - this way the entries are
> +	 * more likely cache hot when they are reallocated.
> +	 */
> +	spin_lock_irqsave(&free_entries_lock, flags);
> +	list_add(&entry->list, &free_entries);
> +	num_free_entries += 1;
> +	spin_unlock_irqrestore(&free_entries_lock, flags);

it might make sense to cache entries in the buckets - hence reuse the 
bucket spinlock. This means a somewhat higher effective pool size, but it 
also avoids a global lock.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 14/16] dma-debug: add checks for sync_single_sg_*
  2009-01-09 16:19 ` [PATCH 14/16] dma-debug: add checks for sync_single_sg_* Joerg Roedel
@ 2009-01-10 23:46   ` Ingo Molnar
  2009-01-11  8:00     ` Joerg Roedel
  0 siblings, 1 reply; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:46 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> +void debug_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
> +			   int nelems, int direction)
> +{
> +	struct scatterlist *s;
> +	int i;
> +
> +	if (global_disable)
> +		return;

"if (unlikely(global_disable))" i suspect?

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/16] dma-debug: x86 architecture bindings
  2009-01-09 16:19 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
  2009-01-10 23:04   ` Ingo Molnar
@ 2009-01-10 23:48   ` Ingo Molnar
  2009-01-11  6:25   ` FUJITA Tomonori
  2 siblings, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:48 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> @@ -175,6 +189,8 @@ dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
>  	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
>  
>  	BUG_ON(!valid_dma_direction(direction));
> +        debug_sync_single_range_for_device(hwdev, dma_handle, offset,

whitespace damage here.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (16 preceding siblings ...)
  2009-01-09 21:24 ` [PATCH 0/16] DMA-API debugging facility v2 Michael Chan
@ 2009-01-10 23:54 ` Ingo Molnar
  2009-01-11  8:11   ` Joerg Roedel
  2009-02-05 22:52 ` David Woodhouse
  18 siblings, 1 reply; 72+ messages in thread
From: Ingo Molnar @ 2009-01-10 23:54 UTC (permalink / raw)
  To: Joerg Roedel, Thomas Gleixner
  Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> Hi,
> 
> this is version 2 of the patchset which introduces code to debug drivers 
> usage of the DMA-API. Many thanks to all the reviewers and the useful 
> comments on the fist version of this patchset. Tests with hardware 
> IOMMUs have shown several bugs in drivers regarding the usage of that 
> API.  Problems were found especially in network card drivers.
> 
> These bugs often don't show up or have any negative impact if there is 
> no hardware IOMMU in use in the system. But with an hardware IOMMU these 
> bugs turn the hardware unusable or, in the worst case, cause data 
> corruption on devices which are managed by other (good) drivers.
> 
> With the code these patches introduce driver developers can find several 
> bugs of misusing the DMA-API in their drivers. But be aware, it can not 
> find all possible bugs. If it finds a problem it prints out messages 
> like
> 
> ------------[ cut here ]------------
> WARNING: at /data2/repos/linux.trees.git/lib/dma-debug.c:231 check_unmap+0xab/0x3d9()
> Hardware name: Toonie
> bnx2 0000:01:00.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x00000000011]
> Modules linked in:
> Pid: 0, comm: swapper Not tainted 2.6.28 #174
> Call Trace:
>  <IRQ>  [<ffffffff8105af3a>] warn_slowpath+0xd3/0xf2
>  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
>  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
>  [<ffffffff812efd16>] ? usb_hcd_link_urb_to_ep+0x94/0xa0
>  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
>  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
>  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
>  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
>  [<ffffffff814b25a5>] ? _spin_lock_irqsave+0x69/0x75
>  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
>  [<ffffffff811e2ff2>] check_unmap+0xab/0x3d9
>  [<ffffffff8107c9ed>] ? trace_hardirqs_on_caller+0x108/0x14a
>  [<ffffffff8107ca3c>] ? trace_hardirqs_on+0xd/0xf
>  [<ffffffff811e3433>] debug_unmap_single+0x3e/0x40
>  [<ffffffff8128d2d8>] dma_unmap_single+0x3d/0x60
>  [<ffffffff8128d335>] pci_unmap_page+0x1c/0x1e
>  [<ffffffff81290759>] bnx2_poll_work+0x626/0x8cb
>  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
>  [<ffffffff81070100>] ? run_posix_cpu_timers+0x49c/0x603
>  [<ffffffff81070000>] ? run_posix_cpu_timers+0x39c/0x603
>  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
>  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
>  [<ffffffff81292804>] bnx2_poll_msix+0x33/0x81
>  [<ffffffff813b6478>] net_rx_action+0x8a/0x139
>  [<ffffffff8105ff39>] __do_softirq+0x8b/0x147
>  [<ffffffff8102933c>] call_softirq+0x1c/0x34
>  [<ffffffff8102a611>] do_softirq+0x39/0x90
>  [<ffffffff8105fde8>] irq_exit+0x4e/0x98
>  [<ffffffff8102a5c2>] do_IRQ+0x11f/0x135
>  [<ffffffff81028b93>] ret_from_intr+0x0/0xf
>  <EOI> <4>---[ end trace 4339d58302097423 ]---
> 
> This way driver developers get an idea where the problem is in their
> code.
> 
> I hope I addressed most of the review comments and objections from the
> first version. Please give this version also a good review and send me
> your comments.

Looks pretty good in general - modulo the few observations i just made in 
reply to the patches. (Note, the comments apply to all the patches - 
there's similar small issues in other places as well.)

Did you have a chance to look at debugobjects and see whether it could be 
reused as the dma-debug-entry object management code?

One request: could you please git-base it on the changes in tip/core/iommu 
(i only have looked at the patches in email - i presume the current ones 
are based on -git)?

That way we'll have it on top of Fujita's very nice DMA-mapping 
consolidation code.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent
  2009-01-09 16:19 ` [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent Joerg Roedel
@ 2009-01-11  6:25   ` FUJITA Tomonori
  2009-01-11  6:30     ` FUJITA Tomonori
  0 siblings, 1 reply; 72+ messages in thread
From: FUJITA Tomonori @ 2009-01-11  6:25 UTC (permalink / raw)
  To: joerg.roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, 9 Jan 2009 17:19:25 +0100
Joerg Roedel <joerg.roedel@amd.com> wrote:

> Impact: add debug callbacks for dma_[alloc|free]_coherent
> 
> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
>  include/linux/dma-debug.h |   16 ++++++++++++++++
>  lib/dma-debug.c           |   45 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 61 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> index b2131f4..a28a701 100644
> --- a/include/linux/dma-debug.h
> +++ b/include/linux/dma-debug.h
> @@ -40,6 +40,12 @@ extern void debug_map_sg(struct device *dev, struct scatterlist *sg,
>  extern void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
>  			   int nelems, int dir);
>  
> +extern void debug_alloc_coherent(struct device *dev, size_t size,
> +				 dma_addr_t dma_addr, void *virt);
> +
> +extern void debug_free_coherent(struct device *dev, size_t size,
> +				void *virt, dma_addr_t addr);
> +
>  #else /* CONFIG_DMA_API_DEBUG */
>  
>  static inline void dma_debug_init(u32 num_entries)
> @@ -68,6 +74,16 @@ static inline void debug_unmap_sg(struct device *dev,
>  {
>  }
>  
> +static inline void debug_alloc_coherent(struct device *dev, size_t size,
> +					dma_addr_t dma_addr, void *virt)
> +{
> +}
> +
> +static inline void debug_free_coherent(struct device *dev, size_t size,
> +				       void *virt, dma_addr_t addr)
> +{
> +}
> +
>  #endif /* CONFIG_DMA_API_DEBUG */
>  
>  #endif /* __DMA_DEBUG_H */
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index e6d45f9..a4a5b0f 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -604,3 +604,48 @@ void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
>  }
>  EXPORT_SYMBOL(debug_unmap_sg);
>  
> +void debug_alloc_coherent(struct device *dev, size_t size,
> +			  dma_addr_t dma_addr, void *virt)
> +{
> +	struct dma_debug_entry *entry;
> +
> +	if (global_disable)
> +		return;
> +
> +	if (dma_addr == bad_dma_address)
> +		return;

Only X86 has 'bad_dma_address' (IA64 also has with some configurations
though). You need to use dma_mapping_error, as I pointed out in the
previous submission.

I recommend you to try this on one non-x86 box (at least). Even if you
don't have non x86, you can use cross compiler.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-09 22:37     ` Joerg Roedel
@ 2009-01-11  6:25       ` FUJITA Tomonori
  0 siblings, 0 replies; 72+ messages in thread
From: FUJITA Tomonori @ 2009-01-11  6:25 UTC (permalink / raw)
  To: joro; +Cc: mchan, iommu, mingo, linux-kernel, netdev

On Fri, 9 Jan 2009 23:37:47 +0100
Joerg Roedel <joro@8bytes.org> wrote:

> On Fri, Jan 09, 2009 at 11:33:27PM +0100, Joerg Roedel wrote:
> > > This was triggered during pci_unmap_page() -> dma_unmap_single() where
> > > check_unmap() did not find the entry.
> > > 
> > > The original mapping was done in bnx2 using pci_map_page().  I did not
> > > see how the debug entry was added to the hash during the call to
> > > pci_map_page() -> dma_map_page().  Did I miss something?
> > 
> > dma_map_page() results in dma_map_single() -> debug_map_single() call on
> > x86. This way the entry would be added. Maybe the error from a double
> > free?
> 
> Ah, it only calls ops->map_single. Thanks for pointing that out. I will
> add a call to debug_map_single to dma_map_page too. So the error above
> may be a false positive.

Then you will find that the interface of debug_map_single is wrong.
You can't use cpu address here. I explained this to you before:

http://marc.info/?t=123116736500005&r=1&w=2

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 02/16] dma-debug: add header file and core data structures
  2009-01-09 16:19 ` [PATCH 02/16] dma-debug: add header file and core data structures Joerg Roedel
@ 2009-01-11  6:25   ` FUJITA Tomonori
  0 siblings, 0 replies; 72+ messages in thread
From: FUJITA Tomonori @ 2009-01-11  6:25 UTC (permalink / raw)
  To: joerg.roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, 9 Jan 2009 17:19:16 +0100
Joerg Roedel <joerg.roedel@amd.com> wrote:

> Impact: add groundwork for DMA-API debugging
> 
> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
>  include/linux/dma-debug.h |   25 +++++++++++++++++++++++++
>  lib/Makefile              |    2 ++
>  lib/dma-debug.c           |   39 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 66 insertions(+), 0 deletions(-)
>  create mode 100644 include/linux/dma-debug.h
>  create mode 100644 lib/dma-debug.c
> 
> diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> new file mode 100644
> index 0000000..ce4ace7
> --- /dev/null
> +++ b/include/linux/dma-debug.h
> @@ -0,0 +1,25 @@
> +/*
> + * Copyright (C) 2008 Advanced Micro Devices, Inc.
> + *
> + * Author: Joerg Roedel <joerg.roedel@amd.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
> + */
> +
> +#ifndef __DMA_DEBUG_H
> +#define __DMA_DEBUG_H
> +
> +struct device;
> +
> +#endif /* __DMA_DEBUG_H */
> diff --git a/lib/Makefile b/lib/Makefile
> index 32b0e64..50b48cf 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -84,6 +84,8 @@ obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
>  
>  obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
>  
> +obj-$(CONFIG_DMA_API_DEBUG) += dma-debug.o
> +
>  hostprogs-y	:= gen_crc32table
>  clean-files	:= crc32table.h
>  
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> new file mode 100644
> index 0000000..d04f8b6
> --- /dev/null
> +++ b/lib/dma-debug.c
> @@ -0,0 +1,39 @@
> +/*
> + * Copyright (C) 2008 Advanced Micro Devices, Inc.
> + *
> + * Author: Joerg Roedel <joerg.roedel@amd.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
> + */
> +
> +#include <linux/dma-debug.h>
> +#include <linux/types.h>
> +#include <linux/list.h>
> +
> +enum {
> +	dma_debug_single,
> +	dma_debug_sg,
> +	dma_debug_coherent,
> +};
> +
> +struct dma_debug_entry {
> +	struct list_head list;
> +	struct device    *dev;
> +	int              type;
> +	void             *cpu_addr;

I don't think that cpu addresses are appropriate here.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/16] dma-debug: x86 architecture bindings
  2009-01-09 16:19 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
  2009-01-10 23:04   ` Ingo Molnar
  2009-01-10 23:48   ` Ingo Molnar
@ 2009-01-11  6:25   ` FUJITA Tomonori
  2009-01-11  8:08     ` Joerg Roedel
  2 siblings, 1 reply; 72+ messages in thread
From: FUJITA Tomonori @ 2009-01-11  6:25 UTC (permalink / raw)
  To: joerg.roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, 9 Jan 2009 17:19:29 +0100
Joerg Roedel <joerg.roedel@amd.com> wrote:

> Impact: make use of DMA-API debugging code in x86
> 
> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
>  arch/x86/Kconfig                   |    1 +
>  arch/x86/include/asm/dma-mapping.h |   30 ++++++++++++++++++++++++++----
>  arch/x86/kernel/pci-dma.c          |    5 +++++
>  3 files changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 862adb9..68a806c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -39,6 +39,7 @@ config X86
>  	select HAVE_GENERIC_DMA_COHERENT if X86_32
>  	select HAVE_EFFICIENT_UNALIGNED_ACCESS
>  	select USER_STACKTRACE_SUPPORT
> +	select HAVE_DMA_API_DEBUG
>  
>  config ARCH_DEFCONFIG
>  	string
> diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
> index 4035357..939d5b3 100644
> --- a/arch/x86/include/asm/dma-mapping.h
> +++ b/arch/x86/include/asm/dma-mapping.h
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/scatterlist.h>
> +#include <linux/dma-debug.h>
>  #include <asm/io.h>
>  #include <asm/swiotlb.h>
>  #include <asm-generic/dma-coherent.h>
> @@ -93,9 +94,12 @@ dma_map_single(struct device *hwdev, void *ptr, size_t size,
>  	       int direction)
>  {
>  	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
> +	dma_addr_t addr;
>  
>  	BUG_ON(!valid_dma_direction(direction));
> -	return ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
> +	addr = ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
> +	debug_map_single(hwdev, ptr, size, direction, addr);
> +	return addr;

What happens if ops->map_single fails?

Seems that debug_map_single doesn't check the dma mapping fails. So it
allocates a new entries and nobody frees it?

Another problem is that what happens if ops->map_single succeeds but
debug_map_single fails? Seems that it gives a false warning.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent
  2009-01-11  6:25   ` FUJITA Tomonori
@ 2009-01-11  6:30     ` FUJITA Tomonori
  2009-01-11  7:59       ` Joerg Roedel
  0 siblings, 1 reply; 72+ messages in thread
From: FUJITA Tomonori @ 2009-01-11  6:30 UTC (permalink / raw)
  To: fujita.tomonori; +Cc: joerg.roedel, linux-kernel, mingo, dwmw2, netdev, iommu

On Sun, 11 Jan 2009 15:25:42 +0900
FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:

> On Fri, 9 Jan 2009 17:19:25 +0100
> Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > Impact: add debug callbacks for dma_[alloc|free]_coherent
> > 
> > Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> > ---
> >  include/linux/dma-debug.h |   16 ++++++++++++++++
> >  lib/dma-debug.c           |   45 +++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 61 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> > index b2131f4..a28a701 100644
> > --- a/include/linux/dma-debug.h
> > +++ b/include/linux/dma-debug.h
> > @@ -40,6 +40,12 @@ extern void debug_map_sg(struct device *dev, struct scatterlist *sg,
> >  extern void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
> >  			   int nelems, int dir);
> >  
> > +extern void debug_alloc_coherent(struct device *dev, size_t size,
> > +				 dma_addr_t dma_addr, void *virt);
> > +
> > +extern void debug_free_coherent(struct device *dev, size_t size,
> > +				void *virt, dma_addr_t addr);
> > +
> >  #else /* CONFIG_DMA_API_DEBUG */
> >  
> >  static inline void dma_debug_init(u32 num_entries)
> > @@ -68,6 +74,16 @@ static inline void debug_unmap_sg(struct device *dev,
> >  {
> >  }
> >  
> > +static inline void debug_alloc_coherent(struct device *dev, size_t size,
> > +					dma_addr_t dma_addr, void *virt)
> > +{
> > +}
> > +
> > +static inline void debug_free_coherent(struct device *dev, size_t size,
> > +				       void *virt, dma_addr_t addr)
> > +{
> > +}
> > +
> >  #endif /* CONFIG_DMA_API_DEBUG */
> >  
> >  #endif /* __DMA_DEBUG_H */
> > diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> > index e6d45f9..a4a5b0f 100644
> > --- a/lib/dma-debug.c
> > +++ b/lib/dma-debug.c
> > @@ -604,3 +604,48 @@ void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
> >  }
> >  EXPORT_SYMBOL(debug_unmap_sg);
> >  
> > +void debug_alloc_coherent(struct device *dev, size_t size,
> > +			  dma_addr_t dma_addr, void *virt)
> > +{
> > +	struct dma_debug_entry *entry;
> > +
> > +	if (global_disable)
> > +		return;
> > +
> > +	if (dma_addr == bad_dma_address)
> > +		return;
> 
> Only X86 has 'bad_dma_address' (IA64 also has with some configurations
> though). You need to use dma_mapping_error, as I pointed out in the
> previous submission.

Oops, this is for dma_alloc_coherent so you need to check 'virt'
instead of dma_mapping_error().

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/16] dma-debug: add debugfs interface
  2009-01-10 23:08   ` Ingo Molnar
@ 2009-01-11  7:52     ` Joerg Roedel
  2009-01-14 15:22     ` Joerg Roedel
  1 sibling, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  7:52 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Sun, Jan 11, 2009 at 12:08:26AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +/* Global error count */
> > +static u32 error_count;
> > +
> > +/* Global error show enable*/
> > +static u32 show_all_errors __read_mostly;
> > +/* Number of errors to show */
> > +static u32 show_num_errors = 1;
> > +
> >  static u32 num_free_entries;
> >  static u32 min_free_entries;
> 
> Small detail: please use native C types for non-hardware variables - 
> 'unsigned int', 'unsigned long', etc.
> 
> u32/u64 is typically used for variables where there is a real significance 
> to the precise width of the variable: there's either a hardware or a 
> user-space ABI involved.

Hmm, these variables are exported to debugfs. Thats the reason I made
them u32.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-10 23:12   ` Ingo Molnar
@ 2009-01-11  7:54     ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  7:54 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Sun, Jan 11, 2009 at 12:12:22AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +	/*
> > +	 *          * This may be no bug in reality - but most implementations of the
> > +	 *                   * DMA API don't handle this properly, so check for it here
> > +	 *                            */
> 
> You must be using Vim and copy & paste messed up? :)

Ups, true :) Thanks.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-10 23:11   ` Ingo Molnar
@ 2009-01-11  7:57     ` Joerg Roedel
  2009-01-11  8:34       ` Joerg Roedel
  2009-01-14 11:44     ` Joerg Roedel
  1 sibling, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  7:57 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Sun, Jan 11, 2009 at 12:11:27AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +#define err_printk(dev, 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);		\
> > +		}						\
> > +		if (!show_all_errors && show_num_errors > 0)	\
> > +			show_num_errors -= 1;			\
> 
> Note that the arithmetics here is SMP-unsafe: we only hold the hash bucket 
> so if two errors hit at once on two CPUs then the error tracking variables 
> can be accessed at once.
> 
> I'd suggest a simple global lock for this error case (taken inside the 
> hash bucket lock), to be on the safe side.
> 
> Also, please dont use a macro for this - printk details can be passed in 
> to helper inlines/functions too.

Yeah, this is not SMP-safe, I know. But debugfs does not support
atomic_t so I made the variables u32. But at least a race condition has
not a too bad impact. What may habben is that error_count misses a error
or the show_num_errors become negative.
But if we really want to avoid this I think its better to add atomic_t
support to debugfs. What do you think?

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent
  2009-01-11  6:30     ` FUJITA Tomonori
@ 2009-01-11  7:59       ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  7:59 UTC (permalink / raw)
  To: FUJITA Tomonori; +Cc: linux-kernel, iommu, mingo, netdev

On Sun, Jan 11, 2009 at 03:30:14PM +0900, FUJITA Tomonori wrote:
> On Sun, 11 Jan 2009 15:25:42 +0900
> FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> 
> > On Fri, 9 Jan 2009 17:19:25 +0100
> > Joerg Roedel <joerg.roedel@amd.com> wrote:
> > 
> > > Impact: add debug callbacks for dma_[alloc|free]_coherent
> > > 
> > > Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> > > ---
> > >  include/linux/dma-debug.h |   16 ++++++++++++++++
> > >  lib/dma-debug.c           |   45 +++++++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 61 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> > > index b2131f4..a28a701 100644
> > > --- a/include/linux/dma-debug.h
> > > +++ b/include/linux/dma-debug.h
> > > @@ -40,6 +40,12 @@ extern void debug_map_sg(struct device *dev, struct scatterlist *sg,
> > >  extern void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
> > >  			   int nelems, int dir);
> > >  
> > > +extern void debug_alloc_coherent(struct device *dev, size_t size,
> > > +				 dma_addr_t dma_addr, void *virt);
> > > +
> > > +extern void debug_free_coherent(struct device *dev, size_t size,
> > > +				void *virt, dma_addr_t addr);
> > > +
> > >  #else /* CONFIG_DMA_API_DEBUG */
> > >  
> > >  static inline void dma_debug_init(u32 num_entries)
> > > @@ -68,6 +74,16 @@ static inline void debug_unmap_sg(struct device *dev,
> > >  {
> > >  }
> > >  
> > > +static inline void debug_alloc_coherent(struct device *dev, size_t size,
> > > +					dma_addr_t dma_addr, void *virt)
> > > +{
> > > +}
> > > +
> > > +static inline void debug_free_coherent(struct device *dev, size_t size,
> > > +				       void *virt, dma_addr_t addr)
> > > +{
> > > +}
> > > +
> > >  #endif /* CONFIG_DMA_API_DEBUG */
> > >  
> > >  #endif /* __DMA_DEBUG_H */
> > > diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> > > index e6d45f9..a4a5b0f 100644
> > > --- a/lib/dma-debug.c
> > > +++ b/lib/dma-debug.c
> > > @@ -604,3 +604,48 @@ void debug_unmap_sg(struct device *dev, struct scatterlist *sglist,
> > >  }
> > >  EXPORT_SYMBOL(debug_unmap_sg);
> > >  
> > > +void debug_alloc_coherent(struct device *dev, size_t size,
> > > +			  dma_addr_t dma_addr, void *virt)
> > > +{
> > > +	struct dma_debug_entry *entry;
> > > +
> > > +	if (global_disable)
> > > +		return;
> > > +
> > > +	if (dma_addr == bad_dma_address)
> > > +		return;
> > 
> > Only X86 has 'bad_dma_address' (IA64 also has with some configurations
> > though). You need to use dma_mapping_error, as I pointed out in the
> > previous submission.
> 
> Oops, this is for dma_alloc_coherent so you need to check 'virt'
> instead of dma_mapping_error().

Ah, true. Thanks. I will fix that.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 14/16] dma-debug: add checks for sync_single_sg_*
  2009-01-10 23:46   ` Ingo Molnar
@ 2009-01-11  8:00     ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  8:00 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Joerg Roedel, netdev, linux-kernel, iommu, mingo

On Sun, Jan 11, 2009 at 12:46:41AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +void debug_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
> > +			   int nelems, int direction)
> > +{
> > +	struct scatterlist *s;
> > +	int i;
> > +
> > +	if (global_disable)
> > +		return;
> 
> "if (unlikely(global_disable))" i suspect?

True. I  will add unlikely() to all global_disable checks.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/16] dma-debug: x86 architecture bindings
  2009-01-11  6:25   ` FUJITA Tomonori
@ 2009-01-11  8:08     ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  8:08 UTC (permalink / raw)
  To: FUJITA Tomonori; +Cc: joerg.roedel, netdev, linux-kernel, iommu, mingo

On Sun, Jan 11, 2009 at 03:25:47PM +0900, FUJITA Tomonori wrote:
> On Fri, 9 Jan 2009 17:19:29 +0100
> Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > Impact: make use of DMA-API debugging code in x86
> > 
> > Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> > ---
> >  arch/x86/Kconfig                   |    1 +
> >  arch/x86/include/asm/dma-mapping.h |   30 ++++++++++++++++++++++++++----
> >  arch/x86/kernel/pci-dma.c          |    5 +++++
> >  3 files changed, 32 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> > index 862adb9..68a806c 100644
> > --- a/arch/x86/Kconfig
> > +++ b/arch/x86/Kconfig
> > @@ -39,6 +39,7 @@ config X86
> >  	select HAVE_GENERIC_DMA_COHERENT if X86_32
> >  	select HAVE_EFFICIENT_UNALIGNED_ACCESS
> >  	select USER_STACKTRACE_SUPPORT
> > +	select HAVE_DMA_API_DEBUG
> >  
> >  config ARCH_DEFCONFIG
> >  	string
> > diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
> > index 4035357..939d5b3 100644
> > --- a/arch/x86/include/asm/dma-mapping.h
> > +++ b/arch/x86/include/asm/dma-mapping.h
> > @@ -7,6 +7,7 @@
> >   */
> >  
> >  #include <linux/scatterlist.h>
> > +#include <linux/dma-debug.h>
> >  #include <asm/io.h>
> >  #include <asm/swiotlb.h>
> >  #include <asm-generic/dma-coherent.h>
> > @@ -93,9 +94,12 @@ dma_map_single(struct device *hwdev, void *ptr, size_t size,
> >  	       int direction)
> >  {
> >  	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
> > +	dma_addr_t addr;
> >  
> >  	BUG_ON(!valid_dma_direction(direction));
> > -	return ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
> > +	addr = ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
> > +	debug_map_single(hwdev, ptr, size, direction, addr);
> > +	return addr;
> 
> What happens if ops->map_single fails?
> 
> Seems that debug_map_single doesn't check the dma mapping fails. So it
> allocates a new entries and nobody frees it?

Ah true. The debug_map_single function has to check for
dma_mapping_error. Same is true for debug_map_sg.

> Another problem is that what happens if ops->map_single succeeds but
> debug_map_single fails? Seems that it gives a false warning.

No, this can not happen. If the code fails it disables itself so no more
warnings will be printed.

Joerg


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-10 23:54 ` Ingo Molnar
@ 2009-01-11  8:11   ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  8:11 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Joerg Roedel, Thomas Gleixner, netdev, linux-kernel, iommu, mingo

On Sun, Jan 11, 2009 at 12:54:35AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > Hi,
> > 
> > this is version 2 of the patchset which introduces code to debug drivers 
> > usage of the DMA-API. Many thanks to all the reviewers and the useful 
> > comments on the fist version of this patchset. Tests with hardware 
> > IOMMUs have shown several bugs in drivers regarding the usage of that 
> > API.  Problems were found especially in network card drivers.
> > 
> > These bugs often don't show up or have any negative impact if there is 
> > no hardware IOMMU in use in the system. But with an hardware IOMMU these 
> > bugs turn the hardware unusable or, in the worst case, cause data 
> > corruption on devices which are managed by other (good) drivers.
> > 
> > With the code these patches introduce driver developers can find several 
> > bugs of misusing the DMA-API in their drivers. But be aware, it can not 
> > find all possible bugs. If it finds a problem it prints out messages 
> > like
> > 
> > ------------[ cut here ]------------
> > WARNING: at /data2/repos/linux.trees.git/lib/dma-debug.c:231 check_unmap+0xab/0x3d9()
> > Hardware name: Toonie
> > bnx2 0000:01:00.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x00000000011]
> > Modules linked in:
> > Pid: 0, comm: swapper Not tainted 2.6.28 #174
> > Call Trace:
> >  <IRQ>  [<ffffffff8105af3a>] warn_slowpath+0xd3/0xf2
> >  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
> >  [<ffffffff8107c36f>] ? find_usage_backwards+0xe2/0x116
> >  [<ffffffff812efd16>] ? usb_hcd_link_urb_to_ep+0x94/0xa0
> >  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
> >  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
> >  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
> >  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
> >  [<ffffffff814b25a5>] ? _spin_lock_irqsave+0x69/0x75
> >  [<ffffffff811e2b4b>] ? get_hash_bucket+0x28/0x33
> >  [<ffffffff811e2ff2>] check_unmap+0xab/0x3d9
> >  [<ffffffff8107c9ed>] ? trace_hardirqs_on_caller+0x108/0x14a
> >  [<ffffffff8107ca3c>] ? trace_hardirqs_on+0xd/0xf
> >  [<ffffffff811e3433>] debug_unmap_single+0x3e/0x40
> >  [<ffffffff8128d2d8>] dma_unmap_single+0x3d/0x60
> >  [<ffffffff8128d335>] pci_unmap_page+0x1c/0x1e
> >  [<ffffffff81290759>] bnx2_poll_work+0x626/0x8cb
> >  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
> >  [<ffffffff81070100>] ? run_posix_cpu_timers+0x49c/0x603
> >  [<ffffffff81070000>] ? run_posix_cpu_timers+0x39c/0x603
> >  [<ffffffff8107c52b>] ? mark_lock+0x1c/0x364
> >  [<ffffffff8107d8f7>] ? __lock_acquire+0xaec/0xb55
> >  [<ffffffff81292804>] bnx2_poll_msix+0x33/0x81
> >  [<ffffffff813b6478>] net_rx_action+0x8a/0x139
> >  [<ffffffff8105ff39>] __do_softirq+0x8b/0x147
> >  [<ffffffff8102933c>] call_softirq+0x1c/0x34
> >  [<ffffffff8102a611>] do_softirq+0x39/0x90
> >  [<ffffffff8105fde8>] irq_exit+0x4e/0x98
> >  [<ffffffff8102a5c2>] do_IRQ+0x11f/0x135
> >  [<ffffffff81028b93>] ret_from_intr+0x0/0xf
> >  <EOI> <4>---[ end trace 4339d58302097423 ]---
> > 
> > This way driver developers get an idea where the problem is in their
> > code.
> > 
> > I hope I addressed most of the review comments and objections from the
> > first version. Please give this version also a good review and send me
> > your comments.
> 
> Looks pretty good in general - modulo the few observations i just made in 
> reply to the patches. (Note, the comments apply to all the patches - 
> there's similar small issues in other places as well.)
> 
> Did you have a chance to look at debugobjects and see whether it could be 
> reused as the dma-debug-entry object management code?

Yes, I looked at it. But the code looks like it is used to debug object
state and not to provide objects for debugging code.

> One request: could you please git-base it on the changes in tip/core/iommu 
> (i only have looked at the patches in email - i presume the current ones 
> are based on -git)?

Yes, I will rebase it for the next post.

Joerg


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-11  7:57     ` Joerg Roedel
@ 2009-01-11  8:34       ` Joerg Roedel
  0 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-11  8:34 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: iommu, mingo, linux-kernel, netdev

On Sun, Jan 11, 2009 at 08:57:52AM +0100, Joerg Roedel wrote:
> On Sun, Jan 11, 2009 at 12:11:27AM +0100, Ingo Molnar wrote:
> > 
> > * Joerg Roedel <joerg.roedel@amd.com> wrote:
> > 
> > > +#define err_printk(dev, 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);		\
> > > +		}						\
> > > +		if (!show_all_errors && show_num_errors > 0)	\
> > > +			show_num_errors -= 1;			\
> > 
> > Note that the arithmetics here is SMP-unsafe: we only hold the hash bucket 
> > so if two errors hit at once on two CPUs then the error tracking variables 
> > can be accessed at once.
> > 
> > I'd suggest a simple global lock for this error case (taken inside the 
> > hash bucket lock), to be on the safe side.
> > 
> > Also, please dont use a macro for this - printk details can be passed in 
> > to helper inlines/functions too.
> 
> Yeah, this is not SMP-safe, I know. But debugfs does not support
> atomic_t so I made the variables u32. But at least a race condition has
> not a too bad impact. What may habben is that error_count misses a error
> or the show_num_errors become negative.
> But if we really want to avoid this I think its better to add atomic_t
> support to debugfs. What do you think?

Even a global lock will not really help here because show_num_errors and
show_all_errors can be set using debugfs. Either we live with the small
race (with limited impact) or I add atomic_t support to debugfs.

Joerg


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-09 16:19 ` [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Joerg Roedel
  2009-01-09 17:55   ` Evgeniy Polyakov
@ 2009-01-13  8:51   ` Andrew Morton
  2009-01-13  8:59     ` David Woodhouse
  2009-01-14 11:43     ` Ingo Molnar
  1 sibling, 2 replies; 72+ messages in thread
From: Andrew Morton @ 2009-01-13  8:51 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Fri, 9 Jan 2009 17:19:17 +0100 Joerg Roedel <joerg.roedel@amd.com> wrote:

> +struct hash_bucket {
> +	struct list_head list;
> +	spinlock_t lock;
> +} ____cacheline_aligned;

__cacheline_aligned_in_smp.

This all looks like an exotically large amount of code for a debug thingy?

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-13  8:51   ` Andrew Morton
@ 2009-01-13  8:59     ` David Woodhouse
  2009-01-14 11:43     ` Ingo Molnar
  1 sibling, 0 replies; 72+ messages in thread
From: David Woodhouse @ 2009-01-13  8:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Joerg Roedel, linux-kernel, mingo, fujita.tomonori, netdev, iommu

On Tue, 2009-01-13 at 00:51 -0800, Andrew Morton wrote:
> This all looks like an exotically large amount of code for a debug
> thingy?

Perhaps so, but it's a useful debug thingy which lets us debug _very_
common problems in drivers, which many people are unlikely to notice
without this 'assistance'. 

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


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-13  8:51   ` Andrew Morton
  2009-01-13  8:59     ` David Woodhouse
@ 2009-01-14 11:43     ` Ingo Molnar
  2009-01-14 17:39       ` Andrew Morton
  1 sibling, 1 reply; 72+ messages in thread
From: Ingo Molnar @ 2009-01-14 11:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Joerg Roedel, linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Andrew Morton <akpm@linux-foundation.org> wrote:

> On Fri, 9 Jan 2009 17:19:17 +0100 Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +struct hash_bucket {
> > +	struct list_head list;
> > +	spinlock_t lock;
> > +} ____cacheline_aligned;
> 
> __cacheline_aligned_in_smp.
> 
> This all looks like an exotically large amount of code for a debug 
> thingy?

this code checks the DMA usage of ~1 million lines of kernel code - all 
the DMA using drivers. I think Joerg's feature is hugely relevant as DMA 
scribbles are one of the hardest to debug kernel bugs: they can end up in 
permanent data corruption or other hard to find bugs. In fact i think his 
patchset is rather simple and even having 10 times as much debug code 
would pay for its existence in the long run.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-10 23:11   ` Ingo Molnar
  2009-01-11  7:57     ` Joerg Roedel
@ 2009-01-14 11:44     ` Joerg Roedel
  2009-01-14 11:48       ` Ingo Molnar
  1 sibling, 1 reply; 72+ messages in thread
From: Joerg Roedel @ 2009-01-14 11:44 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Sun, Jan 11, 2009 at 12:11:27AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +#define err_printk(dev, 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);		\
> > +		}						\
> > +		if (!show_all_errors && show_num_errors > 0)	\
> > +			show_num_errors -= 1;			\
> 
> Note that the arithmetics here is SMP-unsafe: we only hold the hash bucket 
> so if two errors hit at once on two CPUs then the error tracking variables 
> can be accessed at once.
> 
> I'd suggest a simple global lock for this error case (taken inside the 
> hash bucket lock), to be on the safe side.

As I wrote in a previous email, a race here is no big deal. I add a
comment to document it. Or do we want another global lock here?

> Also, please dont use a macro for this - printk details can be passed in 
> to helper inlines/functions too.

Hmm, how does this look like? There is not WARN variant which can use
va_args as a parameter. And it is important that the error message is
logged in the warning itself. So the driver developer can see it when a
user reports the warning.

Joerg

-- 
           | Advanced Micro Devices GmbH
 Operating | Karl-Hammerschmidt-Str. 34, 85609 Dornach bei München
 System    | 
 Research  | Geschäftsführer: Jochen Polster, Thomas M. McCoy, Giuliano Meroni
 Center    | Sitz: Dornach, Gemeinde Aschheim, Landkreis München
           | Registergericht München, HRB Nr. 43632


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/16] dma-debug: add core checking functions
  2009-01-14 11:44     ` Joerg Roedel
@ 2009-01-14 11:48       ` Ingo Molnar
  0 siblings, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-14 11:48 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Joerg Roedel <joerg.roedel@amd.com> wrote:

> On Sun, Jan 11, 2009 at 12:11:27AM +0100, Ingo Molnar wrote:
> > 
> > * Joerg Roedel <joerg.roedel@amd.com> wrote:
> > 
> > > +#define err_printk(dev, 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);		\
> > > +		}						\
> > > +		if (!show_all_errors && show_num_errors > 0)	\
> > > +			show_num_errors -= 1;			\
> > 
> > Note that the arithmetics here is SMP-unsafe: we only hold the hash bucket 
> > so if two errors hit at once on two CPUs then the error tracking variables 
> > can be accessed at once.
> > 
> > I'd suggest a simple global lock for this error case (taken inside the 
> > hash bucket lock), to be on the safe side.
> 
> As I wrote in a previous email, a race here is no big deal. I add a 
> comment to document it. Or do we want another global lock here?

we commonly use global locks in debug exception cases - to serialize 
console output. But it's certainly no big deal.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/16] dma-debug: add debugfs interface
  2009-01-10 23:08   ` Ingo Molnar
  2009-01-11  7:52     ` Joerg Roedel
@ 2009-01-14 15:22     ` Joerg Roedel
  1 sibling, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-14 15:22 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Sun, Jan 11, 2009 at 12:08:26AM +0100, Ingo Molnar wrote:
> 
> * Joerg Roedel <joerg.roedel@amd.com> wrote:
> 
> > +/* Global error count */
> > +static u32 error_count;
> > +
> > +/* Global error show enable*/
> > +static u32 show_all_errors __read_mostly;
> > +/* Number of errors to show */
> > +static u32 show_num_errors = 1;
> > +
> >  static u32 num_free_entries;
> >  static u32 min_free_entries;
> 
> Small detail: please use native C types for non-hardware variables - 
> 'unsigned int', 'unsigned long', etc.
> 
> u32/u64 is typically used for variables where there is a real significance 
> to the precise width of the variable: there's either a hardware or a 
> user-space ABI involved.

There is some kind of userspace ABI: all these variables are exported
via debugfs. And debugfs relies on these types.

Joerg

-- 
           | Advanced Micro Devices GmbH
 Operating | Karl-Hammerschmidt-Str. 34, 85609 Dornach bei München
 System    | 
 Research  | Geschäftsführer: Jochen Polster, Thomas M. McCoy, Giuliano Meroni
 Center    | Sitz: Dornach, Gemeinde Aschheim, Landkreis München
           | Registergericht München, HRB Nr. 43632


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-14 11:43     ` Ingo Molnar
@ 2009-01-14 17:39       ` Andrew Morton
  2009-01-14 17:43         ` Ingo Molnar
                           ` (3 more replies)
  0 siblings, 4 replies; 72+ messages in thread
From: Andrew Morton @ 2009-01-14 17:39 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Joerg Roedel, linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Wed, 14 Jan 2009 12:43:47 +0100 Ingo Molnar <mingo@elte.hu> wrote:

> 
> * Andrew Morton <akpm@linux-foundation.org> wrote:
> 
> > On Fri, 9 Jan 2009 17:19:17 +0100 Joerg Roedel <joerg.roedel@amd.com> wrote:
> > 
> > > +struct hash_bucket {
> > > +	struct list_head list;
> > > +	spinlock_t lock;
> > > +} ____cacheline_aligned;
> > 
> > __cacheline_aligned_in_smp.
> > 
> > This all looks like an exotically large amount of code for a debug 
> > thingy?
> 
> this code checks the DMA usage of ~1 million lines of kernel code - all 
> the DMA using drivers. I think Joerg's feature is hugely relevant as DMA 
> scribbles are one of the hardest to debug kernel bugs: they can end up in 
> permanent data corruption or other hard to find bugs. In fact i think his 
> patchset is rather simple and even having 10 times as much debug code 
> would pay for its existence in the long run.
> 

Have we previously found bugs by other means which this facility would
have detected?  I don't recall any...


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-14 17:39       ` Andrew Morton
@ 2009-01-14 17:43         ` Ingo Molnar
  2009-01-14 17:48         ` Ingo Molnar
                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 72+ messages in thread
From: Ingo Molnar @ 2009-01-14 17:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Joerg Roedel, linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Andrew Morton <akpm@linux-foundation.org> wrote:

> On Wed, 14 Jan 2009 12:43:47 +0100 Ingo Molnar <mingo@elte.hu> wrote:
> 
> > 
> > * Andrew Morton <akpm@linux-foundation.org> wrote:
> > 
> > > On Fri, 9 Jan 2009 17:19:17 +0100 Joerg Roedel <joerg.roedel@amd.com> wrote:
> > > 
> > > > +struct hash_bucket {
> > > > +	struct list_head list;
> > > > +	spinlock_t lock;
> > > > +} ____cacheline_aligned;
> > > 
> > > __cacheline_aligned_in_smp.
> > > 
> > > This all looks like an exotically large amount of code for a debug 
> > > thingy?
> > 
> > this code checks the DMA usage of ~1 million lines of kernel code - 
> > all the DMA using drivers. I think Joerg's feature is hugely relevant 
> > as DMA scribbles are one of the hardest to debug kernel bugs: they can 
> > end up in permanent data corruption or other hard to find bugs. In 
> > fact i think his patchset is rather simple and even having 10 times as 
> > much debug code would pay for its existence in the long run.
> 
> Have we previously found bugs by other means which this facility would 
> have detected?  I don't recall any...

this facility found a handful of real bugs already - Joerg, do you have 
more specifics about that?

Also, such a facility would be useful during driver development, when such 
bugs occur en masse. Faster driver development under Linux is certainly 
desirable.

This facility basically adds a sandbox to all DMA ops and tracks the 
lifetime and validity of DMA operations. Given how ugly DMA bugs can be in 
practice and how hard to debug they are, i see this as good step forward.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-14 17:39       ` Andrew Morton
  2009-01-14 17:43         ` Ingo Molnar
@ 2009-01-14 17:48         ` Ingo Molnar
  2009-01-15  3:44           ` FUJITA Tomonori
  2009-01-14 17:48         ` David Woodhouse
  2009-01-14 17:51         ` Joerg Roedel
  3 siblings, 1 reply; 72+ messages in thread
From: Ingo Molnar @ 2009-01-14 17:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Joerg Roedel, linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu


* Andrew Morton <akpm@linux-foundation.org> wrote:

> On Wed, 14 Jan 2009 12:43:47 +0100 Ingo Molnar <mingo@elte.hu> wrote:
> 
> > 
> > * Andrew Morton <akpm@linux-foundation.org> wrote:
> > 
> > > On Fri, 9 Jan 2009 17:19:17 +0100 Joerg Roedel <joerg.roedel@amd.com> wrote:
> > > 
> > > > +struct hash_bucket {
> > > > +	struct list_head list;
> > > > +	spinlock_t lock;
> > > > +} ____cacheline_aligned;
> > > 
> > > __cacheline_aligned_in_smp.
> > > 
> > > This all looks like an exotically large amount of code for a debug 
> > > thingy?
> > 
> > this code checks the DMA usage of ~1 million lines of kernel code - all 
> > the DMA using drivers. I think Joerg's feature is hugely relevant as DMA 
> > scribbles are one of the hardest to debug kernel bugs: they can end up in 
> > permanent data corruption or other hard to find bugs. In fact i think his 
> > patchset is rather simple and even having 10 times as much debug code 
> > would pay for its existence in the long run.
> > 
> 
> Have we previously found bugs by other means which this facility would 
> have detected?  I don't recall any...

btw., during the past decade we have had countless very ugly driver DMA 
bugs in the past that took vendors months and specialized equipment to 
track down.

I cannot give you a number breakdown, only an impression: storage drivers 
tended to be the hardest hit (due to the severity of the bugs and due to 
their inherent complexity) - but DMA bugs in networking drivers can be 
hard to track down too.

Plus there's another benefit: if a driver passes this checking and there's 
still DMA related corruption observed, then the hardware / firmware 
becomes a stronger suspect. This helps debugging too.

	Ingo

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-14 17:39       ` Andrew Morton
  2009-01-14 17:43         ` Ingo Molnar
  2009-01-14 17:48         ` Ingo Molnar
@ 2009-01-14 17:48         ` David Woodhouse
  2009-01-14 17:51         ` Joerg Roedel
  3 siblings, 0 replies; 72+ messages in thread
From: David Woodhouse @ 2009-01-14 17:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Joerg Roedel, linux-kernel, mingo, fujita.tomonori,
	netdev, iommu

On Wed, 2009-01-14 at 09:39 -0800, Andrew Morton wrote:
> > this code checks the DMA usage of ~1 million lines of kernel code - all 
> > the DMA using drivers. I think Joerg's feature is hugely relevant as DMA 
> > scribbles are one of the hardest to debug kernel bugs: they can end up in 
> > permanent data corruption or other hard to find bugs. In fact i think his 
> > patchset is rather simple and even having 10 times as much debug code 
> > would pay for its existence in the long run.
> > 
> 
> Have we previously found bugs by other means which this facility would
> have detected?  I don't recall any...

Yes. We've found network driver bugs which only showed up when an IOMMU
has been active -- and were painful to diagnose because they involved
DMA going wrong. It happens when drivers make mistakes with the DMA
mapping APIs.

With this debug facility, we can find such problems on _any_ hardware,
and get a sane report about what's wrong.

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


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-14 17:39       ` Andrew Morton
                           ` (2 preceding siblings ...)
  2009-01-14 17:48         ` David Woodhouse
@ 2009-01-14 17:51         ` Joerg Roedel
  3 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-01-14 17:51 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, linux-kernel, mingo, dwmw2, fujita.tomonori, netdev, iommu

On Wed, Jan 14, 2009 at 09:39:18AM -0800, Andrew Morton wrote:
> 
> Have we previously found bugs by other means which this facility would
> have detected?  I don't recall any...
> 

See for example this bugfix:

http://www.spinics.net/lists/netdev/msg83208.html

The bug was found using the first version of this patchset.

Joerg


-- 
           | Advanced Micro Devices GmbH
 Operating | Karl-Hammerschmidt-Str. 34, 85609 Dornach bei München
 System    | 
 Research  | Geschäftsführer: Jochen Polster, Thomas M. McCoy, Giuliano Meroni
 Center    | Sitz: Dornach, Gemeinde Aschheim, Landkreis München
           | Registergericht München, HRB Nr. 43632


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries
  2009-01-14 17:48         ` Ingo Molnar
@ 2009-01-15  3:44           ` FUJITA Tomonori
  0 siblings, 0 replies; 72+ messages in thread
From: FUJITA Tomonori @ 2009-01-15  3:44 UTC (permalink / raw)
  To: mingo
  Cc: akpm, joerg.roedel, linux-kernel, mingo, dwmw2, fujita.tomonori,
	netdev, iommu

On Wed, 14 Jan 2009 18:48:04 +0100
Ingo Molnar <mingo@elte.hu> wrote:

> 
> * Andrew Morton <akpm@linux-foundation.org> wrote:
> 
> > On Wed, 14 Jan 2009 12:43:47 +0100 Ingo Molnar <mingo@elte.hu> wrote:
> > 
> > > 
> > > * Andrew Morton <akpm@linux-foundation.org> wrote:
> > > 
> > > > On Fri, 9 Jan 2009 17:19:17 +0100 Joerg Roedel <joerg.roedel@amd.com> wrote:
> > > > 
> > > > > +struct hash_bucket {
> > > > > +	struct list_head list;
> > > > > +	spinlock_t lock;
> > > > > +} ____cacheline_aligned;
> > > > 
> > > > __cacheline_aligned_in_smp.
> > > > 
> > > > This all looks like an exotically large amount of code for a debug 
> > > > thingy?
> > > 
> > > this code checks the DMA usage of ~1 million lines of kernel code - all 
> > > the DMA using drivers. I think Joerg's feature is hugely relevant as DMA 
> > > scribbles are one of the hardest to debug kernel bugs: they can end up in 
> > > permanent data corruption or other hard to find bugs. In fact i think his 
> > > patchset is rather simple and even having 10 times as much debug code 
> > > would pay for its existence in the long run.
> > > 
> > 
> > Have we previously found bugs by other means which this facility would 
> > have detected?  I don't recall any...
> 
> btw., during the past decade we have had countless very ugly driver DMA 
> bugs in the past that took vendors months and specialized equipment to 
> track down.
> 
> I cannot give you a number breakdown, only an impression: storage drivers 
> tended to be the hardest hit (due to the severity of the bugs and due to 
> their inherent complexity) - but DMA bugs in networking drivers can be 
> hard to track down too.

We have had ugly DMA bugs in scsi drivers but I think that this new
feature can find very few of them. I can't think of any SCSI driver
bugs that this could find. This feature can't find any popular DMA
bugs in scsi drivers, such as messing up driver's dma descriptor from
a scatter gather list.

But this can find some kinds of DMA bugs and it's is just about 1,000
lines. I don't see any problem about merging this. 1,000 lines it too
large? Maybe cutting just 1,000 lines up into too many pieces is
deceptive.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
                   ` (17 preceding siblings ...)
  2009-01-10 23:54 ` Ingo Molnar
@ 2009-02-05 22:52 ` David Woodhouse
  2009-02-06  2:05   ` Chris Wright
                     ` (2 more replies)
  18 siblings, 3 replies; 72+ messages in thread
From: David Woodhouse @ 2009-02-05 22:52 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: linux-kernel, mingo, fujita.tomonori, netdev, iommu

This adds a function to dump the DMA mappings that the debugging code is
aware of -- either for a single device, or for _all_ devices.

This can be useful for debugging -- sticking a call to it in the DMA
page fault handler, for example, to see if the faulting address _should_
be mapped or not, and hence work out whether it's IOMMU bugs we're
seeing, or driver bugs.

I'd also like to make it answer the question 'should address X be mapped
for device Y', but I'll get to that next.

Do we have a %pX format for printing dma_addr_t yet? 

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
index 8a8aae4..5f4fc9f 100644
--- a/include/linux/dma-debug.h
+++ b/include/linux/dma-debug.h
@@ -75,6 +75,8 @@ extern void debug_dma_sync_sg_for_device(struct device *dev,
 					 struct scatterlist *sg,
 					 int nelems, int direction);
 
+extern void debug_dma_dump_mappings(struct device *dev);
+
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_init(u32 num_entries)
@@ -155,6 +157,10 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev,
 {
 }
 
+static inline void debug_dma_dump_mappings(struct device *dev)
+{
+}
+
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 469e5b9..127d108 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -191,6 +191,36 @@ static void hash_bucket_del(struct dma_debug_entry *entry)
 }
 
 /*
+ * Dump mapping entries for debugging purposes
+ */
+void debug_dma_dump_mappings(struct device *dev)
+{
+	int idx;
+
+	for (idx = 0; idx < HASH_SIZE; idx++) {
+		struct hash_bucket *bucket = &dma_entry_hash[idx];
+		struct dma_debug_entry *entry;
+		unsigned long flags;
+
+		spin_lock_irqsave(&bucket->lock, flags);
+
+		list_for_each_entry(entry, &bucket->list, list) {
+			if (!dev || dev == entry->dev) {
+				dev_info(entry->dev,
+					 "%s idx %d P=%Lx D=%Lx L=%Lx %s\n",
+					 type2name[entry->type], idx,
+					 (unsigned long long)entry->paddr,
+					 entry->dev_addr, entry->size,
+					 dir2name[entry->direction]);
+			}
+		}
+
+			spin_unlock_irqrestore(&bucket->lock, flags);
+	}
+}
+EXPORT_SYMBOL(debug_dma_dump_mappings);
+
+/*
  * Wrapper function for adding an entry to the hash.
  * This function takes care of locking itself.
  */


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


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-05 22:52 ` David Woodhouse
@ 2009-02-06  2:05   ` Chris Wright
  2009-02-06  7:56     ` David Woodhouse
  2009-02-12 14:48     ` Joerg Roedel
  2009-02-06  2:27   ` Chris Wright
  2009-02-12 15:20   ` Joerg Roedel
  2 siblings, 2 replies; 72+ messages in thread
From: Chris Wright @ 2009-02-06  2:05 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Joerg Roedel, fujita.tomonori, netdev, iommu, mingo, linux-kernel

* David Woodhouse (dwmw2@infradead.org) wrote:

> +		spin_lock_irqsave(&bucket->lock, flags);
> +			spin_unlock_irqrestore(&bucket->lock, flags);

extra tab

Sample output below (2 of ~2500 faults), pages don't appear to be mapped:
(interesting hash_fn spread ;-)

[   21.646796] DMAR:[DMA Write] Request device [03:00.0] fault addr ff9df000 
[   21.646796] DMAR:[fault reason 05] PTE Write access is not set
[   21.646799] iwlagn 0000:03:00.0: single idx 0 P=1347d4000 D=ffe00000 L=2100 DMA_FROM_DEVICE
[   21.646802] iwlagn 0000:03:00.0: single idx 0 P=1325d4000 D=ffc00000 L=2100 DMA_FROM_DEVICE
[   21.646804] iwlagn 0000:03:00.0: coherent idx 0 P=1322a0000 D=ffa00000 L=8000 DMA_BIDIRECTIONAL
[   21.646806] iwlagn 0000:03:00.0: single idx 2 P=1347d0000 D=ffe04000 L=2100 DMA_FROM_DEVICE
[   21.646808] iwlagn 0000:03:00.0: single idx 2 P=1325d0000 D=ffc04000 L=2100 DMA_FROM_DEVICE
[   21.646810] iwlagn 0000:03:00.0: single idx 4 P=1347cc000 D=ffe08000 L=2100 DMA_FROM_DEVICE
[   21.646812] iwlagn 0000:03:00.0: single idx 4 P=1325cc000 D=ffc08000 L=2100 DMA_FROM_DEVICE
[   21.646814] iwlagn 0000:03:00.0: coherent idx 4 P=132258000 D=ffa08000 L=8000 DMA_BIDIRECTIONAL
[   21.646816] iwlagn 0000:03:00.0: single idx 6 P=1347c8000 D=ffe0c000 L=2100 DMA_FROM_DEVICE
[   21.646818] iwlagn 0000:03:00.0: single idx 6 P=1325c8000 D=ffc0c000 L=2100 DMA_FROM_DEVICE
[   21.646820] iwlagn 0000:03:00.0: single idx 8 P=1347c4000 D=ffe10000 L=2100 DMA_FROM_DEVICE
[   21.646822] iwlagn 0000:03:00.0: single idx 8 P=1325c4000 D=ffc10000 L=2100 DMA_FROM_DEVICE
[   21.646824] iwlagn 0000:03:00.0: coherent idx 8 P=132230000 D=ffa10000 L=8000 DMA_BIDIRECTIONAL
[   21.646826] iwlagn 0000:03:00.0: single idx 10 P=1347c0000 D=ffe14000 L=2100 DMA_FROM_DEVICE
[   21.646828] iwlagn 0000:03:00.0: single idx 10 P=1325c0000 D=ffc14000 L=2100 DMA_FROM_DEVICE
[   21.646830] iwlagn 0000:03:00.0: single idx 12 P=1347bc000 D=ffe18000 L=2100 DMA_FROM_DEVICE
[   21.646832] iwlagn 0000:03:00.0: single idx 12 P=1325bc000 D=ffc18000 L=2100 DMA_FROM_DEVICE
[   21.646834] iwlagn 0000:03:00.0: coherent idx 12 P=1321e8000 D=ffa18000 L=8000 DMA_BIDIRECTIONAL
[   21.646836] iwlagn 0000:03:00.0: single idx 14 P=1347b8000 D=ffe1c000 L=2100 DMA_FROM_DEVICE
[   21.646838] iwlagn 0000:03:00.0: single idx 14 P=1325b8000 D=ffc1c000 L=2100 DMA_FROM_DEVICE
[   21.646840] iwlagn 0000:03:00.0: single idx 16 P=1347b4000 D=ffe20000 L=2100 DMA_FROM_DEVICE
[   21.646842] iwlagn 0000:03:00.0: single idx 16 P=1325b4000 D=ffc20000 L=2100 DMA_FROM_DEVICE
[   21.646844] iwlagn 0000:03:00.0: coherent idx 16 P=1321c0000 D=ffa20000 L=8000 DMA_BIDIRECTIONAL
[   21.646846] iwlagn 0000:03:00.0: single idx 18 P=1347b0000 D=ffe24000 L=2100 DMA_FROM_DEVICE
[   21.646848] iwlagn 0000:03:00.0: single idx 18 P=1325b0000 D=ffc24000 L=2100 DMA_FROM_DEVICE
[   21.646850] iwlagn 0000:03:00.0: single idx 20 P=1347ac000 D=ffe28000 L=2100 DMA_FROM_DEVICE
[   21.646852] iwlagn 0000:03:00.0: single idx 20 P=1325ac000 D=ffc28000 L=2100 DMA_FROM_DEVICE
[   21.646854] iwlagn 0000:03:00.0: coherent idx 20 P=132178000 D=ffa28000 L=8000 DMA_BIDIRECTIONAL
[   21.646856] iwlagn 0000:03:00.0: single idx 22 P=1347a8000 D=ffe2c000 L=2100 DMA_FROM_DEVICE
[   21.646858] iwlagn 0000:03:00.0: single idx 22 P=1325a8000 D=ffc2c000 L=2100 DMA_FROM_DEVICE
[   21.646860] iwlagn 0000:03:00.0: single idx 24 P=1347a4000 D=ffe30000 L=2100 DMA_FROM_DEVICE
[   21.646862] iwlagn 0000:03:00.0: single idx 24 P=1325a4000 D=ffc30000 L=2100 DMA_FROM_DEVICE
[   21.646863] iwlagn 0000:03:00.0: coherent idx 24 P=132150000 D=ffa30000 L=8000 DMA_BIDIRECTIONAL
[   21.646866] iwlagn 0000:03:00.0: single idx 26 P=1347a0000 D=ffe34000 L=2100 DMA_FROM_DEVICE
[   21.646867] iwlagn 0000:03:00.0: single idx 26 P=1325a0000 D=ffc34000 L=2100 DMA_FROM_DEVICE
[   21.646870] iwlagn 0000:03:00.0: single idx 28 P=13479c000 D=ffe38000 L=2100 DMA_FROM_DEVICE
[   21.646871] iwlagn 0000:03:00.0: single idx 28 P=13259c000 D=ffc38000 L=2100 DMA_FROM_DEVICE
[   21.646873] iwlagn 0000:03:00.0: coherent idx 28 P=132108000 D=ffa38000 L=8000 DMA_BIDIRECTIONAL
[   21.646875] iwlagn 0000:03:00.0: single idx 30 P=134798000 D=ffe3c000 L=2100 DMA_FROM_DEVICE
[   21.646877] iwlagn 0000:03:00.0: single idx 30 P=132598000 D=ffc3c000 L=2100 DMA_FROM_DEVICE
[   21.646879] iwlagn 0000:03:00.0: single idx 32 P=134794000 D=ffe40000 L=2100 DMA_FROM_DEVICE
[   21.646881] iwlagn 0000:03:00.0: single idx 32 P=132594000 D=ffc40000 L=2100 DMA_FROM_DEVICE
[   21.646883] iwlagn 0000:03:00.0: coherent idx 32 P=1320e0000 D=ffa40000 L=8000 DMA_BIDIRECTIONAL
[   21.646885] iwlagn 0000:03:00.0: single idx 34 P=134790000 D=ffe44000 L=2100 DMA_FROM_DEVICE
[   21.646887] iwlagn 0000:03:00.0: single idx 34 P=132590000 D=ffc44000 L=2100 DMA_FROM_DEVICE
[   21.646889] iwlagn 0000:03:00.0: single idx 36 P=13478c000 D=ffe48000 L=2100 DMA_FROM_DEVICE
[   21.646891] iwlagn 0000:03:00.0: single idx 36 P=13258c000 D=ffc48000 L=2100 DMA_FROM_DEVICE
[   21.646893] iwlagn 0000:03:00.0: coherent idx 36 P=132098000 D=ffa48000 L=8000 DMA_BIDIRECTIONAL
[   21.646901] iwlagn 0000:03:00.0: single idx 38 P=134788000 D=ffe4c000 L=2100 DMA_FROM_DEVICE
[   21.646902] iwlagn 0000:03:00.0: single idx 38 P=132588000 D=ffc4c000 L=2100 DMA_FROM_DEVICE
[   21.646904] iwlagn 0000:03:00.0: single idx 40 P=134784000 D=ffe50000 L=2100 DMA_FROM_DEVICE
[   21.646906] iwlagn 0000:03:00.0: single idx 40 P=132584000 D=ffc50000 L=2100 DMA_FROM_DEVICE
[   21.646908] iwlagn 0000:03:00.0: coherent idx 40 P=132070000 D=ffa50000 L=8000 DMA_BIDIRECTIONAL
[   21.646910] iwlagn 0000:03:00.0: single idx 42 P=134780000 D=ffe54000 L=2100 DMA_FROM_DEVICE
[   21.646912] iwlagn 0000:03:00.0: single idx 42 P=132580000 D=ffc54000 L=2100 DMA_FROM_DEVICE
[   21.646914] iwlagn 0000:03:00.0: single idx 44 P=13477c000 D=ffe58000 L=2100 DMA_FROM_DEVICE
[   21.646915] iwlagn 0000:03:00.0: single idx 44 P=13257c000 D=ffc58000 L=2100 DMA_FROM_DEVICE
[   21.646917] iwlagn 0000:03:00.0: coherent idx 44 P=132038000 D=ffa58000 L=8000 DMA_BIDIRECTIONAL
[   21.646919] iwlagn 0000:03:00.0: single idx 46 P=134778000 D=ffe5c000 L=2100 DMA_FROM_DEVICE
[   21.646921] iwlagn 0000:03:00.0: single idx 46 P=132578000 D=ffc5c000 L=2100 DMA_FROM_DEVICE
[   21.646923] iwlagn 0000:03:00.0: single idx 48 P=134774000 D=ffe60000 L=2100 DMA_FROM_DEVICE
[   21.646925] iwlagn 0000:03:00.0: single idx 48 P=132574000 D=ffc60000 L=2100 DMA_FROM_DEVICE
[   21.646927] iwlagn 0000:03:00.0: coherent idx 48 P=132018000 D=ffa60000 L=8000 DMA_BIDIRECTIONAL
[   21.646929] iwlagn 0000:03:00.0: single idx 50 P=134770000 D=ffe64000 L=2100 DMA_FROM_DEVICE
[   21.646930] iwlagn 0000:03:00.0: single idx 50 P=132570000 D=ffc64000 L=2100 DMA_FROM_DEVICE
[   21.646932] iwlagn 0000:03:00.0: single idx 52 P=13476c000 D=ffe68000 L=2100 DMA_FROM_DEVICE
[   21.646934] iwlagn 0000:03:00.0: single idx 52 P=13256c000 D=ffc68000 L=2100 DMA_FROM_DEVICE
[   21.646936] iwlagn 0000:03:00.0: coherent idx 52 P=1327f0000 D=ffa68000 L=8000 DMA_BIDIRECTIONAL
[   21.646938] iwlagn 0000:03:00.0: single idx 54 P=134768000 D=ffe6c000 L=2100 DMA_FROM_DEVICE
[   21.646940] iwlagn 0000:03:00.0: single idx 54 P=132568000 D=ffc6c000 L=2100 DMA_FROM_DEVICE
[   21.646942] iwlagn 0000:03:00.0: single idx 56 P=134764000 D=ffe70000 L=2100 DMA_FROM_DEVICE
[   21.646944] iwlagn 0000:03:00.0: single idx 56 P=132564000 D=ffc70000 L=2100 DMA_FROM_DEVICE
[   21.646945] iwlagn 0000:03:00.0: coherent idx 56 P=1327a8000 D=ffa70000 L=8000 DMA_BIDIRECTIONAL
[   21.646947] iwlagn 0000:03:00.0: single idx 58 P=134760000 D=ffe74000 L=2100 DMA_FROM_DEVICE
[   21.646949] iwlagn 0000:03:00.0: single idx 58 P=132560000 D=ffc74000 L=2100 DMA_FROM_DEVICE
[   21.646951] iwlagn 0000:03:00.0: single idx 60 P=13475c000 D=ffe78000 L=2100 DMA_FROM_DEVICE
[   21.646953] iwlagn 0000:03:00.0: single idx 60 P=13255c000 D=ffc78000 L=2100 DMA_FROM_DEVICE
[   21.646955] iwlagn 0000:03:00.0: coherent idx 60 P=132780000 D=ffa78000 L=8000 DMA_BIDIRECTIONAL
[   21.646957] iwlagn 0000:03:00.0: single idx 62 P=134758000 D=ffe7c000 L=2100 DMA_FROM_DEVICE
[   21.646958] iwlagn 0000:03:00.0: single idx 62 P=132558000 D=ffc7c000 L=2100 DMA_FROM_DEVICE
[   21.646960] iwlagn 0000:03:00.0: single idx 64 P=134754000 D=ffe80000 L=2100 DMA_FROM_DEVICE
[   21.646962] iwlagn 0000:03:00.0: single idx 64 P=132554000 D=ffc80000 L=2100 DMA_FROM_DEVICE
[   21.646964] iwlagn 0000:03:00.0: single idx 66 P=134750000 D=ffe84000 L=2100 DMA_FROM_DEVICE
[   21.646966] iwlagn 0000:03:00.0: single idx 66 P=132550000 D=ffc84000 L=2100 DMA_FROM_DEVICE
[   21.646968] iwlagn 0000:03:00.0: coherent idx 67 P=135027000 D=ffa87000 L=1000 DMA_BIDIRECTIONAL
[   21.646970] iwlagn 0000:03:00.0: single idx 68 P=13474c000 D=ffe88000 L=2100 DMA_FROM_DEVICE
[   21.646972] iwlagn 0000:03:00.0: single idx 68 P=13254c000 D=ffc88000 L=2100 DMA_FROM_DEVICE
[   21.646973] iwlagn 0000:03:00.0: coherent idx 68 P=13274c000 D=ffa88000 L=3200 DMA_BIDIRECTIONAL
[   21.646975] iwlagn 0000:03:00.0: single idx 70 P=134748000 D=ffe8c000 L=2100 DMA_FROM_DEVICE
[   21.646977] iwlagn 0000:03:00.0: single idx 70 P=132548000 D=ffc8c000 L=2100 DMA_FROM_DEVICE
[   21.646979] iwlagn 0000:03:00.0: single idx 70 P=132748000 D=ffa8c000 L=2100 DMA_FROM_DEVICE
[   21.646981] iwlagn 0000:03:00.0: single idx 72 P=134744000 D=ffe90000 L=2100 DMA_FROM_DEVICE
[   21.646982] iwlagn 0000:03:00.0: single idx 72 P=132544000 D=ffc90000 L=2100 DMA_FROM_DEVICE
[   21.646984] iwlagn 0000:03:00.0: single idx 72 P=132744000 D=ffa90000 L=2100 DMA_FROM_DEVICE
[   21.646986] iwlagn 0000:03:00.0: single idx 74 P=134740000 D=ffe94000 L=2100 DMA_FROM_DEVICE
[   21.646988] iwlagn 0000:03:00.0: single idx 74 P=132540000 D=ffc94000 L=2100 DMA_FROM_DEVICE
[   21.646990] iwlagn 0000:03:00.0: single idx 74 P=132740000 D=ffa94000 L=2100 DMA_FROM_DEVICE
[   21.646992] iwlagn 0000:03:00.0: single idx 76 P=13473c000 D=ffe98000 L=2100 DMA_FROM_DEVICE
[   21.646994] iwlagn 0000:03:00.0: single idx 76 P=13253c000 D=ffc98000 L=2100 DMA_FROM_DEVICE
[   21.646995] iwlagn 0000:03:00.0: single idx 76 P=13273c000 D=ffa98000 L=2100 DMA_FROM_DEVICE
[   21.646997] iwlagn 0000:03:00.0: single idx 78 P=134738000 D=ffe9c000 L=2100 DMA_FROM_DEVICE
[   21.646999] iwlagn 0000:03:00.0: single idx 78 P=132538000 D=ffc9c000 L=2100 DMA_FROM_DEVICE
[   21.647001] iwlagn 0000:03:00.0: single idx 78 P=132738000 D=ffa9c000 L=2100 DMA_FROM_DEVICE
[   21.647014] iwlagn 0000:03:00.0: single idx 80 P=134734000 D=ffea0000 L=2100 DMA_FROM_DEVICE
[   21.647016] iwlagn 0000:03:00.0: single idx 80 P=132534000 D=ffca0000 L=2100 DMA_FROM_DEVICE
[   21.647025] iwlagn 0000:03:00.0: single idx 80 P=132734000 D=ffaa0000 L=2100 DMA_FROM_DEVICE
[   21.647027] iwlagn 0000:03:00.0: single idx 82 P=134730000 D=ffea4000 L=2100 DMA_FROM_DEVICE
[   21.647029] iwlagn 0000:03:00.0: single idx 82 P=132530000 D=ffca4000 L=2100 DMA_FROM_DEVICE
[   21.647031] iwlagn 0000:03:00.0: single idx 82 P=132730000 D=ffaa4000 L=2100 DMA_FROM_DEVICE
[   21.647033] iwlagn 0000:03:00.0: single idx 84 P=13472c000 D=ffea8000 L=2100 DMA_FROM_DEVICE
[   21.647035] iwlagn 0000:03:00.0: single idx 84 P=13252c000 D=ffca8000 L=2100 DMA_FROM_DEVICE
[   21.647037] iwlagn 0000:03:00.0: single idx 84 P=13272c000 D=ffaa8000 L=2100 DMA_FROM_DEVICE
[   21.647039] iwlagn 0000:03:00.0: single idx 86 P=134728000 D=ffeac000 L=2100 DMA_FROM_DEVICE
[   21.647041] iwlagn 0000:03:00.0: single idx 86 P=132528000 D=ffcac000 L=2100 DMA_FROM_DEVICE
[   21.647043] iwlagn 0000:03:00.0: single idx 86 P=132728000 D=ffaac000 L=2100 DMA_FROM_DEVICE
[   21.647046] iwlagn 0000:03:00.0: single idx 88 P=134724000 D=ffeb0000 L=2100 DMA_FROM_DEVICE
[   21.647048] iwlagn 0000:03:00.0: single idx 88 P=132524000 D=ffcb0000 L=2100 DMA_FROM_DEVICE
[   21.647050] iwlagn 0000:03:00.0: single idx 88 P=132724000 D=ffab0000 L=2100 DMA_FROM_DEVICE
[   21.647052] iwlagn 0000:03:00.0: single idx 90 P=134720000 D=ffeb4000 L=2100 DMA_FROM_DEVICE
[   21.647054] iwlagn 0000:03:00.0: single idx 90 P=132520000 D=ffcb4000 L=2100 DMA_FROM_DEVICE
[   21.647057] iwlagn 0000:03:00.0: single idx 90 P=132720000 D=ffab4000 L=2100 DMA_FROM_DEVICE
[   21.647059] iwlagn 0000:03:00.0: single idx 92 P=13471c000 D=ffeb8000 L=2100 DMA_FROM_DEVICE
[   21.647061] iwlagn 0000:03:00.0: single idx 92 P=13251c000 D=ffcb8000 L=2100 DMA_FROM_DEVICE
[   21.647063] iwlagn 0000:03:00.0: single idx 92 P=13271c000 D=ffab8000 L=2100 DMA_FROM_DEVICE
[   21.647066] iwlagn 0000:03:00.0: single idx 94 P=134718000 D=ffebc000 L=2100 DMA_FROM_DEVICE
[   21.647068] iwlagn 0000:03:00.0: single idx 94 P=132518000 D=ffcbc000 L=2100 DMA_FROM_DEVICE
[   21.647070] iwlagn 0000:03:00.0: single idx 94 P=132718000 D=ffabc000 L=2100 DMA_FROM_DEVICE
[   21.647072] iwlagn 0000:03:00.0: single idx 96 P=134714000 D=ffec0000 L=2100 DMA_FROM_DEVICE
[   21.647074] iwlagn 0000:03:00.0: single idx 96 P=132514000 D=ffcc0000 L=2100 DMA_FROM_DEVICE
[   21.647077] iwlagn 0000:03:00.0: single idx 96 P=132714000 D=ffac0000 L=2100 DMA_FROM_DEVICE
[   21.647079] iwlagn 0000:03:00.0: single idx 98 P=134710000 D=ffec4000 L=2100 DMA_FROM_DEVICE
[   21.647081] iwlagn 0000:03:00.0: single idx 98 P=132510000 D=ffcc4000 L=2100 DMA_FROM_DEVICE
[   21.647083] iwlagn 0000:03:00.0: single idx 98 P=132710000 D=ffac4000 L=2100 DMA_FROM_DEVICE
[   21.647086] iwlagn 0000:03:00.0: single idx 100 P=13470c000 D=ffec8000 L=2100 DMA_FROM_DEVICE
[   21.647088] iwlagn 0000:03:00.0: single idx 100 P=13250c000 D=ffcc8000 L=2100 DMA_FROM_DEVICE
[   21.647090] iwlagn 0000:03:00.0: single idx 100 P=13270c000 D=ffac8000 L=2100 DMA_FROM_DEVICE
[   21.647093] iwlagn 0000:03:00.0: single idx 102 P=134708000 D=ffecc000 L=2100 DMA_FROM_DEVICE
[   21.647095] iwlagn 0000:03:00.0: single idx 102 P=132508000 D=ffccc000 L=2100 DMA_FROM_DEVICE
[   21.647097] iwlagn 0000:03:00.0: single idx 102 P=132708000 D=ffacc000 L=2100 DMA_FROM_DEVICE
[   21.647100] iwlagn 0000:03:00.0: single idx 104 P=134704000 D=ffed0000 L=2100 DMA_FROM_DEVICE
[   21.647102] iwlagn 0000:03:00.0: single idx 104 P=132504000 D=ffcd0000 L=2100 DMA_FROM_DEVICE
[   21.647104] iwlagn 0000:03:00.0: single idx 104 P=132704000 D=ffad0000 L=2100 DMA_FROM_DEVICE
[   21.647106] iwlagn 0000:03:00.0: single idx 106 P=134700000 D=ffed4000 L=2100 DMA_FROM_DEVICE
[   21.647108] iwlagn 0000:03:00.0: single idx 106 P=132500000 D=ffcd4000 L=2100 DMA_FROM_DEVICE
[   21.647110] iwlagn 0000:03:00.0: single idx 106 P=132700000 D=ffad4000 L=2100 DMA_FROM_DEVICE
[   21.647113] iwlagn 0000:03:00.0: single idx 108 P=1346fc000 D=ffed8000 L=2100 DMA_FROM_DEVICE
[   21.647115] iwlagn 0000:03:00.0: single idx 108 P=1324fc000 D=ffcd8000 L=2100 DMA_FROM_DEVICE
[   21.647117] iwlagn 0000:03:00.0: single idx 108 P=1326fc000 D=ffad8000 L=2100 DMA_FROM_DEVICE
[   21.647120] iwlagn 0000:03:00.0: single idx 110 P=1346f8000 D=ffedc000 L=2100 DMA_FROM_DEVICE
[   21.647122] iwlagn 0000:03:00.0: single idx 110 P=1324f8000 D=ffcdc000 L=2100 DMA_FROM_DEVICE
[   21.647124] iwlagn 0000:03:00.0: single idx 110 P=1326f8000 D=ffadc000 L=2100 DMA_FROM_DEVICE
[   21.647126] iwlagn 0000:03:00.0: single idx 112 P=1346f4000 D=ffee0000 L=2100 DMA_FROM_DEVICE
[   21.647128] iwlagn 0000:03:00.0: single idx 112 P=1324f4000 D=ffce0000 L=2100 DMA_FROM_DEVICE
[   21.647130] iwlagn 0000:03:00.0: single idx 112 P=1326f4000 D=ffae0000 L=2100 DMA_FROM_DEVICE
[   21.647132] iwlagn 0000:03:00.0: single idx 114 P=1346f0000 D=ffee4000 L=2100 DMA_FROM_DEVICE
[   21.647134] iwlagn 0000:03:00.0: single idx 114 P=1324f0000 D=ffce4000 L=2100 DMA_FROM_DEVICE
[   21.647136] iwlagn 0000:03:00.0: single idx 114 P=1326f0000 D=ffae4000 L=2100 DMA_FROM_DEVICE
[   21.647138] iwlagn 0000:03:00.0: single idx 116 P=1346ec000 D=ffee8000 L=2100 DMA_FROM_DEVICE
[   21.647140] iwlagn 0000:03:00.0: single idx 116 P=1324ec000 D=ffce8000 L=2100 DMA_FROM_DEVICE
[   21.647142] iwlagn 0000:03:00.0: single idx 116 P=1326ec000 D=ffae8000 L=2100 DMA_FROM_DEVICE
[   21.647144] iwlagn 0000:03:00.0: single idx 118 P=1346e8000 D=ffeec000 L=2100 DMA_FROM_DEVICE
[   21.647147] iwlagn 0000:03:00.0: single idx 118 P=1324e8000 D=ffcec000 L=2100 DMA_FROM_DEVICE
[   21.647149] iwlagn 0000:03:00.0: single idx 118 P=1326e8000 D=ffaec000 L=2100 DMA_FROM_DEVICE
[   21.647151] iwlagn 0000:03:00.0: single idx 120 P=1346e4000 D=ffef0000 L=2100 DMA_FROM_DEVICE
[   21.647153] iwlagn 0000:03:00.0: single idx 120 P=1324e4000 D=ffcf0000 L=2100 DMA_FROM_DEVICE
[   21.647155] iwlagn 0000:03:00.0: single idx 120 P=1326e4000 D=ffaf0000 L=2100 DMA_FROM_DEVICE
[   21.647158] iwlagn 0000:03:00.0: single idx 122 P=1346e0000 D=ffef4000 L=2100 DMA_FROM_DEVICE
[   21.647160] iwlagn 0000:03:00.0: single idx 122 P=1324e0000 D=ffcf4000 L=2100 DMA_FROM_DEVICE
[   21.647162] iwlagn 0000:03:00.0: single idx 122 P=1326e0000 D=ffaf4000 L=2100 DMA_FROM_DEVICE
[   21.647164] iwlagn 0000:03:00.0: single idx 124 P=1346dc000 D=ffef8000 L=2100 DMA_FROM_DEVICE
[   21.647167] iwlagn 0000:03:00.0: single idx 124 P=1324dc000 D=ffcf8000 L=2100 DMA_FROM_DEVICE
[   21.647169] iwlagn 0000:03:00.0: single idx 124 P=1326dc000 D=ffaf8000 L=2100 DMA_FROM_DEVICE
[   21.647171] iwlagn 0000:03:00.0: single idx 126 P=1346d8000 D=ffefc000 L=2100 DMA_FROM_DEVICE
[   21.647173] iwlagn 0000:03:00.0: single idx 126 P=1324d8000 D=ffcfc000 L=2100 DMA_FROM_DEVICE
[   21.647175] iwlagn 0000:03:00.0: single idx 126 P=1326d8000 D=ffafc000 L=2100 DMA_FROM_DEVICE
[   21.647178] iwlagn 0000:03:00.0: single idx 128 P=1346d4000 D=fff00000 L=2100 DMA_FROM_DEVICE
[   21.647180] iwlagn 0000:03:00.0: single idx 128 P=1324d4000 D=ffd00000 L=2100 DMA_FROM_DEVICE
[   21.647182] iwlagn 0000:03:00.0: single idx 128 P=1326d4000 D=ffb00000 L=2100 DMA_FROM_DEVICE
[   21.647185] iwlagn 0000:03:00.0: single idx 130 P=1346d0000 D=fff04000 L=2100 DMA_FROM_DEVICE
[   21.647187] iwlagn 0000:03:00.0: single idx 130 P=1324d0000 D=ffd04000 L=2100 DMA_FROM_DEVICE
[   21.647189] iwlagn 0000:03:00.0: single idx 130 P=1326d0000 D=ffb04000 L=2100 DMA_FROM_DEVICE
[   21.647192] iwlagn 0000:03:00.0: single idx 132 P=1346cc000 D=fff08000 L=2100 DMA_FROM_DEVICE
[   21.647194] iwlagn 0000:03:00.0: single idx 132 P=1324cc000 D=ffd08000 L=2100 DMA_FROM_DEVICE
[   21.647196] iwlagn 0000:03:00.0: single idx 132 P=1326cc000 D=ffb08000 L=2100 DMA_FROM_DEVICE
[   21.647198] iwlagn 0000:03:00.0: single idx 134 P=1346c8000 D=fff0c000 L=2100 DMA_FROM_DEVICE
[   21.647201] iwlagn 0000:03:00.0: single idx 134 P=1324c8000 D=ffd0c000 L=2100 DMA_FROM_DEVICE
[   21.647203] iwlagn 0000:03:00.0: single idx 134 P=1326c8000 D=ffb0c000 L=2100 DMA_FROM_DEVICE
[   21.647205] iwlagn 0000:03:00.0: single idx 136 P=1346c4000 D=fff10000 L=2100 DMA_FROM_DEVICE
[   21.647207] iwlagn 0000:03:00.0: single idx 136 P=1324c4000 D=ffd10000 L=2100 DMA_FROM_DEVICE
[   21.647209] iwlagn 0000:03:00.0: single idx 136 P=1326c4000 D=ffb10000 L=2100 DMA_FROM_DEVICE
[   21.647212] iwlagn 0000:03:00.0: single idx 138 P=1346c0000 D=fff14000 L=2100 DMA_FROM_DEVICE
[   21.647214] iwlagn 0000:03:00.0: single idx 138 P=1324c0000 D=ffd14000 L=2100 DMA_FROM_DEVICE
[   21.647216] iwlagn 0000:03:00.0: single idx 138 P=1326c0000 D=ffb14000 L=2100 DMA_FROM_DEVICE
[   21.647219] iwlagn 0000:03:00.0: single idx 140 P=1346bc000 D=fff18000 L=2100 DMA_FROM_DEVICE
[   21.647221] iwlagn 0000:03:00.0: single idx 140 P=1324bc000 D=ffd18000 L=2100 DMA_FROM_DEVICE
[   21.647223] iwlagn 0000:03:00.0: single idx 140 P=1326bc000 D=ffb18000 L=2100 DMA_FROM_DEVICE
[   21.647225] iwlagn 0000:03:00.0: single idx 142 P=1346b8000 D=fff1c000 L=2100 DMA_FROM_DEVICE
[   21.647228] iwlagn 0000:03:00.0: single idx 142 P=1324b8000 D=ffd1c000 L=2100 DMA_FROM_DEVICE
[   21.647230] iwlagn 0000:03:00.0: single idx 142 P=1326b8000 D=ffb1c000 L=2100 DMA_FROM_DEVICE
[   21.647232] iwlagn 0000:03:00.0: single idx 144 P=1346b4000 D=fff20000 L=2100 DMA_FROM_DEVICE
[   21.647234] iwlagn 0000:03:00.0: single idx 144 P=1324b4000 D=ffd20000 L=2100 DMA_FROM_DEVICE
[   21.647237] iwlagn 0000:03:00.0: single idx 144 P=1326b4000 D=ffb20000 L=2100 DMA_FROM_DEVICE
[   21.647239] iwlagn 0000:03:00.0: single idx 146 P=1346b0000 D=fff24000 L=2100 DMA_FROM_DEVICE
[   21.647241] iwlagn 0000:03:00.0: single idx 146 P=1324b0000 D=ffd24000 L=2100 DMA_FROM_DEVICE
[   21.647243] iwlagn 0000:03:00.0: single idx 146 P=1326b0000 D=ffb24000 L=2100 DMA_FROM_DEVICE
[   21.647246] iwlagn 0000:03:00.0: single idx 148 P=1346ac000 D=fff28000 L=2100 DMA_FROM_DEVICE
[   21.647248] iwlagn 0000:03:00.0: single idx 148 P=1324ac000 D=ffd28000 L=2100 DMA_FROM_DEVICE
[   21.647250] iwlagn 0000:03:00.0: single idx 148 P=1326ac000 D=ffb28000 L=2100 DMA_FROM_DEVICE
[   21.647252] iwlagn 0000:03:00.0: single idx 150 P=1346a8000 D=fff2c000 L=2100 DMA_FROM_DEVICE
[   21.647255] iwlagn 0000:03:00.0: single idx 150 P=1324a8000 D=ffd2c000 L=2100 DMA_FROM_DEVICE
[   21.647257] iwlagn 0000:03:00.0: single idx 150 P=1326a8000 D=ffb2c000 L=2100 DMA_FROM_DEVICE
[   21.647259] iwlagn 0000:03:00.0: single idx 152 P=1346a4000 D=fff30000 L=2100 DMA_FROM_DEVICE
[   21.647261] iwlagn 0000:03:00.0: single idx 152 P=1324a4000 D=ffd30000 L=2100 DMA_FROM_DEVICE
[   21.647263] iwlagn 0000:03:00.0: single idx 152 P=1326a4000 D=ffb30000 L=2100 DMA_FROM_DEVICE
[   21.647266] iwlagn 0000:03:00.0: single idx 154 P=1346a0000 D=fff34000 L=2100 DMA_FROM_DEVICE
[   21.647268] iwlagn 0000:03:00.0: single idx 154 P=1324a0000 D=ffd34000 L=2100 DMA_FROM_DEVICE
[   21.647270] iwlagn 0000:03:00.0: single idx 154 P=1326a0000 D=ffb34000 L=2100 DMA_FROM_DEVICE
[   21.647272] iwlagn 0000:03:00.0: single idx 156 P=13469c000 D=fff38000 L=2100 DMA_FROM_DEVICE
[   21.647274] iwlagn 0000:03:00.0: single idx 156 P=13249c000 D=ffd38000 L=2100 DMA_FROM_DEVICE
[   21.647276] iwlagn 0000:03:00.0: single idx 156 P=13269c000 D=ffb38000 L=2100 DMA_FROM_DEVICE
[   21.647279] iwlagn 0000:03:00.0: single idx 158 P=134698000 D=fff3c000 L=2100 DMA_FROM_DEVICE
[   21.647281] iwlagn 0000:03:00.0: single idx 158 P=132498000 D=ffd3c000 L=2100 DMA_FROM_DEVICE
[   21.647283] iwlagn 0000:03:00.0: single idx 158 P=132698000 D=ffb3c000 L=2100 DMA_FROM_DEVICE
[   21.647286] iwlagn 0000:03:00.0: single idx 160 P=134694000 D=fff40000 L=2100 DMA_FROM_DEVICE
[   21.647288] iwlagn 0000:03:00.0: single idx 160 P=132494000 D=ffd40000 L=2100 DMA_FROM_DEVICE
[   21.647290] iwlagn 0000:03:00.0: single idx 160 P=132694000 D=ffb40000 L=2100 DMA_FROM_DEVICE
[   21.647292] iwlagn 0000:03:00.0: single idx 162 P=134690000 D=fff44000 L=2100 DMA_FROM_DEVICE
[   21.647294] iwlagn 0000:03:00.0: single idx 162 P=132490000 D=ffd44000 L=2100 DMA_FROM_DEVICE
[   21.647296] iwlagn 0000:03:00.0: single idx 162 P=132690000 D=ffb44000 L=2100 DMA_FROM_DEVICE
[   21.647299] iwlagn 0000:03:00.0: single idx 164 P=13468c000 D=fff48000 L=2100 DMA_FROM_DEVICE
[   21.647301] iwlagn 0000:03:00.0: single idx 164 P=13248c000 D=ffd48000 L=2100 DMA_FROM_DEVICE
[   21.647303] iwlagn 0000:03:00.0: single idx 164 P=13268c000 D=ffb48000 L=2100 DMA_FROM_DEVICE
[   21.647306] iwlagn 0000:03:00.0: single idx 166 P=134688000 D=fff4c000 L=2100 DMA_FROM_DEVICE
[   21.647308] iwlagn 0000:03:00.0: single idx 166 P=132488000 D=ffd4c000 L=2100 DMA_FROM_DEVICE
[   21.647310] iwlagn 0000:03:00.0: single idx 166 P=132688000 D=ffb4c000 L=2100 DMA_FROM_DEVICE
[   21.647312] iwlagn 0000:03:00.0: single idx 168 P=134684000 D=fff50000 L=2100 DMA_FROM_DEVICE
[   21.647315] iwlagn 0000:03:00.0: single idx 168 P=132484000 D=ffd50000 L=2100 DMA_FROM_DEVICE
[   21.647317] iwlagn 0000:03:00.0: single idx 168 P=132684000 D=ffb50000 L=2100 DMA_FROM_DEVICE
[   21.647319] iwlagn 0000:03:00.0: single idx 170 P=134680000 D=fff54000 L=2100 DMA_FROM_DEVICE
[   21.647321] iwlagn 0000:03:00.0: single idx 170 P=132480000 D=ffd54000 L=2100 DMA_FROM_DEVICE
[   21.647323] iwlagn 0000:03:00.0: single idx 170 P=132680000 D=ffb54000 L=2100 DMA_FROM_DEVICE
[   21.647326] iwlagn 0000:03:00.0: single idx 172 P=13467c000 D=fff58000 L=2100 DMA_FROM_DEVICE
[   21.647328] iwlagn 0000:03:00.0: single idx 172 P=13247c000 D=ffd58000 L=2100 DMA_FROM_DEVICE
[   21.647330] iwlagn 0000:03:00.0: single idx 172 P=13267c000 D=ffb58000 L=2100 DMA_FROM_DEVICE
[   21.647332] iwlagn 0000:03:00.0: single idx 174 P=134678000 D=fff5c000 L=2100 DMA_FROM_DEVICE
[   21.647334] iwlagn 0000:03:00.0: single idx 174 P=132478000 D=ffd5c000 L=2100 DMA_FROM_DEVICE
[   21.647337] iwlagn 0000:03:00.0: single idx 174 P=132678000 D=ffb5c000 L=2100 DMA_FROM_DEVICE
[   21.647339] iwlagn 0000:03:00.0: single idx 176 P=134674000 D=fff60000 L=2100 DMA_FROM_DEVICE
[   21.647341] iwlagn 0000:03:00.0: single idx 176 P=132474000 D=ffd60000 L=2100 DMA_FROM_DEVICE
[   21.647343] iwlagn 0000:03:00.0: single idx 176 P=132674000 D=ffb60000 L=2100 DMA_FROM_DEVICE
[   21.647346] iwlagn 0000:03:00.0: single idx 178 P=134670000 D=fff64000 L=2100 DMA_FROM_DEVICE
[   21.647348] iwlagn 0000:03:00.0: single idx 178 P=132470000 D=ffd64000 L=2100 DMA_FROM_DEVICE
[   21.647350] iwlagn 0000:03:00.0: single idx 178 P=132670000 D=ffb64000 L=2100 DMA_FROM_DEVICE
[   21.647352] iwlagn 0000:03:00.0: single idx 180 P=13466c000 D=fff68000 L=2100 DMA_FROM_DEVICE
[   21.647354] iwlagn 0000:03:00.0: single idx 180 P=13246c000 D=ffd68000 L=2100 DMA_FROM_DEVICE
[   21.647357] iwlagn 0000:03:00.0: single idx 180 P=13266c000 D=ffb68000 L=2100 DMA_FROM_DEVICE
[   21.647359] iwlagn 0000:03:00.0: single idx 182 P=134668000 D=fff6c000 L=2100 DMA_FROM_DEVICE
[   21.647361] iwlagn 0000:03:00.0: single idx 182 P=132468000 D=ffd6c000 L=2100 DMA_FROM_DEVICE
[   21.647363] iwlagn 0000:03:00.0: single idx 182 P=132668000 D=ffb6c000 L=2100 DMA_FROM_DEVICE
[   21.647366] iwlagn 0000:03:00.0: single idx 184 P=134664000 D=fff70000 L=2100 DMA_FROM_DEVICE
[   21.647368] iwlagn 0000:03:00.0: single idx 184 P=132464000 D=ffd70000 L=2100 DMA_FROM_DEVICE
[   21.647370] iwlagn 0000:03:00.0: single idx 184 P=132664000 D=ffb70000 L=2100 DMA_FROM_DEVICE
[   21.647372] iwlagn 0000:03:00.0: single idx 186 P=134660000 D=fff74000 L=2100 DMA_FROM_DEVICE
[   21.647374] iwlagn 0000:03:00.0: single idx 186 P=132460000 D=ffd74000 L=2100 DMA_FROM_DEVICE
[   21.647377] iwlagn 0000:03:00.0: single idx 186 P=132660000 D=ffb74000 L=2100 DMA_FROM_DEVICE
[   21.647379] iwlagn 0000:03:00.0: single idx 188 P=13465c000 D=fff78000 L=2100 DMA_FROM_DEVICE
[   21.647381] iwlagn 0000:03:00.0: single idx 188 P=13245c000 D=ffd78000 L=2100 DMA_FROM_DEVICE
[   21.647383] iwlagn 0000:03:00.0: single idx 188 P=13265c000 D=ffb78000 L=2100 DMA_FROM_DEVICE
[   21.647386] iwlagn 0000:03:00.0: single idx 190 P=134658000 D=fff7c000 L=2100 DMA_FROM_DEVICE
[   21.647388] iwlagn 0000:03:00.0: single idx 190 P=132458000 D=ffd7c000 L=2100 DMA_FROM_DEVICE
[   21.647390] iwlagn 0000:03:00.0: single idx 190 P=132658000 D=ffb7c000 L=2100 DMA_FROM_DEVICE
[   21.647392] iwlagn 0000:03:00.0: single idx 192 P=134654000 D=fff80000 L=2100 DMA_FROM_DEVICE
[   21.647394] iwlagn 0000:03:00.0: single idx 192 P=132454000 D=ffd80000 L=2100 DMA_FROM_DEVICE
[   21.647396] iwlagn 0000:03:00.0: single idx 192 P=132654000 D=ffb80000 L=2100 DMA_FROM_DEVICE
[   21.647399] iwlagn 0000:03:00.0: single idx 194 P=132450000 D=ffd84000 L=2100 DMA_FROM_DEVICE
[   21.647401] iwlagn 0000:03:00.0: single idx 194 P=132650000 D=ffb84000 L=2100 DMA_FROM_DEVICE
[   21.647403] iwlagn 0000:03:00.0: single idx 196 P=13244c000 D=ffd88000 L=2100 DMA_FROM_DEVICE
[   21.647405] iwlagn 0000:03:00.0: single idx 196 P=13264c000 D=ffb88000 L=2100 DMA_FROM_DEVICE
[   21.647408] iwlagn 0000:03:00.0: single idx 198 P=132448000 D=ffd8c000 L=2100 DMA_FROM_DEVICE
[   21.647410] iwlagn 0000:03:00.0: single idx 198 P=132648000 D=ffb8c000 L=2100 DMA_FROM_DEVICE
[   21.647412] iwlagn 0000:03:00.0: coherent idx 199 P=1345d4000 D=fff8f000 L=400 DMA_BIDIRECTIONAL
[   21.647414] iwlagn 0000:03:00.0: coherent idx 199 P=1345d3000 D=fff8e000 L=8 DMA_BIDIRECTIONAL
[   21.647417] iwlagn 0000:03:00.0: coherent idx 200 P=134640000 D=fff90000 L=c000 DMA_BIDIRECTIONAL
[   21.647419] iwlagn 0000:03:00.0: single idx 200 P=132444000 D=ffd90000 L=2100 DMA_FROM_DEVICE
[   21.647421] iwlagn 0000:03:00.0: single idx 200 P=132644000 D=ffb90000 L=2100 DMA_FROM_DEVICE
[   21.647423] iwlagn 0000:03:00.0: single idx 202 P=132440000 D=ffd94000 L=2100 DMA_FROM_DEVICE
[   21.647425] iwlagn 0000:03:00.0: single idx 202 P=132640000 D=ffb94000 L=2100 DMA_FROM_DEVICE
[   21.647428] iwlagn 0000:03:00.0: single idx 204 P=13243c000 D=ffd98000 L=2100 DMA_FROM_DEVICE
[   21.647430] iwlagn 0000:03:00.0: single idx 204 P=13263c000 D=ffb98000 L=2100 DMA_FROM_DEVICE
[   21.647432] iwlagn 0000:03:00.0: single idx 206 P=132438000 D=ffd9c000 L=2100 DMA_FROM_DEVICE
[   21.647434] iwlagn 0000:03:00.0: single idx 206 P=132638000 D=ffb9c000 L=2100 DMA_FROM_DEVICE
[   21.647436] iwlagn 0000:03:00.0: coherent idx 208 P=134620000 D=fffa0000 L=1cda0 DMA_BIDIRECTIONAL
[   21.647439] iwlagn 0000:03:00.0: single idx 208 P=132434000 D=ffda0000 L=2100 DMA_FROM_DEVICE
[   21.647441] iwlagn 0000:03:00.0: single idx 208 P=132634000 D=ffba0000 L=2100 DMA_FROM_DEVICE
[   21.647443] iwlagn 0000:03:00.0: single idx 210 P=132430000 D=ffda4000 L=2100 DMA_FROM_DEVICE
[   21.647445] iwlagn 0000:03:00.0: single idx 210 P=132630000 D=ffba4000 L=2100 DMA_FROM_DEVICE
[   21.647448] iwlagn 0000:03:00.0: single idx 212 P=13242c000 D=ffda8000 L=2100 DMA_FROM_DEVICE
[   21.647450] iwlagn 0000:03:00.0: single idx 212 P=13262c000 D=ffba8000 L=2100 DMA_FROM_DEVICE
[   21.647452] iwlagn 0000:03:00.0: single idx 214 P=132428000 D=ffdac000 L=2100 DMA_FROM_DEVICE
[   21.647454] iwlagn 0000:03:00.0: single idx 214 P=132628000 D=ffbac000 L=2100 DMA_FROM_DEVICE
[   21.647456] iwlagn 0000:03:00.0: single idx 216 P=132424000 D=ffdb0000 L=2100 DMA_FROM_DEVICE
[   21.647459] iwlagn 0000:03:00.0: single idx 216 P=132624000 D=ffbb0000 L=2100 DMA_FROM_DEVICE
[   21.647461] iwlagn 0000:03:00.0: single idx 218 P=132420000 D=ffdb4000 L=2100 DMA_FROM_DEVICE
[   21.647463] iwlagn 0000:03:00.0: single idx 218 P=132620000 D=ffbb4000 L=2100 DMA_FROM_DEVICE
[   21.647466] iwlagn 0000:03:00.0: single idx 220 P=13241c000 D=ffdb8000 L=2100 DMA_FROM_DEVICE
[   21.647468] iwlagn 0000:03:00.0: single idx 220 P=13261c000 D=ffbb8000 L=2100 DMA_FROM_DEVICE
[   21.647470] iwlagn 0000:03:00.0: single idx 222 P=132418000 D=ffdbc000 L=2100 DMA_FROM_DEVICE
[   21.647472] iwlagn 0000:03:00.0: single idx 222 P=132618000 D=ffbbc000 L=2100 DMA_FROM_DEVICE
[   21.647475] iwlagn 0000:03:00.0: coherent idx 224 P=134610000 D=fffc0000 L=c000 DMA_BIDIRECTIONAL
[   21.647477] iwlagn 0000:03:00.0: single idx 224 P=132414000 D=ffdc0000 L=2100 DMA_FROM_DEVICE
[   21.647479] iwlagn 0000:03:00.0: single idx 224 P=132614000 D=ffbc0000 L=2100 DMA_FROM_DEVICE
[   21.647482] iwlagn 0000:03:00.0: single idx 226 P=132410000 D=ffdc4000 L=2100 DMA_FROM_DEVICE
[   21.647484] iwlagn 0000:03:00.0: single idx 226 P=132610000 D=ffbc4000 L=2100 DMA_FROM_DEVICE
[   21.647486] iwlagn 0000:03:00.0: single idx 228 P=13240c000 D=ffdc8000 L=2100 DMA_FROM_DEVICE
[   21.647488] iwlagn 0000:03:00.0: single idx 228 P=13260c000 D=ffbc8000 L=2100 DMA_FROM_DEVICE
[   21.647491] iwlagn 0000:03:00.0: single idx 230 P=132408000 D=ffdcc000 L=2100 DMA_FROM_DEVICE
[   21.647493] iwlagn 0000:03:00.0: single idx 230 P=132608000 D=ffbcc000 L=2100 DMA_FROM_DEVICE
[   21.647495] iwlagn 0000:03:00.0: coherent idx 232 P=134600000 D=fffd0000 L=c000 DMA_BIDIRECTIONAL
[   21.647498] iwlagn 0000:03:00.0: single idx 232 P=132404000 D=ffdd0000 L=2100 DMA_FROM_DEVICE
[   21.647500] iwlagn 0000:03:00.0: single idx 232 P=132604000 D=ffbd0000 L=2100 DMA_FROM_DEVICE
[   21.647502] iwlagn 0000:03:00.0: single idx 234 P=132400000 D=ffdd4000 L=2100 DMA_FROM_DEVICE
[   21.647504] iwlagn 0000:03:00.0: single idx 234 P=132600000 D=ffbd4000 L=2100 DMA_FROM_DEVICE
[   21.647507] iwlagn 0000:03:00.0: single idx 236 P=1347fc000 D=ffdd8000 L=2100 DMA_FROM_DEVICE
[   21.647509] iwlagn 0000:03:00.0: single idx 236 P=1325fc000 D=ffbd8000 L=2100 DMA_FROM_DEVICE
[   21.647512] iwlagn 0000:03:00.0: single idx 238 P=1347f8000 D=ffddc000 L=2100 DMA_FROM_DEVICE
[   21.647514] iwlagn 0000:03:00.0: single idx 238 P=1325f8000 D=ffbdc000 L=2100 DMA_FROM_DEVICE
[   21.647516] iwlagn 0000:03:00.0: coherent idx 240 P=1345e0000 D=fffe0000 L=1f5f8 DMA_BIDIRECTIONAL
[   21.647518] iwlagn 0000:03:00.0: single idx 240 P=1347f4000 D=ffde0000 L=2100 DMA_FROM_DEVICE
[   21.647520] iwlagn 0000:03:00.0: single idx 240 P=1325f4000 D=ffbe0000 L=2100 DMA_FROM_DEVICE
[   21.647523] iwlagn 0000:03:00.0: coherent idx 240 P=132380000 D=ff9e0000 L=8000 DMA_BIDIRECTIONAL
[   21.647525] iwlagn 0000:03:00.0: single idx 242 P=1347f0000 D=ffde4000 L=2100 DMA_FROM_DEVICE
[   21.647527] iwlagn 0000:03:00.0: single idx 242 P=1325f0000 D=ffbe4000 L=2100 DMA_FROM_DEVICE
[   21.647530] iwlagn 0000:03:00.0: single idx 244 P=1347ec000 D=ffde8000 L=2100 DMA_FROM_DEVICE
[   21.647532] iwlagn 0000:03:00.0: single idx 244 P=1325ec000 D=ffbe8000 L=2100 DMA_FROM_DEVICE
[   21.647534] iwlagn 0000:03:00.0: coherent idx 244 P=132338000 D=ff9e8000 L=8000 DMA_BIDIRECTIONAL
[   21.647536] iwlagn 0000:03:00.0: single idx 246 P=1347e8000 D=ffdec000 L=2100 DMA_FROM_DEVICE
[   21.647538] iwlagn 0000:03:00.0: single idx 246 P=1325e8000 D=ffbec000 L=2100 DMA_FROM_DEVICE
[   21.647541] iwlagn 0000:03:00.0: single idx 248 P=1347e4000 D=ffdf0000 L=2100 DMA_FROM_DEVICE
[   21.647543] iwlagn 0000:03:00.0: single idx 248 P=1325e4000 D=ffbf0000 L=2100 DMA_FROM_DEVICE
[   21.647545] iwlagn 0000:03:00.0: coherent idx 248 P=132310000 D=ff9f0000 L=8000 DMA_BIDIRECTIONAL
[   21.647548] iwlagn 0000:03:00.0: single idx 250 P=1347e0000 D=ffdf4000 L=2100 DMA_FROM_DEVICE
[   21.647550] iwlagn 0000:03:00.0: single idx 250 P=1325e0000 D=ffbf4000 L=2100 DMA_FROM_DEVICE
[   21.647552] iwlagn 0000:03:00.0: single idx 252 P=1347dc000 D=ffdf8000 L=2100 DMA_FROM_DEVICE
[   21.647555] iwlagn 0000:03:00.0: single idx 252 P=1325dc000 D=ffbf8000 L=2100 DMA_FROM_DEVICE
[   21.647557] iwlagn 0000:03:00.0: coherent idx 252 P=1322c8000 D=ff9f8000 L=8000 DMA_BIDIRECTIONAL
[   21.647561] iwlagn 0000:03:00.0: single idx 254 P=1347d8000 D=ffdfc000 L=2100 DMA_FROM_DEVICE
[   21.647563] iwlagn 0000:03:00.0: single idx 254 P=1325d8000 D=ffbfc000 L=2100 DMA_FROM_DEVICE
[   21.647681] DMAR:[DMA Write] Request device [03:00.0] fault addr ff9dd000 
[   21.647682] DMAR:[fault reason 05] PTE Write access is not set
[   21.647684] iwlagn 0000:03:00.0: single idx 0 P=1347d4000 D=ffe00000 L=2100 DMA_FROM_DEVICE
[   21.647686] iwlagn 0000:03:00.0: single idx 0 P=1325d4000 D=ffc00000 L=2100 DMA_FROM_DEVICE
[   21.647688] iwlagn 0000:03:00.0: coherent idx 0 P=1322a0000 D=ffa00000 L=8000 DMA_BIDIRECTIONAL
[   21.647690] iwlagn 0000:03:00.0: single idx 2 P=1347d0000 D=ffe04000 L=2100 DMA_FROM_DEVICE
[   21.647692] iwlagn 0000:03:00.0: single idx 2 P=1325d0000 D=ffc04000 L=2100 DMA_FROM_DEVICE
[   21.647694] iwlagn 0000:03:00.0: single idx 4 P=1347cc000 D=ffe08000 L=2100 DMA_FROM_DEVICE
[   21.647696] iwlagn 0000:03:00.0: single idx 4 P=1325cc000 D=ffc08000 L=2100 DMA_FROM_DEVICE
[   21.647698] iwlagn 0000:03:00.0: coherent idx 4 P=132258000 D=ffa08000 L=8000 DMA_BIDIRECTIONAL
[   21.647700] iwlagn 0000:03:00.0: single idx 6 P=1347c8000 D=ffe0c000 L=2100 DMA_FROM_DEVICE
[   21.647701] iwlagn 0000:03:00.0: single idx 6 P=1325c8000 D=ffc0c000 L=2100 DMA_FROM_DEVICE
[   21.647703] iwlagn 0000:03:00.0: single idx 8 P=1347c4000 D=ffe10000 L=2100 DMA_FROM_DEVICE
[   21.647705] iwlagn 0000:03:00.0: single idx 8 P=1325c4000 D=ffc10000 L=2100 DMA_FROM_DEVICE
[   21.647707] iwlagn 0000:03:00.0: coherent idx 8 P=132230000 D=ffa10000 L=8000 DMA_BIDIRECTIONAL
[   21.647709] iwlagn 0000:03:00.0: single idx 10 P=1347c0000 D=ffe14000 L=2100 DMA_FROM_DEVICE
[   21.647711] iwlagn 0000:03:00.0: single idx 10 P=1325c0000 D=ffc14000 L=2100 DMA_FROM_DEVICE
[   21.647713] iwlagn 0000:03:00.0: single idx 12 P=1347bc000 D=ffe18000 L=2100 DMA_FROM_DEVICE
[   21.647715] iwlagn 0000:03:00.0: single idx 12 P=1325bc000 D=ffc18000 L=2100 DMA_FROM_DEVICE
[   21.647716] iwlagn 0000:03:00.0: coherent idx 12 P=1321e8000 D=ffa18000 L=8000 DMA_BIDIRECTIONAL
[   21.647718] iwlagn 0000:03:00.0: single idx 14 P=1347b8000 D=ffe1c000 L=2100 DMA_FROM_DEVICE
[   21.647720] iwlagn 0000:03:00.0: single idx 14 P=1325b8000 D=ffc1c000 L=2100 DMA_FROM_DEVICE
[   21.647722] iwlagn 0000:03:00.0: single idx 16 P=1347b4000 D=ffe20000 L=2100 DMA_FROM_DEVICE
[   21.647724] iwlagn 0000:03:00.0: single idx 16 P=1325b4000 D=ffc20000 L=2100 DMA_FROM_DEVICE
[   21.647726] iwlagn 0000:03:00.0: coherent idx 16 P=1321c0000 D=ffa20000 L=8000 DMA_BIDIRECTIONAL
[   21.647728] iwlagn 0000:03:00.0: single idx 18 P=1347b0000 D=ffe24000 L=2100 DMA_FROM_DEVICE
[   21.647730] iwlagn 0000:03:00.0: single idx 18 P=1325b0000 D=ffc24000 L=2100 DMA_FROM_DEVICE
[   21.647732] iwlagn 0000:03:00.0: single idx 20 P=1347ac000 D=ffe28000 L=2100 DMA_FROM_DEVICE
[   21.647733] iwlagn 0000:03:00.0: single idx 20 P=1325ac000 D=ffc28000 L=2100 DMA_FROM_DEVICE
[   21.647735] iwlagn 0000:03:00.0: coherent idx 20 P=132178000 D=ffa28000 L=8000 DMA_BIDIRECTIONAL
[   21.647737] iwlagn 0000:03:00.0: single idx 22 P=1347a8000 D=ffe2c000 L=2100 DMA_FROM_DEVICE
[   21.647739] iwlagn 0000:03:00.0: single idx 22 P=1325a8000 D=ffc2c000 L=2100 DMA_FROM_DEVICE
[   21.647741] iwlagn 0000:03:00.0: single idx 24 P=1347a4000 D=ffe30000 L=2100 DMA_FROM_DEVICE
[   21.647743] iwlagn 0000:03:00.0: single idx 24 P=1325a4000 D=ffc30000 L=2100 DMA_FROM_DEVICE
[   21.647745] iwlagn 0000:03:00.0: coherent idx 24 P=132150000 D=ffa30000 L=8000 DMA_BIDIRECTIONAL
[   21.647747] iwlagn 0000:03:00.0: single idx 26 P=1347a0000 D=ffe34000 L=2100 DMA_FROM_DEVICE
[   21.647749] iwlagn 0000:03:00.0: single idx 26 P=1325a0000 D=ffc34000 L=2100 DMA_FROM_DEVICE
[   21.647750] iwlagn 0000:03:00.0: single idx 28 P=13479c000 D=ffe38000 L=2100 DMA_FROM_DEVICE
[   21.647752] iwlagn 0000:03:00.0: single idx 28 P=13259c000 D=ffc38000 L=2100 DMA_FROM_DEVICE
[   21.647754] iwlagn 0000:03:00.0: coherent idx 28 P=132108000 D=ffa38000 L=8000 DMA_BIDIRECTIONAL
[   21.647756] iwlagn 0000:03:00.0: single idx 30 P=134798000 D=ffe3c000 L=2100 DMA_FROM_DEVICE
[   21.647758] iwlagn 0000:03:00.0: single idx 30 P=132598000 D=ffc3c000 L=2100 DMA_FROM_DEVICE
[   21.647760] iwlagn 0000:03:00.0: single idx 32 P=134794000 D=ffe40000 L=2100 DMA_FROM_DEVICE
[   21.647762] iwlagn 0000:03:00.0: single idx 32 P=132594000 D=ffc40000 L=2100 DMA_FROM_DEVICE
[   21.647764] iwlagn 0000:03:00.0: coherent idx 32 P=1320e0000 D=ffa40000 L=8000 DMA_BIDIRECTIONAL
[   21.647765] iwlagn 0000:03:00.0: single idx 34 P=134790000 D=ffe44000 L=2100 DMA_FROM_DEVICE
[   21.647767] iwlagn 0000:03:00.0: single idx 34 P=132590000 D=ffc44000 L=2100 DMA_FROM_DEVICE
[   21.647769] iwlagn 0000:03:00.0: single idx 36 P=13478c000 D=ffe48000 L=2100 DMA_FROM_DEVICE
[   21.647771] iwlagn 0000:03:00.0: single idx 36 P=13258c000 D=ffc48000 L=2100 DMA_FROM_DEVICE
[   21.647773] iwlagn 0000:03:00.0: coherent idx 36 P=132098000 D=ffa48000 L=8000 DMA_BIDIRECTIONAL
[   21.647775] iwlagn 0000:03:00.0: single idx 38 P=134788000 D=ffe4c000 L=2100 DMA_FROM_DEVICE
[   21.647777] iwlagn 0000:03:00.0: single idx 38 P=132588000 D=ffc4c000 L=2100 DMA_FROM_DEVICE
[   21.647779] iwlagn 0000:03:00.0: single idx 40 P=134784000 D=ffe50000 L=2100 DMA_FROM_DEVICE
[   21.647781] iwlagn 0000:03:00.0: single idx 40 P=132584000 D=ffc50000 L=2100 DMA_FROM_DEVICE
[   21.647782] iwlagn 0000:03:00.0: coherent idx 40 P=132070000 D=ffa50000 L=8000 DMA_BIDIRECTIONAL
[   21.647784] iwlagn 0000:03:00.0: single idx 42 P=134780000 D=ffe54000 L=2100 DMA_FROM_DEVICE
[   21.647786] iwlagn 0000:03:00.0: single idx 42 P=132580000 D=ffc54000 L=2100 DMA_FROM_DEVICE
[   21.647788] iwlagn 0000:03:00.0: single idx 44 P=13477c000 D=ffe58000 L=2100 DMA_FROM_DEVICE
[   21.647790] iwlagn 0000:03:00.0: single idx 44 P=13257c000 D=ffc58000 L=2100 DMA_FROM_DEVICE
[   21.647792] iwlagn 0000:03:00.0: coherent idx 44 P=132038000 D=ffa58000 L=8000 DMA_BIDIRECTIONAL
[   21.647794] iwlagn 0000:03:00.0: single idx 46 P=134778000 D=ffe5c000 L=2100 DMA_FROM_DEVICE
[   21.647796] iwlagn 0000:03:00.0: single idx 46 P=132578000 D=ffc5c000 L=2100 DMA_FROM_DEVICE
[   21.647797] iwlagn 0000:03:00.0: single idx 48 P=134774000 D=ffe60000 L=2100 DMA_FROM_DEVICE
[   21.647799] iwlagn 0000:03:00.0: single idx 48 P=132574000 D=ffc60000 L=2100 DMA_FROM_DEVICE
[   21.647801] iwlagn 0000:03:00.0: coherent idx 48 P=132018000 D=ffa60000 L=8000 DMA_BIDIRECTIONAL
[   21.647803] iwlagn 0000:03:00.0: single idx 50 P=134770000 D=ffe64000 L=2100 DMA_FROM_DEVICE
[   21.647805] iwlagn 0000:03:00.0: single idx 50 P=132570000 D=ffc64000 L=2100 DMA_FROM_DEVICE
[   21.647807] iwlagn 0000:03:00.0: single idx 52 P=13476c000 D=ffe68000 L=2100 DMA_FROM_DEVICE
[   21.647809] iwlagn 0000:03:00.0: single idx 52 P=13256c000 D=ffc68000 L=2100 DMA_FROM_DEVICE
[   21.647811] iwlagn 0000:03:00.0: coherent idx 52 P=1327f0000 D=ffa68000 L=8000 DMA_BIDIRECTIONAL
[   21.647812] iwlagn 0000:03:00.0: single idx 54 P=134768000 D=ffe6c000 L=2100 DMA_FROM_DEVICE
[   21.647814] iwlagn 0000:03:00.0: single idx 54 P=132568000 D=ffc6c000 L=2100 DMA_FROM_DEVICE
[   21.647816] iwlagn 0000:03:00.0: single idx 56 P=134764000 D=ffe70000 L=2100 DMA_FROM_DEVICE
[   21.647818] iwlagn 0000:03:00.0: single idx 56 P=132564000 D=ffc70000 L=2100 DMA_FROM_DEVICE
[   21.647820] iwlagn 0000:03:00.0: coherent idx 56 P=1327a8000 D=ffa70000 L=8000 DMA_BIDIRECTIONAL
[   21.647822] iwlagn 0000:03:00.0: single idx 58 P=134760000 D=ffe74000 L=2100 DMA_FROM_DEVICE
[   21.647824] iwlagn 0000:03:00.0: single idx 58 P=132560000 D=ffc74000 L=2100 DMA_FROM_DEVICE
[   21.647826] iwlagn 0000:03:00.0: single idx 60 P=13475c000 D=ffe78000 L=2100 DMA_FROM_DEVICE
[   21.647828] iwlagn 0000:03:00.0: single idx 60 P=13255c000 D=ffc78000 L=2100 DMA_FROM_DEVICE
[   21.647829] iwlagn 0000:03:00.0: coherent idx 60 P=132780000 D=ffa78000 L=8000 DMA_BIDIRECTIONAL
[   21.647831] iwlagn 0000:03:00.0: single idx 62 P=134758000 D=ffe7c000 L=2100 DMA_FROM_DEVICE
[   21.647833] iwlagn 0000:03:00.0: single idx 62 P=132558000 D=ffc7c000 L=2100 DMA_FROM_DEVICE
[   21.647841] iwlagn 0000:03:00.0: single idx 64 P=134754000 D=ffe80000 L=2100 DMA_FROM_DEVICE
[   21.647842] iwlagn 0000:03:00.0: single idx 64 P=132554000 D=ffc80000 L=2100 DMA_FROM_DEVICE
[   21.647844] iwlagn 0000:03:00.0: single idx 66 P=134750000 D=ffe84000 L=2100 DMA_FROM_DEVICE
[   21.647846] iwlagn 0000:03:00.0: single idx 66 P=132550000 D=ffc84000 L=2100 DMA_FROM_DEVICE
[   21.647848] iwlagn 0000:03:00.0: coherent idx 67 P=135027000 D=ffa87000 L=1000 DMA_BIDIRECTIONAL
[   21.647850] iwlagn 0000:03:00.0: single idx 68 P=13474c000 D=ffe88000 L=2100 DMA_FROM_DEVICE
[   21.647851] iwlagn 0000:03:00.0: single idx 68 P=13254c000 D=ffc88000 L=2100 DMA_FROM_DEVICE
[   21.647853] iwlagn 0000:03:00.0: coherent idx 68 P=13274c000 D=ffa88000 L=3200 DMA_BIDIRECTIONAL
[   21.647855] iwlagn 0000:03:00.0: single idx 70 P=134748000 D=ffe8c000 L=2100 DMA_FROM_DEVICE
[   21.647857] iwlagn 0000:03:00.0: single idx 70 P=132548000 D=ffc8c000 L=2100 DMA_FROM_DEVICE
[   21.647858] iwlagn 0000:03:00.0: single idx 70 P=132748000 D=ffa8c000 L=2100 DMA_FROM_DEVICE
[   21.647860] iwlagn 0000:03:00.0: single idx 72 P=134744000 D=ffe90000 L=2100 DMA_FROM_DEVICE
[   21.647862] iwlagn 0000:03:00.0: single idx 72 P=132544000 D=ffc90000 L=2100 DMA_FROM_DEVICE
[   21.647864] iwlagn 0000:03:00.0: single idx 72 P=132744000 D=ffa90000 L=2100 DMA_FROM_DEVICE
[   21.647866] iwlagn 0000:03:00.0: single idx 74 P=134740000 D=ffe94000 L=2100 DMA_FROM_DEVICE
[   21.647867] iwlagn 0000:03:00.0: single idx 74 P=132540000 D=ffc94000 L=2100 DMA_FROM_DEVICE
[   21.647869] iwlagn 0000:03:00.0: single idx 74 P=132740000 D=ffa94000 L=2100 DMA_FROM_DEVICE
[   21.647871] iwlagn 0000:03:00.0: single idx 76 P=13473c000 D=ffe98000 L=2100 DMA_FROM_DEVICE
[   21.647873] iwlagn 0000:03:00.0: single idx 76 P=13253c000 D=ffc98000 L=2100 DMA_FROM_DEVICE
[   21.647874] iwlagn 0000:03:00.0: single idx 76 P=13273c000 D=ffa98000 L=2100 DMA_FROM_DEVICE
[   21.647876] iwlagn 0000:03:00.0: single idx 78 P=134738000 D=ffe9c000 L=2100 DMA_FROM_DEVICE
[   21.647878] iwlagn 0000:03:00.0: single idx 78 P=132538000 D=ffc9c000 L=2100 DMA_FROM_DEVICE
[   21.647880] iwlagn 0000:03:00.0: single idx 78 P=132738000 D=ffa9c000 L=2100 DMA_FROM_DEVICE
[   21.647881] iwlagn 0000:03:00.0: single idx 80 P=134734000 D=ffea0000 L=2100 DMA_FROM_DEVICE
[   21.647883] iwlagn 0000:03:00.0: single idx 80 P=132534000 D=ffca0000 L=2100 DMA_FROM_DEVICE
[   21.647885] iwlagn 0000:03:00.0: single idx 80 P=132734000 D=ffaa0000 L=2100 DMA_FROM_DEVICE
[   21.647887] iwlagn 0000:03:00.0: single idx 82 P=134730000 D=ffea4000 L=2100 DMA_FROM_DEVICE
[   21.647888] iwlagn 0000:03:00.0: single idx 82 P=132530000 D=ffca4000 L=2100 DMA_FROM_DEVICE
[   21.647890] iwlagn 0000:03:00.0: single idx 82 P=132730000 D=ffaa4000 L=2100 DMA_FROM_DEVICE
[   21.647892] iwlagn 0000:03:00.0: single idx 84 P=13472c000 D=ffea8000 L=2100 DMA_FROM_DEVICE
[   21.647894] iwlagn 0000:03:00.0: single idx 84 P=13252c000 D=ffca8000 L=2100 DMA_FROM_DEVICE
[   21.647896] iwlagn 0000:03:00.0: single idx 84 P=13272c000 D=ffaa8000 L=2100 DMA_FROM_DEVICE
[   21.647897] iwlagn 0000:03:00.0: single idx 86 P=134728000 D=ffeac000 L=2100 DMA_FROM_DEVICE
[   21.647899] iwlagn 0000:03:00.0: single idx 86 P=132528000 D=ffcac000 L=2100 DMA_FROM_DEVICE
[   21.647901] iwlagn 0000:03:00.0: single idx 86 P=132728000 D=ffaac000 L=2100 DMA_FROM_DEVICE
[   21.647903] iwlagn 0000:03:00.0: single idx 88 P=134724000 D=ffeb0000 L=2100 DMA_FROM_DEVICE
[   21.647905] iwlagn 0000:03:00.0: single idx 88 P=132524000 D=ffcb0000 L=2100 DMA_FROM_DEVICE
[   21.647906] iwlagn 0000:03:00.0: single idx 88 P=132724000 D=ffab0000 L=2100 DMA_FROM_DEVICE
[   21.647908] iwlagn 0000:03:00.0: single idx 90 P=134720000 D=ffeb4000 L=2100 DMA_FROM_DEVICE
[   21.647910] iwlagn 0000:03:00.0: single idx 90 P=132520000 D=ffcb4000 L=2100 DMA_FROM_DEVICE
[   21.647912] iwlagn 0000:03:00.0: single idx 90 P=132720000 D=ffab4000 L=2100 DMA_FROM_DEVICE
[   21.647913] iwlagn 0000:03:00.0: single idx 92 P=13471c000 D=ffeb8000 L=2100 DMA_FROM_DEVICE
[   21.647915] iwlagn 0000:03:00.0: single idx 92 P=13251c000 D=ffcb8000 L=2100 DMA_FROM_DEVICE
[   21.647917] iwlagn 0000:03:00.0: single idx 92 P=13271c000 D=ffab8000 L=2100 DMA_FROM_DEVICE
[   21.647919] iwlagn 0000:03:00.0: single idx 94 P=134718000 D=ffebc000 L=2100 DMA_FROM_DEVICE
[   21.647920] iwlagn 0000:03:00.0: single idx 94 P=132518000 D=ffcbc000 L=2100 DMA_FROM_DEVICE
[   21.647922] iwlagn 0000:03:00.0: single idx 94 P=132718000 D=ffabc000 L=2100 DMA_FROM_DEVICE
[   21.647924] iwlagn 0000:03:00.0: single idx 96 P=134714000 D=ffec0000 L=2100 DMA_FROM_DEVICE
[   21.647926] iwlagn 0000:03:00.0: single idx 96 P=132514000 D=ffcc0000 L=2100 DMA_FROM_DEVICE
[   21.647927] iwlagn 0000:03:00.0: single idx 96 P=132714000 D=ffac0000 L=2100 DMA_FROM_DEVICE
[   21.647929] iwlagn 0000:03:00.0: single idx 98 P=134710000 D=ffec4000 L=2100 DMA_FROM_DEVICE
[   21.647931] iwlagn 0000:03:00.0: single idx 98 P=132510000 D=ffcc4000 L=2100 DMA_FROM_DEVICE
[   21.647933] iwlagn 0000:03:00.0: single idx 98 P=132710000 D=ffac4000 L=2100 DMA_FROM_DEVICE
[   21.647935] iwlagn 0000:03:00.0: single idx 100 P=13470c000 D=ffec8000 L=2100 DMA_FROM_DEVICE
[   21.647936] iwlagn 0000:03:00.0: single idx 100 P=13250c000 D=ffcc8000 L=2100 DMA_FROM_DEVICE
[   21.647938] iwlagn 0000:03:00.0: single idx 100 P=13270c000 D=ffac8000 L=2100 DMA_FROM_DEVICE
[   21.647940] iwlagn 0000:03:00.0: single idx 102 P=134708000 D=ffecc000 L=2100 DMA_FROM_DEVICE
[   21.647942] iwlagn 0000:03:00.0: single idx 102 P=132508000 D=ffccc000 L=2100 DMA_FROM_DEVICE
[   21.647943] iwlagn 0000:03:00.0: single idx 102 P=132708000 D=ffacc000 L=2100 DMA_FROM_DEVICE
[   21.647945] iwlagn 0000:03:00.0: single idx 104 P=134704000 D=ffed0000 L=2100 DMA_FROM_DEVICE
[   21.647947] iwlagn 0000:03:00.0: single idx 104 P=132504000 D=ffcd0000 L=2100 DMA_FROM_DEVICE
[   21.647949] iwlagn 0000:03:00.0: single idx 104 P=132704000 D=ffad0000 L=2100 DMA_FROM_DEVICE
[   21.647951] iwlagn 0000:03:00.0: single idx 106 P=134700000 D=ffed4000 L=2100 DMA_FROM_DEVICE
[   21.647952] iwlagn 0000:03:00.0: single idx 106 P=132500000 D=ffcd4000 L=2100 DMA_FROM_DEVICE
[   21.647954] iwlagn 0000:03:00.0: single idx 106 P=132700000 D=ffad4000 L=2100 DMA_FROM_DEVICE
[   21.647956] iwlagn 0000:03:00.0: single idx 108 P=1346fc000 D=ffed8000 L=2100 DMA_FROM_DEVICE
[   21.647958] iwlagn 0000:03:00.0: single idx 108 P=1324fc000 D=ffcd8000 L=2100 DMA_FROM_DEVICE
[   21.647959] iwlagn 0000:03:00.0: single idx 108 P=1326fc000 D=ffad8000 L=2100 DMA_FROM_DEVICE
[   21.647961] iwlagn 0000:03:00.0: single idx 110 P=1346f8000 D=ffedc000 L=2100 DMA_FROM_DEVICE
[   21.647963] iwlagn 0000:03:00.0: single idx 110 P=1324f8000 D=ffcdc000 L=2100 DMA_FROM_DEVICE
[   21.647965] iwlagn 0000:03:00.0: single idx 110 P=1326f8000 D=ffadc000 L=2100 DMA_FROM_DEVICE
[   21.647967] iwlagn 0000:03:00.0: single idx 112 P=1346f4000 D=ffee0000 L=2100 DMA_FROM_DEVICE
[   21.647968] iwlagn 0000:03:00.0: single idx 112 P=1324f4000 D=ffce0000 L=2100 DMA_FROM_DEVICE
[   21.647970] iwlagn 0000:03:00.0: single idx 112 P=1326f4000 D=ffae0000 L=2100 DMA_FROM_DEVICE
[   21.647972] iwlagn 0000:03:00.0: single idx 114 P=1346f0000 D=ffee4000 L=2100 DMA_FROM_DEVICE
[   21.647974] iwlagn 0000:03:00.0: single idx 114 P=1324f0000 D=ffce4000 L=2100 DMA_FROM_DEVICE
[   21.647976] iwlagn 0000:03:00.0: single idx 114 P=1326f0000 D=ffae4000 L=2100 DMA_FROM_DEVICE
[   21.647977] iwlagn 0000:03:00.0: single idx 116 P=1346ec000 D=ffee8000 L=2100 DMA_FROM_DEVICE
[   21.647979] iwlagn 0000:03:00.0: single idx 116 P=1324ec000 D=ffce8000 L=2100 DMA_FROM_DEVICE
[   21.647981] iwlagn 0000:03:00.0: single idx 116 P=1326ec000 D=ffae8000 L=2100 DMA_FROM_DEVICE
[   21.647983] iwlagn 0000:03:00.0: single idx 118 P=1346e8000 D=ffeec000 L=2100 DMA_FROM_DEVICE
[   21.647985] iwlagn 0000:03:00.0: single idx 118 P=1324e8000 D=ffcec000 L=2100 DMA_FROM_DEVICE
[   21.647987] iwlagn 0000:03:00.0: single idx 118 P=1326e8000 D=ffaec000 L=2100 DMA_FROM_DEVICE
[   21.647989] iwlagn 0000:03:00.0: single idx 120 P=1346e4000 D=ffef0000 L=2100 DMA_FROM_DEVICE
[   21.647990] iwlagn 0000:03:00.0: single idx 120 P=1324e4000 D=ffcf0000 L=2100 DMA_FROM_DEVICE
[   21.647992] iwlagn 0000:03:00.0: single idx 120 P=1326e4000 D=ffaf0000 L=2100 DMA_FROM_DEVICE
[   21.647994] iwlagn 0000:03:00.0: single idx 122 P=1346e0000 D=ffef4000 L=2100 DMA_FROM_DEVICE
[   21.647996] iwlagn 0000:03:00.0: single idx 122 P=1324e0000 D=ffcf4000 L=2100 DMA_FROM_DEVICE
[   21.647998] iwlagn 0000:03:00.0: single idx 122 P=1326e0000 D=ffaf4000 L=2100 DMA_FROM_DEVICE
[   21.648000] iwlagn 0000:03:00.0: single idx 124 P=1346dc000 D=ffef8000 L=2100 DMA_FROM_DEVICE
[   21.648001] iwlagn 0000:03:00.0: single idx 124 P=1324dc000 D=ffcf8000 L=2100 DMA_FROM_DEVICE
[   21.648003] iwlagn 0000:03:00.0: single idx 124 P=1326dc000 D=ffaf8000 L=2100 DMA_FROM_DEVICE
[   21.648007] iwlagn 0000:03:00.0: single idx 126 P=1346d8000 D=ffefc000 L=2100 DMA_FROM_DEVICE
[   21.648009] iwlagn 0000:03:00.0: single idx 126 P=1324d8000 D=ffcfc000 L=2100 DMA_FROM_DEVICE
[   21.648011] iwlagn 0000:03:00.0: single idx 126 P=1326d8000 D=ffafc000 L=2100 DMA_FROM_DEVICE
[   21.648012] iwlagn 0000:03:00.0: single idx 128 P=1346d4000 D=fff00000 L=2100 DMA_FROM_DEVICE
[   21.648014] iwlagn 0000:03:00.0: single idx 128 P=1324d4000 D=ffd00000 L=2100 DMA_FROM_DEVICE
[   21.648023] iwlagn 0000:03:00.0: single idx 128 P=1326d4000 D=ffb00000 L=2100 DMA_FROM_DEVICE
[   21.648025] iwlagn 0000:03:00.0: single idx 130 P=1346d0000 D=fff04000 L=2100 DMA_FROM_DEVICE
[   21.648027] iwlagn 0000:03:00.0: single idx 130 P=1324d0000 D=ffd04000 L=2100 DMA_FROM_DEVICE
[   21.648029] iwlagn 0000:03:00.0: single idx 130 P=1326d0000 D=ffb04000 L=2100 DMA_FROM_DEVICE
[   21.648031] iwlagn 0000:03:00.0: single idx 132 P=1346cc000 D=fff08000 L=2100 DMA_FROM_DEVICE
[   21.648033] iwlagn 0000:03:00.0: single idx 132 P=1324cc000 D=ffd08000 L=2100 DMA_FROM_DEVICE
[   21.648035] iwlagn 0000:03:00.0: single idx 132 P=1326cc000 D=ffb08000 L=2100 DMA_FROM_DEVICE
[   21.648037] iwlagn 0000:03:00.0: single idx 134 P=1346c8000 D=fff0c000 L=2100 DMA_FROM_DEVICE
[   21.648039] iwlagn 0000:03:00.0: single idx 134 P=1324c8000 D=ffd0c000 L=2100 DMA_FROM_DEVICE
[   21.648041] iwlagn 0000:03:00.0: single idx 134 P=1326c8000 D=ffb0c000 L=2100 DMA_FROM_DEVICE
[   21.648043] iwlagn 0000:03:00.0: single idx 136 P=1346c4000 D=fff10000 L=2100 DMA_FROM_DEVICE
[   21.648045] iwlagn 0000:03:00.0: single idx 136 P=1324c4000 D=ffd10000 L=2100 DMA_FROM_DEVICE
[   21.648047] iwlagn 0000:03:00.0: single idx 136 P=1326c4000 D=ffb10000 L=2100 DMA_FROM_DEVICE
[   21.648049] iwlagn 0000:03:00.0: single idx 138 P=1346c0000 D=fff14000 L=2100 DMA_FROM_DEVICE
[   21.648051] iwlagn 0000:03:00.0: single idx 138 P=1324c0000 D=ffd14000 L=2100 DMA_FROM_DEVICE
[   21.648053] iwlagn 0000:03:00.0: single idx 138 P=1326c0000 D=ffb14000 L=2100 DMA_FROM_DEVICE
[   21.648055] iwlagn 0000:03:00.0: single idx 140 P=1346bc000 D=fff18000 L=2100 DMA_FROM_DEVICE
[   21.648057] iwlagn 0000:03:00.0: single idx 140 P=1324bc000 D=ffd18000 L=2100 DMA_FROM_DEVICE
[   21.648059] iwlagn 0000:03:00.0: single idx 140 P=1326bc000 D=ffb18000 L=2100 DMA_FROM_DEVICE
[   21.648061] iwlagn 0000:03:00.0: single idx 142 P=1346b8000 D=fff1c000 L=2100 DMA_FROM_DEVICE
[   21.648062] iwlagn 0000:03:00.0: single idx 142 P=1324b8000 D=ffd1c000 L=2100 DMA_FROM_DEVICE
[   21.648064] iwlagn 0000:03:00.0: single idx 142 P=1326b8000 D=ffb1c000 L=2100 DMA_FROM_DEVICE
[   21.648066] iwlagn 0000:03:00.0: single idx 144 P=1346b4000 D=fff20000 L=2100 DMA_FROM_DEVICE
[   21.648068] iwlagn 0000:03:00.0: single idx 144 P=1324b4000 D=ffd20000 L=2100 DMA_FROM_DEVICE
[   21.648070] iwlagn 0000:03:00.0: single idx 144 P=1326b4000 D=ffb20000 L=2100 DMA_FROM_DEVICE
[   21.648072] iwlagn 0000:03:00.0: single idx 146 P=1346b0000 D=fff24000 L=2100 DMA_FROM_DEVICE
[   21.648074] iwlagn 0000:03:00.0: single idx 146 P=1324b0000 D=ffd24000 L=2100 DMA_FROM_DEVICE
[   21.648076] iwlagn 0000:03:00.0: single idx 146 P=1326b0000 D=ffb24000 L=2100 DMA_FROM_DEVICE
[   21.648078] iwlagn 0000:03:00.0: single idx 148 P=1346ac000 D=fff28000 L=2100 DMA_FROM_DEVICE
[   21.648080] iwlagn 0000:03:00.0: single idx 148 P=1324ac000 D=ffd28000 L=2100 DMA_FROM_DEVICE
[   21.648082] iwlagn 0000:03:00.0: single idx 148 P=1326ac000 D=ffb28000 L=2100 DMA_FROM_DEVICE
[   21.648084] iwlagn 0000:03:00.0: single idx 150 P=1346a8000 D=fff2c000 L=2100 DMA_FROM_DEVICE
[   21.648086] iwlagn 0000:03:00.0: single idx 150 P=1324a8000 D=ffd2c000 L=2100 DMA_FROM_DEVICE
[   21.648088] iwlagn 0000:03:00.0: single idx 150 P=1326a8000 D=ffb2c000 L=2100 DMA_FROM_DEVICE
[   21.648090] iwlagn 0000:03:00.0: single idx 152 P=1346a4000 D=fff30000 L=2100 DMA_FROM_DEVICE
[   21.648092] iwlagn 0000:03:00.0: single idx 152 P=1324a4000 D=ffd30000 L=2100 DMA_FROM_DEVICE
[   21.648094] iwlagn 0000:03:00.0: single idx 152 P=1326a4000 D=ffb30000 L=2100 DMA_FROM_DEVICE
[   21.648096] iwlagn 0000:03:00.0: single idx 154 P=1346a0000 D=fff34000 L=2100 DMA_FROM_DEVICE
[   21.648097] iwlagn 0000:03:00.0: single idx 154 P=1324a0000 D=ffd34000 L=2100 DMA_FROM_DEVICE
[   21.648099] iwlagn 0000:03:00.0: single idx 154 P=1326a0000 D=ffb34000 L=2100 DMA_FROM_DEVICE
[   21.648101] iwlagn 0000:03:00.0: single idx 156 P=13469c000 D=fff38000 L=2100 DMA_FROM_DEVICE
[   21.648103] iwlagn 0000:03:00.0: single idx 156 P=13249c000 D=ffd38000 L=2100 DMA_FROM_DEVICE
[   21.648105] iwlagn 0000:03:00.0: single idx 156 P=13269c000 D=ffb38000 L=2100 DMA_FROM_DEVICE
[   21.648107] iwlagn 0000:03:00.0: single idx 158 P=134698000 D=fff3c000 L=2100 DMA_FROM_DEVICE
[   21.648109] iwlagn 0000:03:00.0: single idx 158 P=132498000 D=ffd3c000 L=2100 DMA_FROM_DEVICE
[   21.648111] iwlagn 0000:03:00.0: single idx 158 P=132698000 D=ffb3c000 L=2100 DMA_FROM_DEVICE
[   21.648113] iwlagn 0000:03:00.0: single idx 160 P=134694000 D=fff40000 L=2100 DMA_FROM_DEVICE
[   21.648115] iwlagn 0000:03:00.0: single idx 160 P=132494000 D=ffd40000 L=2100 DMA_FROM_DEVICE
[   21.648117] iwlagn 0000:03:00.0: single idx 160 P=132694000 D=ffb40000 L=2100 DMA_FROM_DEVICE
[   21.648119] iwlagn 0000:03:00.0: single idx 162 P=134690000 D=fff44000 L=2100 DMA_FROM_DEVICE
[   21.648121] iwlagn 0000:03:00.0: single idx 162 P=132490000 D=ffd44000 L=2100 DMA_FROM_DEVICE
[   21.648123] iwlagn 0000:03:00.0: single idx 162 P=132690000 D=ffb44000 L=2100 DMA_FROM_DEVICE
[   21.648125] iwlagn 0000:03:00.0: single idx 164 P=13468c000 D=fff48000 L=2100 DMA_FROM_DEVICE
[   21.648127] iwlagn 0000:03:00.0: single idx 164 P=13248c000 D=ffd48000 L=2100 DMA_FROM_DEVICE
[   21.648128] iwlagn 0000:03:00.0: single idx 164 P=13268c000 D=ffb48000 L=2100 DMA_FROM_DEVICE
[   21.648137] iwlagn 0000:03:00.0: single idx 166 P=134688000 D=fff4c000 L=2100 DMA_FROM_DEVICE
[   21.648139] iwlagn 0000:03:00.0: single idx 166 P=132488000 D=ffd4c000 L=2100 DMA_FROM_DEVICE
[   21.648141] iwlagn 0000:03:00.0: single idx 166 P=132688000 D=ffb4c000 L=2100 DMA_FROM_DEVICE
[   21.648143] iwlagn 0000:03:00.0: single idx 168 P=134684000 D=fff50000 L=2100 DMA_FROM_DEVICE
[   21.648145] iwlagn 0000:03:00.0: single idx 168 P=132484000 D=ffd50000 L=2100 DMA_FROM_DEVICE
[   21.648147] iwlagn 0000:03:00.0: single idx 168 P=132684000 D=ffb50000 L=2100 DMA_FROM_DEVICE
[   21.648149] iwlagn 0000:03:00.0: single idx 170 P=134680000 D=fff54000 L=2100 DMA_FROM_DEVICE
[   21.648151] iwlagn 0000:03:00.0: single idx 170 P=132480000 D=ffd54000 L=2100 DMA_FROM_DEVICE
[   21.648153] iwlagn 0000:03:00.0: single idx 170 P=132680000 D=ffb54000 L=2100 DMA_FROM_DEVICE
[   21.648155] iwlagn 0000:03:00.0: single idx 172 P=13467c000 D=fff58000 L=2100 DMA_FROM_DEVICE
[   21.648157] iwlagn 0000:03:00.0: single idx 172 P=13247c000 D=ffd58000 L=2100 DMA_FROM_DEVICE
[   21.648159] iwlagn 0000:03:00.0: single idx 172 P=13267c000 D=ffb58000 L=2100 DMA_FROM_DEVICE
[   21.648161] iwlagn 0000:03:00.0: single idx 174 P=134678000 D=fff5c000 L=2100 DMA_FROM_DEVICE
[   21.648163] iwlagn 0000:03:00.0: single idx 174 P=132478000 D=ffd5c000 L=2100 DMA_FROM_DEVICE
[   21.648165] iwlagn 0000:03:00.0: single idx 174 P=132678000 D=ffb5c000 L=2100 DMA_FROM_DEVICE
[   21.648167] iwlagn 0000:03:00.0: single idx 176 P=134674000 D=fff60000 L=2100 DMA_FROM_DEVICE
[   21.648168] iwlagn 0000:03:00.0: single idx 176 P=132474000 D=ffd60000 L=2100 DMA_FROM_DEVICE
[   21.648170] iwlagn 0000:03:00.0: single idx 176 P=132674000 D=ffb60000 L=2100 DMA_FROM_DEVICE
[   21.648172] iwlagn 0000:03:00.0: single idx 178 P=134670000 D=fff64000 L=2100 DMA_FROM_DEVICE
[   21.648174] iwlagn 0000:03:00.0: single idx 178 P=132470000 D=ffd64000 L=2100 DMA_FROM_DEVICE
[   21.648176] iwlagn 0000:03:00.0: single idx 178 P=132670000 D=ffb64000 L=2100 DMA_FROM_DEVICE
[   21.648178] iwlagn 0000:03:00.0: single idx 180 P=13466c000 D=fff68000 L=2100 DMA_FROM_DEVICE
[   21.648180] iwlagn 0000:03:00.0: single idx 180 P=13246c000 D=ffd68000 L=2100 DMA_FROM_DEVICE
[   21.648182] iwlagn 0000:03:00.0: single idx 180 P=13266c000 D=ffb68000 L=2100 DMA_FROM_DEVICE
[   21.648190] iwlagn 0000:03:00.0: single idx 182 P=134668000 D=fff6c000 L=2100 DMA_FROM_DEVICE
[   21.648191] iwlagn 0000:03:00.0: single idx 182 P=132468000 D=ffd6c000 L=2100 DMA_FROM_DEVICE
[   21.648193] iwlagn 0000:03:00.0: single idx 182 P=132668000 D=ffb6c000 L=2100 DMA_FROM_DEVICE
[   21.648195] iwlagn 0000:03:00.0: single idx 184 P=134664000 D=fff70000 L=2100 DMA_FROM_DEVICE
[   21.648197] iwlagn 0000:03:00.0: single idx 184 P=132464000 D=ffd70000 L=2100 DMA_FROM_DEVICE
[   21.648199] iwlagn 0000:03:00.0: single idx 184 P=132664000 D=ffb70000 L=2100 DMA_FROM_DEVICE
[   21.648201] iwlagn 0000:03:00.0: single idx 186 P=134660000 D=fff74000 L=2100 DMA_FROM_DEVICE
[   21.648202] iwlagn 0000:03:00.0: single idx 186 P=132460000 D=ffd74000 L=2100 DMA_FROM_DEVICE
[   21.648204] iwlagn 0000:03:00.0: single idx 186 P=132660000 D=ffb74000 L=2100 DMA_FROM_DEVICE
[   21.648206] iwlagn 0000:03:00.0: single idx 188 P=13465c000 D=fff78000 L=2100 DMA_FROM_DEVICE
[   21.648208] iwlagn 0000:03:00.0: single idx 188 P=13245c000 D=ffd78000 L=2100 DMA_FROM_DEVICE
[   21.648210] iwlagn 0000:03:00.0: single idx 188 P=13265c000 D=ffb78000 L=2100 DMA_FROM_DEVICE
[   21.648212] iwlagn 0000:03:00.0: single idx 190 P=132458000 D=ffd7c000 L=2100 DMA_FROM_DEVICE
[   21.648214] iwlagn 0000:03:00.0: single idx 190 P=132658000 D=ffb7c000 L=2100 DMA_FROM_DEVICE
[   21.648215] iwlagn 0000:03:00.0: single idx 192 P=132454000 D=ffd80000 L=2100 DMA_FROM_DEVICE
[   21.648217] iwlagn 0000:03:00.0: single idx 192 P=132654000 D=ffb80000 L=2100 DMA_FROM_DEVICE
[   21.648219] iwlagn 0000:03:00.0: single idx 194 P=132450000 D=ffd84000 L=2100 DMA_FROM_DEVICE
[   21.648221] iwlagn 0000:03:00.0: single idx 194 P=132650000 D=ffb84000 L=2100 DMA_FROM_DEVICE
[   21.648223] iwlagn 0000:03:00.0: single idx 196 P=13244c000 D=ffd88000 L=2100 DMA_FROM_DEVICE
[   21.648225] iwlagn 0000:03:00.0: single idx 196 P=13264c000 D=ffb88000 L=2100 DMA_FROM_DEVICE
[   21.648227] iwlagn 0000:03:00.0: single idx 198 P=132448000 D=ffd8c000 L=2100 DMA_FROM_DEVICE
[   21.648228] iwlagn 0000:03:00.0: single idx 198 P=132648000 D=ffb8c000 L=2100 DMA_FROM_DEVICE
[   21.648230] iwlagn 0000:03:00.0: coherent idx 199 P=1345d4000 D=fff8f000 L=400 DMA_BIDIRECTIONAL
[   21.648232] iwlagn 0000:03:00.0: coherent idx 199 P=1345d3000 D=fff8e000 L=8 DMA_BIDIRECTIONAL
[   21.648234] iwlagn 0000:03:00.0: coherent idx 200 P=134640000 D=fff90000 L=c000 DMA_BIDIRECTIONAL
[   21.648236] iwlagn 0000:03:00.0: single idx 200 P=132444000 D=ffd90000 L=2100 DMA_FROM_DEVICE
[   21.648238] iwlagn 0000:03:00.0: single idx 200 P=132644000 D=ffb90000 L=2100 DMA_FROM_DEVICE
[   21.648240] iwlagn 0000:03:00.0: single idx 202 P=132440000 D=ffd94000 L=2100 DMA_FROM_DEVICE
[   21.648242] iwlagn 0000:03:00.0: single idx 202 P=132640000 D=ffb94000 L=2100 DMA_FROM_DEVICE
[   21.648243] iwlagn 0000:03:00.0: single idx 204 P=13243c000 D=ffd98000 L=2100 DMA_FROM_DEVICE
[   21.648245] iwlagn 0000:03:00.0: single idx 204 P=13263c000 D=ffb98000 L=2100 DMA_FROM_DEVICE
[   21.648247] iwlagn 0000:03:00.0: single idx 206 P=132438000 D=ffd9c000 L=2100 DMA_FROM_DEVICE
[   21.648249] iwlagn 0000:03:00.0: single idx 206 P=132638000 D=ffb9c000 L=2100 DMA_FROM_DEVICE
[   21.648251] iwlagn 0000:03:00.0: coherent idx 208 P=134620000 D=fffa0000 L=1cda0 DMA_BIDIRECTIONAL
[   21.648253] iwlagn 0000:03:00.0: single idx 208 P=132434000 D=ffda0000 L=2100 DMA_FROM_DEVICE
[   21.648255] iwlagn 0000:03:00.0: single idx 208 P=132634000 D=ffba0000 L=2100 DMA_FROM_DEVICE
[   21.648256] iwlagn 0000:03:00.0: single idx 210 P=132430000 D=ffda4000 L=2100 DMA_FROM_DEVICE
[   21.648258] iwlagn 0000:03:00.0: single idx 210 P=132630000 D=ffba4000 L=2100 DMA_FROM_DEVICE
[   21.648260] iwlagn 0000:03:00.0: single idx 212 P=13242c000 D=ffda8000 L=2100 DMA_FROM_DEVICE
[   21.648262] iwlagn 0000:03:00.0: single idx 212 P=13262c000 D=ffba8000 L=2100 DMA_FROM_DEVICE
[   21.648264] iwlagn 0000:03:00.0: single idx 214 P=132428000 D=ffdac000 L=2100 DMA_FROM_DEVICE
[   21.648266] iwlagn 0000:03:00.0: single idx 214 P=132628000 D=ffbac000 L=2100 DMA_FROM_DEVICE
[   21.648268] iwlagn 0000:03:00.0: single idx 216 P=132424000 D=ffdb0000 L=2100 DMA_FROM_DEVICE
[   21.648269] iwlagn 0000:03:00.0: single idx 216 P=132624000 D=ffbb0000 L=2100 DMA_FROM_DEVICE
[   21.648271] iwlagn 0000:03:00.0: single idx 218 P=132420000 D=ffdb4000 L=2100 DMA_FROM_DEVICE
[   21.648273] iwlagn 0000:03:00.0: single idx 218 P=132620000 D=ffbb4000 L=2100 DMA_FROM_DEVICE
[   21.648275] iwlagn 0000:03:00.0: single idx 220 P=13241c000 D=ffdb8000 L=2100 DMA_FROM_DEVICE
[   21.648277] iwlagn 0000:03:00.0: single idx 220 P=13261c000 D=ffbb8000 L=2100 DMA_FROM_DEVICE
[   21.648279] iwlagn 0000:03:00.0: single idx 222 P=132418000 D=ffdbc000 L=2100 DMA_FROM_DEVICE
[   21.648281] iwlagn 0000:03:00.0: single idx 222 P=132618000 D=ffbbc000 L=2100 DMA_FROM_DEVICE
[   21.648283] iwlagn 0000:03:00.0: coherent idx 224 P=134610000 D=fffc0000 L=c000 DMA_BIDIRECTIONAL
[   21.648284] iwlagn 0000:03:00.0: single idx 224 P=132414000 D=ffdc0000 L=2100 DMA_FROM_DEVICE
[   21.648286] iwlagn 0000:03:00.0: single idx 224 P=132614000 D=ffbc0000 L=2100 DMA_FROM_DEVICE
[   21.648288] iwlagn 0000:03:00.0: single idx 226 P=132410000 D=ffdc4000 L=2100 DMA_FROM_DEVICE
[   21.648290] iwlagn 0000:03:00.0: single idx 226 P=132610000 D=ffbc4000 L=2100 DMA_FROM_DEVICE
[   21.648292] iwlagn 0000:03:00.0: single idx 228 P=13240c000 D=ffdc8000 L=2100 DMA_FROM_DEVICE
[   21.648294] iwlagn 0000:03:00.0: single idx 228 P=13260c000 D=ffbc8000 L=2100 DMA_FROM_DEVICE
[   21.648296] iwlagn 0000:03:00.0: single idx 230 P=132408000 D=ffdcc000 L=2100 DMA_FROM_DEVICE
[   21.648297] iwlagn 0000:03:00.0: single idx 230 P=132608000 D=ffbcc000 L=2100 DMA_FROM_DEVICE
[   21.648299] iwlagn 0000:03:00.0: coherent idx 232 P=134600000 D=fffd0000 L=c000 DMA_BIDIRECTIONAL
[   21.648301] iwlagn 0000:03:00.0: single idx 232 P=132404000 D=ffdd0000 L=2100 DMA_FROM_DEVICE
[   21.648303] iwlagn 0000:03:00.0: single idx 232 P=132604000 D=ffbd0000 L=2100 DMA_FROM_DEVICE
[   21.648305] iwlagn 0000:03:00.0: single idx 234 P=132400000 D=ffdd4000 L=2100 DMA_FROM_DEVICE
[   21.648307] iwlagn 0000:03:00.0: single idx 234 P=132600000 D=ffbd4000 L=2100 DMA_FROM_DEVICE
[   21.648309] iwlagn 0000:03:00.0: single idx 236 P=1347fc000 D=ffdd8000 L=2100 DMA_FROM_DEVICE
[   21.648311] iwlagn 0000:03:00.0: single idx 236 P=1325fc000 D=ffbd8000 L=2100 DMA_FROM_DEVICE
[   21.648312] iwlagn 0000:03:00.0: single idx 238 P=1347f8000 D=ffddc000 L=2100 DMA_FROM_DEVICE
[   21.648314] iwlagn 0000:03:00.0: single idx 238 P=1325f8000 D=ffbdc000 L=2100 DMA_FROM_DEVICE
[   21.648316] iwlagn 0000:03:00.0: coherent idx 240 P=1345e0000 D=fffe0000 L=1f5f8 DMA_BIDIRECTIONAL
[   21.648318] iwlagn 0000:03:00.0: single idx 240 P=1347f4000 D=ffde0000 L=2100 DMA_FROM_DEVICE
[   21.648320] iwlagn 0000:03:00.0: single idx 240 P=1325f4000 D=ffbe0000 L=2100 DMA_FROM_DEVICE
[   21.648322] iwlagn 0000:03:00.0: coherent idx 240 P=132380000 D=ff9e0000 L=8000 DMA_BIDIRECTIONAL
[   21.648324] iwlagn 0000:03:00.0: single idx 242 P=1347f0000 D=ffde4000 L=2100 DMA_FROM_DEVICE
[   21.648325] iwlagn 0000:03:00.0: single idx 242 P=1325f0000 D=ffbe4000 L=2100 DMA_FROM_DEVICE
[   21.648327] iwlagn 0000:03:00.0: single idx 244 P=1347ec000 D=ffde8000 L=2100 DMA_FROM_DEVICE
[   21.648329] iwlagn 0000:03:00.0: single idx 244 P=1325ec000 D=ffbe8000 L=2100 DMA_FROM_DEVICE
[   21.648331] iwlagn 0000:03:00.0: coherent idx 244 P=132338000 D=ff9e8000 L=8000 DMA_BIDIRECTIONAL
[   21.648333] iwlagn 0000:03:00.0: single idx 246 P=1347e8000 D=ffdec000 L=2100 DMA_FROM_DEVICE
[   21.648335] iwlagn 0000:03:00.0: single idx 246 P=1325e8000 D=ffbec000 L=2100 DMA_FROM_DEVICE
[   21.648337] iwlagn 0000:03:00.0: single idx 248 P=1347e4000 D=ffdf0000 L=2100 DMA_FROM_DEVICE
[   21.648338] iwlagn 0000:03:00.0: single idx 248 P=1325e4000 D=ffbf0000 L=2100 DMA_FROM_DEVICE
[   21.648340] iwlagn 0000:03:00.0: coherent idx 248 P=132310000 D=ff9f0000 L=8000 DMA_BIDIRECTIONAL
[   21.648342] iwlagn 0000:03:00.0: single idx 250 P=1347e0000 D=ffdf4000 L=2100 DMA_FROM_DEVICE
[   21.648344] iwlagn 0000:03:00.0: single idx 250 P=1325e0000 D=ffbf4000 L=2100 DMA_FROM_DEVICE
[   21.648346] iwlagn 0000:03:00.0: single idx 252 P=1347dc000 D=ffdf8000 L=2100 DMA_FROM_DEVICE
[   21.648348] iwlagn 0000:03:00.0: single idx 252 P=1325dc000 D=ffbf8000 L=2100 DMA_FROM_DEVICE
[   21.648350] iwlagn 0000:03:00.0: coherent idx 252 P=1322c8000 D=ff9f8000 L=8000 DMA_BIDIRECTIONAL
[   21.648352] iwlagn 0000:03:00.0: single idx 254 P=1347d8000 D=ffdfc000 L=2100 DMA_FROM_DEVICE
[   21.648354] iwlagn 0000:03:00.0: single idx 254 P=1325d8000 D=ffbfc000 L=2100 DMA_FROM_DEVICE


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-05 22:52 ` David Woodhouse
  2009-02-06  2:05   ` Chris Wright
@ 2009-02-06  2:27   ` Chris Wright
  2009-02-12 15:20   ` Joerg Roedel
  2 siblings, 0 replies; 72+ messages in thread
From: Chris Wright @ 2009-02-06  2:27 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Joerg Roedel, fujita.tomonori, netdev, iommu, mingo, linux-kernel

* David Woodhouse (dwmw2@infradead.org) wrote:
> This adds a function to dump the DMA mappings that the debugging code is
> aware of -- either for a single device, or for _all_ devices.
> 
> This can be useful for debugging -- sticking a call to it in the DMA
> page fault handler, for example, to see if the faulting address _should_
> be mapped or not, and hence work out whether it's IOMMU bugs we're
> seeing, or driver bugs.

BTW, here's how I hooked it up:

diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index c933980..df593d1 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -1072,6 +1072,34 @@ void dmar_msi_read(int irq, struct msi_msg *msg)
 	spin_unlock_irqrestore(&iommu->register_lock, flag);
 }
 
+static struct pci_dev *domain_find_pdev(u8 bus, u8 devfn)
+{
+	unsigned long flags;
+	struct pci_dev *pdev = NULL;
+	struct device_domain_info *info;
+
+	spin_lock_irqsave(&device_domain_lock, flags);
+	list_for_each_entry(info, &device_domain_list, global) {
+		if (info->bus == bus && info->devfn == devfn) {
+			pdev = info->dev;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&device_domain_lock, flags);
+	return pdev;
+}
+
+static void dump_mappings(u16 source_id)
+{
+	struct pci_dev *pdev;
+	u8 bus = source_id >> 8;
+	u8 devfn = source_id & 0xff;
+
+	pdev = domain_find_pdev(bus, devfn);
+	if (pdev)
+		debug_dma_dump_mappings(&pdev->dev);
+}
+
 static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
 		u8 fault_reason, u16 source_id, unsigned long long addr)
 {
@@ -1086,6 +1114,8 @@ static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
 		(type ? "DMA Read" : "DMA Write"),
 		(source_id >> 8), PCI_SLOT(source_id & 0xFF),
 		PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+
+	dump_mappings(source_id);
 	return 0;
 }
 

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-06  2:05   ` Chris Wright
@ 2009-02-06  7:56     ` David Woodhouse
  2009-02-06 16:08       ` Chris Wright
  2009-02-06 18:20       ` Chris Wright
  2009-02-12 14:48     ` Joerg Roedel
  1 sibling, 2 replies; 72+ messages in thread
From: David Woodhouse @ 2009-02-06  7:56 UTC (permalink / raw)
  To: Chris Wright
  Cc: Joerg Roedel, fujita.tomonori, netdev, iommu, mingo, linux-kernel

On Thu, 2009-02-05 at 18:05 -0800, Chris Wright wrote:
> extra tab

Thanks. Your code to hook it up is better than mine too. I'll steal
that.

> Sample output below (2 of ~2500 faults), pages don't appear to be
> mapped:

What machine did you get that on?

Yeah, I saw one of those. If could be a driver bug, of course -- it
could be unmapping a range before it's actually finished with it. But
that's unlikely.

An alternative explanation... The DMA is aborted¹, and the device
interrupts us to tell us about it at the _same_ time that the IOMMU
interrupts us to tell us about the fault. We process the device
interrupt first, unmap that buffer. And then we process the IOMMU
interrupt... and the buffer is already gone from the list.

It might be interesting to make this code also remember and print the
last range that was unmapped, as well as the currently-mapped ranges.

> (interesting hash_fn spread ;-)

Yeah, that's a little suboptimal, isn't it :)

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

¹ due to the bug we're chasing now. The range _is_ supposed to be mapped.


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-06  7:56     ` David Woodhouse
@ 2009-02-06 16:08       ` Chris Wright
  2009-02-06 18:20       ` Chris Wright
  1 sibling, 0 replies; 72+ messages in thread
From: Chris Wright @ 2009-02-06 16:08 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Chris Wright, Joerg Roedel, fujita.tomonori, netdev, iommu,
	mingo, linux-kernel

* David Woodhouse (dwmw2@infradead.org) wrote:
> What machine did you get that on?

That's a T400 (I'd expect it's same issue as X200).

> Yeah, I saw one of those. If could be a driver bug, of course -- it
> could be unmapping a range before it's actually finished with it. But
> that's unlikely.

One thing I noticed is many of the faults are the page prior to a
coherent range 0x8000 in length, which seems to correspond to tfd buffer.
No obvious off-by-one error anywhere, and not all faults fit that pattern,
so w/out more iwlagn driver knowledge hard to say if that's meaningful
or just mapping coincidence.

> An alternative explanation... The DMA is aborted¹, and the device
> interrupts us to tell us about it at the _same_ time that the IOMMU
> interrupts us to tell us about the fault. We process the device
> interrupt first, unmap that buffer. And then we process the IOMMU
> interrupt... and the buffer is already gone from the list.

I'd have expected the iommu fault to be delivered first, but hey...

> It might be interesting to make this code also remember and print the
> last range that was unmapped, as well as the currently-mapped ranges.

That's what I was thinking too.  Almost need a flight recorder mode to
see if the range was ever mapped/unmapped.

thanks,
-chris

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-06  7:56     ` David Woodhouse
  2009-02-06 16:08       ` Chris Wright
@ 2009-02-06 18:20       ` Chris Wright
  1 sibling, 0 replies; 72+ messages in thread
From: Chris Wright @ 2009-02-06 18:20 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Chris Wright, Joerg Roedel, fujita.tomonori, netdev, iommu,
	mingo, linux-kernel

* David Woodhouse (dwmw2@infradead.org) wrote:
> An alternative explanation... The DMA is aborted¹, and the device
> interrupts us to tell us about it at the _same_ time that the IOMMU
> interrupts us to tell us about the fault. We process the device
> interrupt first, unmap that buffer. And then we process the IOMMU
> interrupt... and the buffer is already gone from the list.

[  362.283661] Device 0000:03:00.0 mapping: 1000@fff1b000
[  362.283727] DMAR:[DMA Write] Request device [03:00.0] fault addr fff1b000 
[  362.284719] Device 0000:03:00.0 unmapping: 1000@fff1b000

[  362.426974] Device 0000:03:00.0 mapping: 1000@fff1b000
[  362.427040] DMAR:[DMA Write] Request device [03:00.0] fault addr fff1b000 
[  362.429092] Device 0000:03:00.0 unmapping: 1000@fff1b000

[  447.644332] Device 0000:03:00.0 mapping: 1000@fff03000
[  447.644373] DMAR:[DMA Write] Request device [03:00.0] fault addr fff03000 
[  447.646008] Device 0000:03:00.0 unmapping: 1000@fff03000

[  483.037641] Device 0000:03:00.0 mapping: 1000@ffc9f000
[  483.037707] DMAR:[DMA Write] Request device [03:00.0] fault addr ffc9f000 
[  483.038699] Device 0000:03:00.0 unmapping: 1000@ffc9f000

...

Looks like driver is doing the right thing.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-06  2:05   ` Chris Wright
  2009-02-06  7:56     ` David Woodhouse
@ 2009-02-12 14:48     ` Joerg Roedel
  1 sibling, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-02-12 14:48 UTC (permalink / raw)
  To: Chris Wright
  Cc: David Woodhouse, linux-kernel, fujita.tomonori, iommu, mingo, netdev

On Thu, Feb 05, 2009 at 06:05:35PM -0800, Chris Wright wrote:

> (interesting hash_fn spread ;-)

Hmm, thats because all device addresses are 16kb aligned. The hashfn
uses bits 13 to 21 as the index for the hash. I can move this window up
to bits 18-26 if it improves the hash spread.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 0/16] DMA-API debugging facility v2
  2009-02-05 22:52 ` David Woodhouse
  2009-02-06  2:05   ` Chris Wright
  2009-02-06  2:27   ` Chris Wright
@ 2009-02-12 15:20   ` Joerg Roedel
  2 siblings, 0 replies; 72+ messages in thread
From: Joerg Roedel @ 2009-02-12 15:20 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Joerg Roedel, fujita.tomonori, netdev, iommu, mingo, linux-kernel


On Thu, Feb 05, 2009 at 10:52:32PM +0000, David Woodhouse wrote:
> This adds a function to dump the DMA mappings that the debugging code is
> aware of -- either for a single device, or for _all_ devices.
> 
> This can be useful for debugging -- sticking a call to it in the DMA
> page fault handler, for example, to see if the faulting address _should_
> be mapped or not, and hence work out whether it's IOMMU bugs we're
> seeing, or driver bugs.
> 
> I'd also like to make it answer the question 'should address X be mapped
> for device Y', but I'll get to that next.
> 
> Do we have a %pX format for printing dma_addr_t yet? 
> 
> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
> 

Great. Thanks. Applied to my dma-api/debug branch.

Joerg

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2009-02-12 15:20 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-09 16:19 [PATCH 0/16] DMA-API debugging facility v2 Joerg Roedel
2009-01-09 16:19 ` [PATCH 01/16] dma-debug: add Kconfig entry Joerg Roedel
2009-01-09 20:12   ` Randy Dunlap
2009-01-09 16:19 ` [PATCH 02/16] dma-debug: add header file and core data structures Joerg Roedel
2009-01-11  6:25   ` FUJITA Tomonori
2009-01-09 16:19 ` [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Joerg Roedel
2009-01-09 17:55   ` Evgeniy Polyakov
2009-01-09 18:14     ` Joerg Roedel
2009-01-09 18:23       ` Evgeniy Polyakov
2009-01-09 18:40         ` Joerg Roedel
2009-01-13  8:51   ` Andrew Morton
2009-01-13  8:59     ` David Woodhouse
2009-01-14 11:43     ` Ingo Molnar
2009-01-14 17:39       ` Andrew Morton
2009-01-14 17:43         ` Ingo Molnar
2009-01-14 17:48         ` Ingo Molnar
2009-01-15  3:44           ` FUJITA Tomonori
2009-01-14 17:48         ` David Woodhouse
2009-01-14 17:51         ` Joerg Roedel
2009-01-09 16:19 ` [PATCH 04/16] dma-debug: add allocator code Joerg Roedel
2009-01-10 23:43   ` Ingo Molnar
2009-01-09 16:19 ` [PATCH 05/16] dma-debug: add initialization code Joerg Roedel
2009-01-09 17:58   ` Evgeniy Polyakov
2009-01-09 18:17     ` Joerg Roedel
2009-01-09 16:19 ` [PATCH 06/16] dma-debug: add kernel command line parameters Joerg Roedel
2009-01-09 16:19 ` [PATCH 07/16] dma-debug: add debugfs interface Joerg Roedel
2009-01-10 23:08   ` Ingo Molnar
2009-01-11  7:52     ` Joerg Roedel
2009-01-14 15:22     ` Joerg Roedel
2009-01-10 23:15   ` Ingo Molnar
2009-01-09 16:19 ` [PATCH 08/16] dma-debug: add core checking functions Joerg Roedel
2009-01-10 23:11   ` Ingo Molnar
2009-01-11  7:57     ` Joerg Roedel
2009-01-11  8:34       ` Joerg Roedel
2009-01-14 11:44     ` Joerg Roedel
2009-01-14 11:48       ` Ingo Molnar
2009-01-10 23:12   ` Ingo Molnar
2009-01-11  7:54     ` Joerg Roedel
2009-01-10 23:13   ` Ingo Molnar
2009-01-09 16:19 ` [PATCH 09/16] dma-debug: add checking for map/unmap_single Joerg Roedel
2009-01-09 16:19 ` [PATCH 10/16] dma-debug: add add checking for map/unmap_sg Joerg Roedel
2009-01-09 18:08   ` Evgeniy Polyakov
2009-01-09 18:11     ` Joerg Roedel
2009-01-09 16:19 ` [PATCH 11/16] dma-debug: add checking for [alloc|free]_coherent Joerg Roedel
2009-01-11  6:25   ` FUJITA Tomonori
2009-01-11  6:30     ` FUJITA Tomonori
2009-01-11  7:59       ` Joerg Roedel
2009-01-09 16:19 ` [PATCH 12/16] dma-debug: add checks for sync_single_* Joerg Roedel
2009-01-09 16:19 ` [PATCH 13/16] dma-debug: add checks for sync_single_range_* Joerg Roedel
2009-01-09 16:19 ` [PATCH 14/16] dma-debug: add checks for sync_single_sg_* Joerg Roedel
2009-01-10 23:46   ` Ingo Molnar
2009-01-11  8:00     ` Joerg Roedel
2009-01-09 16:19 ` [PATCH 15/16] dma-debug: x86 architecture bindings Joerg Roedel
2009-01-10 23:04   ` Ingo Molnar
2009-01-10 23:48   ` Ingo Molnar
2009-01-11  6:25   ` FUJITA Tomonori
2009-01-11  8:08     ` Joerg Roedel
2009-01-09 16:19 ` [PATCH 16/16] dma-debug: Documentation update Joerg Roedel
2009-01-09 21:24 ` [PATCH 0/16] DMA-API debugging facility v2 Michael Chan
2009-01-09 22:33   ` Joerg Roedel
2009-01-09 22:37     ` Joerg Roedel
2009-01-11  6:25       ` FUJITA Tomonori
2009-01-10 23:54 ` Ingo Molnar
2009-01-11  8:11   ` Joerg Roedel
2009-02-05 22:52 ` David Woodhouse
2009-02-06  2:05   ` Chris Wright
2009-02-06  7:56     ` David Woodhouse
2009-02-06 16:08       ` Chris Wright
2009-02-06 18:20       ` Chris Wright
2009-02-12 14:48     ` Joerg Roedel
2009-02-06  2:27   ` Chris Wright
2009-02-12 15:20   ` Joerg Roedel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).