PERFORCE change 163741 for review

Scott Long scottl at FreeBSD.org
Sun Jun 7 21:51:29 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163741

Change 163741 by scottl at scottl-deimos on 2009/06/07 21:51:11

	Iterate dc lists in 3 steps instead of two.  This allows the
	lock to be held while unref'ing dt's, which will allow them to
	be safely freed in the future.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/kern/subr_bus.c#23 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/kern/subr_bus.c#23 (text+ko) ====

@@ -925,12 +925,13 @@
 	}
 
 	mtx_unlock(&devclasses_mtx);
-	for (i = 0; i < maxunit; i++) {
+	for (i = 0; i < maxunit; i++)
 		BUS_DRIVER_ADDED(devlist[i], driver);
+
+	mtx_lock(&devclasses_mtx);
+	for (i = 0; i < maxunit; i++)
 		DT_UNREF(devlist[i]);
-	}
 	free(devlist, M_BUS);
-	mtx_lock(&devclasses_mtx);
 
 	/*
 	 * Walk through the children classes.  Since we only keep a
@@ -991,10 +992,9 @@
 	dl->driver = driver;
 	TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
 	driver->refs++;		/* XXX: kobj_mtx */
+	DC_REF(dc);
 
-	DC_REF(dc);
 	devclass_driver_added(dc, driver);
-	DC_UNREF(dc);
 	bus_data_generation_update();
 	mtx_unlock(&devclasses_mtx);
 	return (0);
@@ -1070,30 +1070,40 @@
 			}
 		}
 	}
+
 	mtx_unlock(&devclasses_mtx);
-
 	error = 0;
 	for (i = 0; i < maxunit; i++) {
 		dev = devlist[i];
-		if ((error = device_detach(dev)) != 0) {
-			DT_UNREF(dev);
+		/*
+		 * If device_detach() generates an error, the rest of the
+		 * devices in the list still need to be deref'd.
+		 */
+		if ((error = device_detach(dev)) != 0)
 			break;
-		}
 		device_set_driver(dev, NULL);
+	}
+
+	mtx_lock(&devclasses_mtx);
+	for (i = 0; i < maxunit; i++) {
+		dev = devlist[i];
 		DT_UNREF(dev);
 	}
+
 	free(devlist, M_BUS);
-	if (error)
+	if (error) {
+		mtx_unlock(&devclasses_mtx);
 		return (error);
+	}
 
-	mtx_lock(&devclasses_mtx);
 	TAILQ_REMOVE(&busclass->drivers, dl, link);
 	free(dl, M_BUS);
 
 	/* XXX: kobj_mtx */
+	DC_UNREF(dc);
 	driver->refs--;
 	if (driver->refs == 0)
-		kobj_class_free((kobj_class_t) driver);
+	kobj_class_free((kobj_class_t) driver);
 
 	bus_data_generation_update();
 	mtx_unlock(&devclasses_mtx);
@@ -1169,17 +1179,20 @@
 			}
 		}
 	}
+
 	mtx_unlock(&devclasses_mtx);
-
 	error = 0;
 	for (i = 0; i < maxunit; i++) {
-		dev = devlist[i];
-		error = device_quiesce(dev);
-		DT_UNREF(dev);
-		if (error)
+		if ((error = device_quiesce(devlist[i])) != 0)
 			break;
 	}
 
+	mtx_lock(&devclasses_mtx);
+	for (i = 0; i < maxunit; i++) {
+		DT_UNREF(devlist[i]);
+	}
+	mtx_unlock(&devclasses_mtx);
+
 	free(devlist, M_BUS);
 	return (error);
 }


More information about the p4-projects mailing list