[PATCH] create iommu_free_table()

John Rose johnrose at austin.ibm.com
Sat Oct 23 04:15:39 EST 2004


Thanks for the comments and help... responses below.

On Wed, 2004-10-20 at 17:26, Olof Johansson wrote:
<snip>

> > +	for (i = 0; i < (tbl->it_mapsize/64); i++) {
> > +		if (tbl->it_map[i] != 0) {
> > +			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
> > +				__FUNCTION__, dn->full_name);
> > +			break;
> > +		}
> 
> Could this get spammy? It could be nice to see a WARN_ON(1) too, so the 
> call stack is dumped. If that's added, a printk_ratelimit() would 
> definately be warranted around both the printk and the WARN_ON().

I'd have to disagree here.  Since the stack trace will always involve
the removal of a device node prompted by a write to /proc, it doesn't
reveal any useful info.  The printk above includes the OF path of the
device, so any offending driver can be tracked down.  

Here's a patch without the whitespace problems you pointed out.

Thanks-
John

Signed-off-by: John Rose <johnrose at austin.ibm.com>

diff -Nru a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
--- a/arch/ppc64/kernel/pSeries_iommu.c	Fri Oct 22 13:03:21 2004
+++ b/arch/ppc64/kernel/pSeries_iommu.c	Fri Oct 22 13:03:21 2004
@@ -412,6 +412,38 @@
 	dn->iommu_table = iommu_init_table(tbl);
 }
 
+void iommu_free_table(struct device_node *dn)
+{
+	struct iommu_table *tbl = dn->iommu_table;
+	unsigned long bitmap_sz, i;
+	unsigned int order;
+
+	if (!tbl || !tbl->it_map) {
+		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
+				dn->full_name);
+		return;
+	}
+
+	/* verify that table contains no entries */
+	/* it_mapsize is in entries, and we're examining 64 at a time */
+	for (i = 0; i < (tbl->it_mapsize/64); i++) {
+		if (tbl->it_map[i] != 0) {
+			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
+				__FUNCTION__, dn->full_name);
+			break;
+		}
+	}
+
+	/* calculate bitmap size in bytes */
+	bitmap_sz = (tbl->it_mapsize + 7) / 8;
+
+	/* free bitmap */
+	order = get_order(bitmap_sz);
+	free_pages((unsigned long) tbl->it_map, order);
+
+	/* free table */
+	kfree(tbl);
+}
 
 void iommu_setup_pSeries(void)
 {
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c	Fri Oct 22 13:03:21 2004
+++ b/arch/ppc64/kernel/prom.c	Fri Oct 22 13:03:21 2004
@@ -1818,6 +1818,9 @@
 		return -EBUSY;
 	}
 
+	if (np->iommu_table)
+		iommu_free_table(np);
+
 	write_lock(&devtree_lock);
 	OF_MARK_STALE(np);
 	remove_node_proc_entries(np);
diff -Nru a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h
--- a/include/asm-ppc64/iommu.h	Fri Oct 22 13:03:21 2004
+++ b/include/asm-ppc64/iommu.h	Fri Oct 22 13:03:21 2004
@@ -113,6 +113,9 @@
 /* Creates table for an individual device node */
 extern void iommu_devnode_init(struct device_node *dn);
 
+/* Frees table for an individual device node */
+extern void iommu_free_table(struct device_node *dn);
+
 #endif /* CONFIG_PPC_MULTIPLATFORM */
 
 #ifdef CONFIG_PPC_ISERIES





More information about the Linuxppc64-dev mailing list