From owner-p4-projects@FreeBSD.ORG Sun Jun 17 18:56:13 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7871B16A474; Sun, 17 Jun 2007 18:56:13 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 3E8F516A400 for ; Sun, 17 Jun 2007 18:56:13 +0000 (UTC) (envelope-from scottl@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 2EDA213C465 for ; Sun, 17 Jun 2007 18:56:13 +0000 (UTC) (envelope-from scottl@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l5HIuDv9019832 for ; Sun, 17 Jun 2007 18:56:13 GMT (envelope-from scottl@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l5HIuCcI019823 for perforce@freebsd.org; Sun, 17 Jun 2007 18:56:12 GMT (envelope-from scottl@freebsd.org) Date: Sun, 17 Jun 2007 18:56:12 GMT Message-Id: <200706171856.l5HIuCcI019823@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to scottl@freebsd.org using -f From: Scott Long To: Perforce Change Reviews Cc: Subject: PERFORCE change 121867 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Jun 2007 18:56:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=121867 Change 121867 by scottl@scottl-x64 on 2007/06/17 18:55:17 initial, incomplete whack at newbus locking. Affected files ... .. //depot/projects/scottl-camlock/src/sys/kern/subr_bus.c#12 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/kern/subr_bus.c#12 (text+ko) ==== @@ -74,6 +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 devclass { TAILQ_ENTRY(devclass) link; @@ -736,6 +737,7 @@ */ static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses); +MTX_SYSINIT(newbus_lock, &newbus_lock, "Newbus internal lock", MTX_DEF); /** @@ -759,6 +761,8 @@ { devclass_t dc; + mtx_assert(&newbus_lock, MA_OWNED); + PDEBUG(("looking for %s", classname)); if (!classname) return (NULL); @@ -810,7 +814,12 @@ devclass_t devclass_create(const char *classname) { - return (devclass_find_internal(classname, NULL, TRUE)); + devclass_t dc; + + mtx_lock(&newbus_lock); + dc = devclass_find_internal(classname, NULL, TRUE); + mtx_unlock(&newbus_lock); + return (dc); } /** @@ -824,7 +833,12 @@ devclass_t devclass_find(const char *classname) { - return (devclass_find_internal(classname, NULL, FALSE)); + devclass_t dc; + + mtx_lock(&newbus_lock); + dc = devclass_find_internal(classname, NULL, FALSE); + mtx_lock(&newbus_lock); + return (dc); } /** @@ -861,6 +875,7 @@ /* * Make sure the devclass which the driver is implementing exists. */ + mtx_lock(&newbus_lock); devclass_find_internal(driver->name, NULL, TRUE); dl->driver = driver; @@ -871,10 +886,16 @@ * Call BUS_DRIVER_ADDED for any existing busses in this class. */ for (i = 0; i < dc->maxunit; i++) - if (dc->devices[i]) + if (dc->devices[i]) { + /* XXX UNSAFE */ + mtx_unlock(&newbus_lock); BUS_DRIVER_ADDED(dc->devices[i], driver); + mtx_lock(&newbus_lock); + } + } bus_data_generation_update(); + mtx_unlock(&newbus_lock); return (0); } @@ -909,6 +930,7 @@ /* * Find the link structure in the bus' list of drivers. */ + mtx_lock(&newbus_lock); TAILQ_FOREACH(dl, &busclass->drivers, link) { if (dl->driver == driver) break; @@ -917,8 +939,10 @@ if (!dl) { PDEBUG(("%s not found in %s list", driver->name, busclass->name)); + mtx_unlock(&newbus_lock); return (ENOENT); } + TAILQ_REMOVE(&busclass->drivers, dl, link); /* * Disassociate from any devices. We iterate through all the @@ -935,14 +959,16 @@ dev = dc->devices[i]; if (dev->driver == driver && dev->parent && dev->parent->devclass == busclass) { + /* XXX UNSAFE */ + mtx_unlock(&newbus_lock); if ((error = device_detach(dev)) != 0) return (error); device_set_driver(dev, NULL); + mtx_lock(&newbus_lock); } } } - TAILQ_REMOVE(&busclass->drivers, dl, link); free(dl, M_BUS); /* XXX: kobj_mtx */ @@ -951,6 +977,7 @@ kobj_class_free((kobj_class_t) driver); bus_data_generation_update(); + mtx_unlock(&newbus_lock); return (0); } @@ -984,6 +1011,7 @@ /* * Find the link structure in the bus' list of drivers. */ + mtx_lock(&newbus_lock); TAILQ_FOREACH(dl, &busclass->drivers, link) { if (dl->driver == driver) break; @@ -992,6 +1020,7 @@ if (!dl) { PDEBUG(("%s not found in %s list", driver->name, busclass->name)); + mtx_unlock(&newbus_lock); return (ENOENT); } @@ -1010,12 +1039,16 @@ dev = dc->devices[i]; if (dev->driver == driver && dev->parent && dev->parent->devclass == busclass) { + /* XXX UNSAFE */ + mtx_unlock(&newbus_lock); if ((error = device_quiesce(dev)) != 0) return (error); + mtx_lock(&newbus_lock); } } } + mtx_unlock(&newbus_lock); return (0); } @@ -1051,12 +1084,15 @@ kobj_class_t devclass_find_driver(devclass_t dc, const char *classname) { + kobj_class_t kc = NULL; driverlink_t dl; + mtx_lock(&newbus_lock); dl = devclass_find_driver_internal(dc, classname); if (dl) - return (dl->driver); - return (NULL); + kc = dl->driver; + mtx_unlock(&newbus_lock); + return (kc); } /** @@ -1697,8 +1733,7 @@ int result, pri = 0; int hasclass = (child->devclass != 0); - GIANT_REQUIRED; - + mtx_lock(&newbus_lock); dc = dev->devclass; if (!dc) panic("device_probe_child: parent device has no devclass"); @@ -1707,8 +1742,10 @@ * If the state is already probed, then return. However, don't * return if we can rebid this object. */ - if (child->state == DS_ALIVE && (child->flags & DF_REBID) == 0) + if (child->state == DS_ALIVE && (child->flags & DF_REBID) == 0) { + mtx_unlock(&newbus_lock); return (0); + } for (; dc; dc = dc->parent) { for (dl = first_matching_driver(dc, child); @@ -1723,7 +1760,10 @@ resource_int_value(dl->driver->name, child->unit, "flags", &child->devflags); + /* XXX UNSAFE */ + mtx_unlock(&newbus_lock); result = DEVICE_PROBE(child); + mtx_lock(&newbus_lock); /* Reset flags and devclass before the next probe. */ child->devflags = 0; @@ -1815,9 +1855,11 @@ child->state = DS_ALIVE; bus_data_generation_update(); + mtx_unlock(&newbus_lock); return (0); } + mtx_unlock(&newbus_lock); return (ENXIO); } @@ -1854,13 +1896,16 @@ device_t *list; count = 0; + mtx_lock(&newbus_lock); TAILQ_FOREACH(child, &dev->children, link) { count++; } list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO); - if (!list) + if (!list) { + mtx_unlock(&newbus_lock); return (ENOMEM); + } count = 0; TAILQ_FOREACH(child, &dev->children, link) { @@ -1870,6 +1915,7 @@ *devlistp = list; *devcountp = count; + mtx_unlock(&newbus_lock); return (0); } @@ -2230,24 +2276,30 @@ devclass_t dc; int error; + mtx_lock(&newbus_lock); if (!classname) { if (dev->devclass) devclass_delete_device(dev->devclass, dev); + mtx_unlock(&newbus_lock); return (0); } if (dev->devclass) { printf("device_set_devclass: device class already set\n"); + mtx_unlock(&newbus_lock); return (EINVAL); } dc = devclass_find_internal(classname, NULL, TRUE); - if (!dc) + if (!dc) { + mtx_unlock(&newbus_lock); return (ENOMEM); + } error = devclass_add_device(dc, dev); bus_data_generation_update(); + mtx_unlock(&newbus_lock); return (error); } @@ -3729,7 +3781,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); root_devclass = devclass_find_internal("root", NULL, FALSE); + mtx_unlock(&newbus_lock); devinit(); return (0); @@ -3785,7 +3839,9 @@ kobj_class_t driver; dmd = (struct driver_module_data *)arg; + mtx_lock(&newbus_lock); bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE); + mtx_unlock(&newbus_lock); error = 0; switch (what) { @@ -3807,6 +3863,7 @@ * search for drivers in both devclasses for children * of a device using this driver. */ + mtx_lock(&newbus_lock); if (driver->baseclasses) { const char *parentname; parentname = driver->baseclasses[0]->name; @@ -3817,6 +3874,7 @@ *dmd->dmd_devclass = devclass_find_internal(driver->name, NULL, TRUE); } + mtx_unlock(&newbus_lock); break; case MOD_UNLOAD: