Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jun 2007 16:57:27 GMT
From:      Scott Long <scottl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 121923 for review
Message-ID:  <200706181657.l5IGvRit043742@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=121923

Change 121923 by scottl@scottl-deimos on 2007/06/18 16:57:09

	Another round of newbus/devclass locking.

Affected files ...

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

Differences ...

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

@@ -74,7 +74,7 @@
 typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
 typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
 typedef TAILQ_HEAD(device_list, device) device_list_t;
-struct mtx newbus_lock;
+struct mtx devclass_lock;
 
 struct devclass {
 	TAILQ_ENTRY(devclass) link;
@@ -737,7 +737,7 @@
  */
 
 static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
-MTX_SYSINIT(newbus_lock, &newbus_lock, "Newbus internal lock", MTX_DEF);
+MTX_SYSINIT(devclass_lock, &devclass_lock, "Newbus internal lock", MTX_DEF);
 
 
 /**
@@ -761,7 +761,7 @@
 {
 	devclass_t dc;
 
-	mtx_assert(&newbus_lock, MA_OWNED);
+	mtx_assert(&devclass_lock, MA_OWNED);
 
 	PDEBUG(("looking for %s", classname));
 	if (!classname)
@@ -816,9 +816,9 @@
 {
 	devclass_t dc;
 
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	dc = devclass_find_internal(classname, NULL, TRUE);
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (dc);
 }
 
@@ -835,9 +835,9 @@
 {
 	devclass_t dc;
 
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	dc = devclass_find_internal(classname, NULL, FALSE);
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	return (dc);
 }
 
@@ -875,7 +875,7 @@
 	/*
 	 * Make sure the devclass which the driver is implementing exists.
 	 */
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	devclass_find_internal(driver->name, NULL, TRUE);
 
 	dl->driver = driver;
@@ -888,14 +888,14 @@
 	for (i = 0; i < dc->maxunit; i++)
 		if (dc->devices[i]) {
 			/* XXX UNSAFE */
-			mtx_unlock(&newbus_lock);
+			mtx_unlock(&devclass_lock);
 			BUS_DRIVER_ADDED(dc->devices[i], driver);
-			mtx_lock(&newbus_lock);
+			mtx_lock(&devclass_lock);
 		}
 	}
 
 	bus_data_generation_update();
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (0);
 }
 
@@ -930,7 +930,7 @@
 	/*
 	 * Find the link structure in the bus' list of drivers.
 	 */
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	TAILQ_FOREACH(dl, &busclass->drivers, link) {
 		if (dl->driver == driver)
 			break;
@@ -939,7 +939,7 @@
 	if (!dl) {
 		PDEBUG(("%s not found in %s list", driver->name,
 		    busclass->name));
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (ENOENT);
 	}
 	TAILQ_REMOVE(&busclass->drivers, dl, link);
@@ -960,11 +960,11 @@
 			if (dev->driver == driver && dev->parent &&
 			    dev->parent->devclass == busclass) {
 				/* XXX UNSAFE */
-				mtx_unlock(&newbus_lock);
+				mtx_unlock(&devclass_lock);
 				if ((error = device_detach(dev)) != 0)
 					return (error);
 				device_set_driver(dev, NULL);
-				mtx_lock(&newbus_lock);
+				mtx_lock(&devclass_lock);
 			}
 		}
 	}
@@ -977,7 +977,7 @@
 		kobj_class_free((kobj_class_t) driver);
 
 	bus_data_generation_update();
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (0);
 }
 
@@ -1011,7 +1011,7 @@
 	/*
 	 * Find the link structure in the bus' list of drivers.
 	 */
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	TAILQ_FOREACH(dl, &busclass->drivers, link) {
 		if (dl->driver == driver)
 			break;
@@ -1020,7 +1020,7 @@
 	if (!dl) {
 		PDEBUG(("%s not found in %s list", driver->name,
 		    busclass->name));
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (ENOENT);
 	}
 
@@ -1040,15 +1040,15 @@
 			if (dev->driver == driver && dev->parent &&
 			    dev->parent->devclass == busclass) {
 				/* XXX UNSAFE */
-				mtx_unlock(&newbus_lock);
+				mtx_unlock(&devclass_lock);
 				if ((error = device_quiesce(dev)) != 0)
 					return (error);
-				mtx_lock(&newbus_lock);
+				mtx_lock(&devclass_lock);
 			}
 		}
 	}
 
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (0);
 }
 
@@ -1087,11 +1087,11 @@
 	kobj_class_t kc = NULL;
 	driverlink_t dl;
 
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	dl = devclass_find_driver_internal(dc, classname);
 	if (dl)
 		kc = dl->driver;
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (kc);
 }
 
@@ -1116,9 +1116,15 @@
 device_t
 devclass_get_device(devclass_t dc, int unit)
 {
+	device_t dev;
+
+	mtx_lock(&devclass_lock);
 	if (dc == NULL || unit < 0 || unit >= dc->maxunit)
-		return (NULL);
-	return (dc->devices[unit]);
+		dev = NULL;
+	else
+		dev = dc->devices[unit]);
+	mtx_unlock(&devclass_lock);
+	return (dev);
 }
 
 /**
@@ -1165,10 +1171,13 @@
 	int count, i;
 	device_t *list;
 
+	mtx_lock(&devclass_lock);
 	count = devclass_get_count(dc);
 	list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
-	if (!list)
+	if (!list) {
+		mtx_unlock(&devclass_lock);
 		return (ENOMEM);
+	}
 
 	count = 0;
 	for (i = 0; i < dc->maxunit; i++) {
@@ -1177,6 +1186,7 @@
 			count++;
 		}
 	}
+	mtx_unlock(&devclass_lock);
 
 	*devlistp = list;
 	*devcountp = count;
@@ -1230,8 +1240,8 @@
  *
  * @param dc		the devclass to examine
  */
-int
-devclass_get_count(devclass_t dc)
+static int
+_devclass_get_count(devclass_t dc)
 {
 	int count, i;
 
@@ -1242,6 +1252,17 @@
 	return (count);
 }
 
+int
+devclass_get_count(devclass_t dc)
+{
+	int count;
+
+	mtx_lock(&devclass_lock);
+	count = _devlcass_get_count(dc);
+	mtx_unlock(&devclass_lock);
+	return (count);
+}
+
 /**
  * @brief Get the maximum unit number used in a devclass
  *
@@ -1250,10 +1271,21 @@
  *
  * @param dc		the devclass to examine
  */
+static int
+_devclass_get_maxunit(devclass_t dc)
+{
+	return (dc->maxunit);
+}
+
 int
 devclass_get_maxunit(devclass_t dc)
 {
-	return (dc->maxunit);
+	int maxunit;
+
+	mtx_lock(&devlcass_lock);
+	maxunit = _devclass_get_maxunit(dc);
+	mtx_unlock(&devclass_lock);
+	return (maxunit);
 }
 
 /**
@@ -1333,6 +1365,7 @@
 {
 	int unit = *unitp;
 
+	mtx_assert(&devclass_lock, MA_OWNED);
 	PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
 
 	/* If we were given a wired unit number, check for existing device */
@@ -1474,7 +1507,9 @@
 	PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
 
 	if (name) {
+		mtx_lock(&devclass_lock);
 		dc = devclass_find_internal(name, NULL, TRUE);
+		mtx_unlock(&devclass_lock);
 		if (!dc) {
 			printf("make_device: can't find device class %s\n",
 			    name);
@@ -1504,10 +1539,13 @@
 		dev->flags |= DF_WILDCARD;
 	if (name) {
 		dev->flags |= DF_FIXEDCLASS;
+		mtx_lock(&devclass_lock);
 		if (devclass_add_device(dc, dev)) {
+			mtx_unlock(&devclass_lock);
 			kobj_delete((kobj_t) dev, M_BUS);
 			return (NULL);
 		}
+		mtx_unlock(&devclass_lock);
 	}
 	dev->ivars = NULL;
 	dev->softc = NULL;
@@ -1733,7 +1771,7 @@
 	int result, pri = 0;
 	int hasclass = (child->devclass != 0);
 
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	dc = dev->devclass;
 	if (!dc)
 		panic("device_probe_child: parent device has no devclass");
@@ -1743,7 +1781,7 @@
 	 * return if we can rebid this object.
 	 */
 	if (child->state == DS_ALIVE && (child->flags & DF_REBID) == 0) {
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (0);
 	}
 
@@ -1761,9 +1799,9 @@
 			    "flags", &child->devflags);
 
 			/* XXX UNSAFE */
-			mtx_unlock(&newbus_lock);
+			mtx_unlock(&devclass_lock);
 			result = DEVICE_PROBE(child);
-			mtx_lock(&newbus_lock);
+			mtx_lock(&devclass_lock);
 
 			/* Reset flags and devclass before the next probe. */
 			child->devflags = 0;
@@ -1855,11 +1893,11 @@
 		child->state = DS_ALIVE;
 
 		bus_data_generation_update();
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (0);
 	}
 
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (ENXIO);
 }
 
@@ -1896,14 +1934,14 @@
 	device_t *list;
 
 	count = 0;
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	TAILQ_FOREACH(child, &dev->children, link) {
 		count++;
 	}
 
 	list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
 	if (!list) {
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (ENOMEM);
 	}
 
@@ -1915,7 +1953,7 @@
 
 	*devlistp = list;
 	*devcountp = count;
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 
 	return (0);
 }
@@ -2276,30 +2314,30 @@
 	devclass_t dc;
 	int error;
 
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	if (!classname) {
 		if (dev->devclass)
 			devclass_delete_device(dev->devclass, dev);
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (0);
 	}
 
 	if (dev->devclass) {
 		printf("device_set_devclass: device class already set\n");
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (EINVAL);
 	}
 
 	dc = devclass_find_internal(classname, NULL, TRUE);
 	if (!dc) {
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		return (ENOMEM);
 	}
 
 	error = devclass_add_device(dc, dev);
 
 	bus_data_generation_update();
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	return (error);
 }
 
@@ -2552,7 +2590,9 @@
 	if (err)
 		return (err);
 	dev->unit = unit;
+	mtx_lock(&devclass_lock);
 	err = devclass_add_device(dc, dev);
+	mtx_unlock(&devclass_lock);
 	if (err)
 		return (err);
 
@@ -3781,9 +3821,9 @@
 		kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
 		root_bus->driver = &root_driver;
 		root_bus->state = DS_ATTACHED;
-		mtx_lock(&newbus_lock);
+		mtx_lock(&devclass_lock);
 		root_devclass = devclass_find_internal("root", NULL, FALSE);
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		devinit();
 		return (0);
 
@@ -3839,9 +3879,9 @@
 	kobj_class_t driver;
 
 	dmd = (struct driver_module_data *)arg;
-	mtx_lock(&newbus_lock);
+	mtx_lock(&devclass_lock);
 	bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
-	mtx_unlock(&newbus_lock);
+	mtx_unlock(&devclass_lock);
 	error = 0;
 
 	switch (what) {
@@ -3863,7 +3903,7 @@
 		 * search for drivers in both devclasses for children
 		 * of a device using this driver.
 		 */
-		mtx_lock(&newbus_lock);
+		mtx_lock(&devclass_lock);
 		if (driver->baseclasses) {
 			const char *parentname;
 			parentname = driver->baseclasses[0]->name;
@@ -3874,7 +3914,7 @@
 			*dmd->dmd_devclass =
 				devclass_find_internal(driver->name, NULL, TRUE);
 		}
-		mtx_unlock(&newbus_lock);
+		mtx_unlock(&devclass_lock);
 		break;
 
 	case MOD_UNLOAD:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706181657.l5IGvRit043742>