From: tip-bot for Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@redhat.com,
konrad.wilk@oracle.com, fujita.tomonori@lab.ntt.co.jp,
tglx@linutronix.de, hpa@linux.intel.com
Subject: [tip:x86/iommu] x86, iommu: Add proper dependency sort routine (and sanity check).
Date: Thu, 26 Aug 2010 23:28:35 GMT [thread overview]
Message-ID: <tip-5bef80a4b826b9cee1c6aec7ecc371ec395260cc@git.kernel.org> (raw)
In-Reply-To: <1282845485-8991-4-git-send-email-konrad.wilk@oracle.com>
Commit-ID: 5bef80a4b826b9cee1c6aec7ecc371ec395260cc
Gitweb: http://git.kernel.org/tip/5bef80a4b826b9cee1c6aec7ecc371ec395260cc
Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
AuthorDate: Thu, 26 Aug 2010 13:57:58 -0400
Committer: H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 26 Aug 2010 15:13:19 -0700
x86, iommu: Add proper dependency sort routine (and sanity check).
We are using a very simple sort routine which sorts the .iommu_table
array in the order of dependencies. Specifically each structure
of iommu_table_entry has a field 'depend' which contains the function
pointer to the IOMMU that MUST be run before us. We sort the array
of structures so that the struct iommu_table_entry with no
'depend' field are first, and then the subsequent ones are the
ones for which the 'depend' function has been already invoked
(in other words, precede us).
Using the kernel's version 'sort', which is a mergeheap is
feasible, but would require making the comparison operator
scan recursivly the array to satisfy the "heapify" process: setting the
levels properly. The end result would much more complex than it should
be an it is just much simpler to utilize this simple sort routine.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
LKML-Reference: <1282845485-8991-4-git-send-email-konrad.wilk@oracle.com>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Fujita Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
arch/x86/include/asm/iommu_table.h | 6 ++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/pci-iommu_table.c | 89 ++++++++++++++++++++++++++++++++++++
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h
index 435176f..2124e3e 100644
--- a/arch/x86/include/asm/iommu_table.h
+++ b/arch/x86/include/asm/iommu_table.h
@@ -92,4 +92,10 @@ struct iommu_table_entry {
#define IOMMU_INIT(_detect, _depend, _init, _late_init) \
__IOMMU_INIT(_detect, _depend, _init, _late_init, 0)
+void sort_iommu_table(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish);
+
+void check_iommu_entries(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish);
+
#endif /* _ASM_X86_IOMMU_TABLE_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0925676..6817546 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -42,6 +42,7 @@ obj-y += bootflag.o e820.o
obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
obj-y += tsc.o io_delay.o rtc.o
+obj-y += pci-iommu_table.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-y += process.o
diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c
new file mode 100644
index 0000000..55d745e
--- /dev/null
+++ b/arch/x86/kernel/pci-iommu_table.c
@@ -0,0 +1,89 @@
+#include <linux/dma-mapping.h>
+#include <asm/iommu_table.h>
+#include <linux/string.h>
+#include <linux/kallsyms.h>
+
+
+#define DEBUG 1
+
+static struct iommu_table_entry * __init
+find_dependents_of(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish,
+ struct iommu_table_entry *q)
+{
+ struct iommu_table_entry *p;
+
+ if (!q)
+ return NULL;
+
+ for (p = start; p < finish; p++)
+ if (p->detect == q->depend)
+ return p;
+
+ return NULL;
+}
+
+
+void __init sort_iommu_table(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish) {
+
+ struct iommu_table_entry *p, *q, tmp;
+
+ for (p = start; p < finish; p++) {
+again:
+ q = find_dependents_of(start, finish, p);
+ /* We are bit sneaky here. We use the memory address to figure
+ * out if the node we depend on is past our point, if so, swap.
+ */
+ if (q > p) {
+ tmp = *p;
+ memmove(p, q, sizeof(*p));
+ *q = tmp;
+ goto again;
+ }
+ }
+
+}
+
+#ifdef DEBUG
+void __init check_iommu_entries(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish)
+{
+ struct iommu_table_entry *p, *q, *x;
+ char sym_p[KSYM_SYMBOL_LEN];
+ char sym_q[KSYM_SYMBOL_LEN];
+
+ /* Simple cyclic dependency checker. */
+ for (p = start; p < finish; p++) {
+ q = find_dependents_of(start, finish, p);
+ x = find_dependents_of(start, finish, q);
+ if (p == x) {
+ sprint_symbol(sym_p, (unsigned long)p->detect);
+ sprint_symbol(sym_q, (unsigned long)q->detect);
+
+ printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \
+ " on %s and vice-versa. BREAKING IT.\n",
+ sym_p, sym_q);
+ /* Heavy handed way..*/
+ x->depend = 0;
+ }
+ }
+
+ for (p = start; p < finish; p++) {
+ q = find_dependents_of(p, finish, p);
+ if (q && q > p) {
+ sprint_symbol(sym_p, (unsigned long)p->detect);
+ sprint_symbol(sym_q, (unsigned long)q->detect);
+
+ printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\
+ "should be called before %s!\n",
+ sym_p, sym_q);
+ }
+ }
+}
+#else
+inline void check_iommu_entries(struct iommu_table_entry *start,
+ struct iommu_table_entry *finish)
+{
+}
+#endif
next prev parent reply other threads:[~2010-08-26 23:29 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-26 17:57 [RFC PATCH v2] Modularize IOMMUs detection/init for X86 Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 01/10] x86/iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure Konrad Rzeszutek Wilk
2010-08-26 18:19 ` Sam Ravnborg
2010-08-26 19:48 ` H. Peter Anvin
2010-08-26 23:47 ` H. Peter Anvin
2010-08-27 14:38 ` Konrad Rzeszutek Wilk
2010-08-27 14:40 ` Sam Ravnborg
2010-08-27 18:19 ` [PATCH] x86: Adding comments about .iommu_table and its neighbors Konrad Rzeszutek Wilk
2010-08-28 1:54 ` [tip:x86/iommu] x86, doc: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 23:27 ` [tip:x86/iommu] x86, iommu: Add IOMMU_INIT macros, .iommu_table section, and iommu_table_entry structure tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 02/10] x86/iommu: Make all IOMMU's detection routines return a value Konrad Rzeszutek Wilk
2010-08-26 23:28 ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:57 ` [PATCH 03/10] x86/iommu: Add proper dependency sort routine (and sanity check) Konrad Rzeszutek Wilk
2010-08-26 23:28 ` tip-bot for Konrad Rzeszutek Wilk [this message]
2010-08-26 17:57 ` [PATCH 04/10] x86/swiotlb: Simplify SWIOTLB pci_swiotlb_detect routine Konrad Rzeszutek Wilk
2010-08-26 23:28 ` [tip:x86/iommu] x86, swiotlb: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 05/10] x86/swiotlb: Make SWIOTLB use IOMMU_INIT_* macros Konrad Rzeszutek Wilk
2010-08-26 23:29 ` [tip:x86/iommu] x86, swiotlb: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 06/10] x86/xen-swiotlb: Make Xen-SWIOTLB " Konrad Rzeszutek Wilk
2010-08-26 23:29 ` [tip:x86/iommu] x86, xen-swiotlb: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 07/10] x86/calgary: Make Calgary IOMMU " Konrad Rzeszutek Wilk
2010-08-26 23:30 ` [tip:x86/iommu] x86, calgary: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 08/10] x86/GART/AMD-VI: Make AMD GART and " Konrad Rzeszutek Wilk
2010-08-26 23:30 ` [tip:x86/iommu] x86, GART/AMD-VI: " tip-bot for Konrad Rzeszutek Wilk
2010-08-26 17:58 ` [PATCH 09/10] x86/VT-d: Make Intel VT-d " Konrad Rzeszutek Wilk
2010-08-26 23:30 ` [tip:x86/iommu] x86, VT-d: " tip-bot for Konrad Rzeszutek Wilk
2010-09-07 18:10 ` [PATCH 09/10] x86/VT-d: " Tony Luck
2010-09-07 19:07 ` Konrad Rzeszutek Wilk
2010-09-07 19:12 ` Luck, Tony
2010-08-26 17:58 ` [PATCH 10/10] x86/iommu: Utilize the IOMMU_INIT macros functionality Konrad Rzeszutek Wilk
2010-08-26 23:31 ` [tip:x86/iommu] x86, iommu: " tip-bot for Konrad Rzeszutek Wilk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-5bef80a4b826b9cee1c6aec7ecc371ec395260cc@git.kernel.org \
--to=konrad.wilk@oracle.com \
--cc=fujita.tomonori@lab.ntt.co.jp \
--cc=hpa@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.