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