From owner-svn-src-all@FreeBSD.ORG Sun Aug 2 14:28:41 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 89F3C106566B; Sun, 2 Aug 2009 14:28:41 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 741C58FC08; Sun, 2 Aug 2009 14:28:41 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n72ESf94016999; Sun, 2 Aug 2009 14:28:41 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n72ESeGr016971; Sun, 2 Aug 2009 14:28:40 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <200908021428.n72ESeGr016971@svn.freebsd.org> From: Attilio Rao Date: Sun, 2 Aug 2009 14:28:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r196037 - in head/sys: dev/aac dev/acpica dev/adb dev/amdtemp dev/amr dev/ata dev/atkbdc dev/bktr dev/drm dev/ips dev/mfi dev/mlx dev/mmc dev/pccbb dev/pst dev/rp dev/sound/pci/hda dev/... X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Aug 2009 14:28:42 -0000 Author: attilio Date: Sun Aug 2 14:28:40 2009 New Revision: 196037 URL: http://svn.freebsd.org/changeset/base/196037 Log: Make the newbus subsystem Giant free by adding the new newbus sxlock. The newbus lock is responsible for protecting newbus internIal structures, device states and devclass flags. It is necessary to hold it when all such datas are accessed. For the other operations, softc locking should ensure enough protection to avoid races. Newbus lock is automatically held when virtual operations on the device and bus are invoked when loading the driver or when the suspend/resume take place. For other 'spourious' operations trying to access/modify the newbus topology, newbus lock needs to be automatically acquired and dropped. For the moment Giant is also acquired in some key point (modules subsystem) in order to avoid problems before the 8.0 release as module handlers could make assumptions about it. This Giant locking should go just after the release happens. Please keep in mind that the public interface can be expanded in order to provide more support, if there are really necessities at some point and also some bugs could arise as long as the patch needs a bit of further testing. Bump __FreeBSD_version in order to reflect the newbus lock introduction. Reviewed by: ed, hps, jhb, imp, mav, scottl No answer by: ariff, thompsa, yongari Tested by: pho, G. Trematerra , Brandon Gooch Sponsored by: Yahoo! Incorporated Approved by: re (ksmith) Modified: head/sys/dev/aac/aac.c head/sys/dev/acpica/acpi.c head/sys/dev/acpica/acpi_battery.c head/sys/dev/acpica/acpi_cpu.c head/sys/dev/acpica/acpi_dock.c head/sys/dev/acpica/acpi_thermal.c head/sys/dev/adb/adb_bus.c head/sys/dev/amdtemp/amdtemp.c head/sys/dev/amr/amr.c head/sys/dev/ata/ata-all.c head/sys/dev/atkbdc/psm.c head/sys/dev/bktr/bktr_os.c head/sys/dev/drm/drm_drv.c head/sys/dev/ips/ips_pci.c head/sys/dev/mfi/mfi.c head/sys/dev/mlx/mlx.c head/sys/dev/mmc/mmc.c head/sys/dev/pccbb/pccbb.c head/sys/dev/pst/pst-iop.c head/sys/dev/rp/rp.c head/sys/dev/sound/pci/hda/hdac.c head/sys/dev/twe/twe.c head/sys/dev/usb/controller/usb_controller.c head/sys/dev/usb/input/ukbd.c head/sys/dev/usb/net/usb_ethernet.c head/sys/dev/usb/usb_compat_linux.c head/sys/dev/usb/usb_dev.c head/sys/dev/usb/usb_handle_request.c head/sys/dev/usb/usb_hub.c head/sys/dev/usb/wlan/if_upgt.c head/sys/dev/xen/blkback/blkback.c head/sys/dev/xen/netback/netback.c head/sys/i386/acpica/acpi_machdep.c head/sys/i386/bios/smapi.c head/sys/i386/bios/smbios.c head/sys/i386/bios/vpd.c head/sys/kern/subr_bus.c head/sys/pc98/cbus/fdc.c head/sys/sys/bus.h head/sys/sys/param.h head/sys/xen/xenbus/xenbus_probe.c Modified: head/sys/dev/aac/aac.c ============================================================================== --- head/sys/dev/aac/aac.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/aac/aac.c Sun Aug 2 14:28:40 2009 (r196037) @@ -3270,10 +3270,10 @@ aac_handle_aif(struct aac_softc *sc, str while (co != NULL) { if (co->co_found == 0) { mtx_unlock(&sc->aac_io_lock); - mtx_lock(&Giant); + newbus_xlock(); device_delete_child(sc->aac_dev, co->co_disk); - mtx_unlock(&Giant); + newbus_xunlock(); mtx_lock(&sc->aac_io_lock); co_next = TAILQ_NEXT(co, co_link); mtx_lock(&sc->aac_container_lock); @@ -3291,9 +3291,9 @@ aac_handle_aif(struct aac_softc *sc, str /* Attach the newly created containers */ if (added) { mtx_unlock(&sc->aac_io_lock); - mtx_lock(&Giant); + newbus_xlock(); bus_generic_attach(sc->aac_dev); - mtx_unlock(&Giant); + newbus_xunlock(); mtx_lock(&sc->aac_io_lock); } Modified: head/sys/dev/acpica/acpi.c ============================================================================== --- head/sys/dev/acpica/acpi.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/acpica/acpi.c Sun Aug 2 14:28:40 2009 (r196037) @@ -675,8 +675,6 @@ acpi_suspend(device_t dev) device_t child, *devlist; int error, i, numdevs, pstate; - GIANT_REQUIRED; - /* First give child devices a chance to suspend. */ error = bus_generic_suspend(dev); if (error) @@ -719,8 +717,6 @@ acpi_resume(device_t dev) int i, numdevs, error; device_t child, *devlist; - GIANT_REQUIRED; - /* * Put all devices in D0 before resuming them. Call _S0D on each one * since some systems expect this. @@ -745,8 +741,6 @@ static int acpi_shutdown(device_t dev) { - GIANT_REQUIRED; - /* Allow children to shutdown first. */ bus_generic_shutdown(dev); @@ -2534,11 +2528,7 @@ acpi_EnterSleepState(struct acpi_softc * thread_unlock(curthread); #endif - /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE - * drivers need this. - */ - mtx_lock(&Giant); + newbus_xlock(); slp_state = ACPI_SS_NONE; @@ -2611,7 +2601,7 @@ backout: if (slp_state >= ACPI_SS_SLEPT) acpi_enable_fixed_events(sc); - mtx_unlock(&Giant); + newbus_xunlock(); #ifdef SMP thread_lock(curthread); Modified: head/sys/dev/acpica/acpi_battery.c ============================================================================== --- head/sys/dev/acpica/acpi_battery.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/acpica/acpi_battery.c Sun Aug 2 14:28:40 2009 (r196037) @@ -329,6 +329,7 @@ acpi_battery_find_dev(u_int logical_unit dev = NULL; found_unit = 0; + newbus_slock(); batt_dc = devclass_find("battery"); maxunit = devclass_get_maxunit(batt_dc); for (i = 0; i < maxunit; i++) { @@ -340,6 +341,7 @@ acpi_battery_find_dev(u_int logical_unit found_unit++; dev = NULL; } + newbus_sunlock(); return (dev); } @@ -369,13 +371,17 @@ acpi_battery_ioctl(u_long cmd, caddr_t a */ switch (cmd) { case ACPIIO_BATT_GET_UNITS: + newbus_slock(); *(int *)addr = acpi_battery_get_units(); + newbus_sunlock(); error = 0; break; case ACPIIO_BATT_GET_BATTINFO: if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS) { bzero(&ioctl_arg->battinfo, sizeof(ioctl_arg->battinfo)); + newbus_slock(); error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo); + newbus_sunlock(); } break; case ACPIIO_BATT_GET_BIF: @@ -416,6 +422,11 @@ acpi_battery_sysctl(SYSCTL_HANDLER_ARGS) { int val, error; + /* + * Tolerate a race here because newbus lock can't be acquired before + * acpi_battery_get_battinfo() as it can create a LOR with the sysctl + * lock. + */ acpi_battery_get_battinfo(NULL, &acpi_battery_battinfo); val = *(u_int *)oidp->oid_arg1; error = sysctl_handle_int(oidp, &val, 0, req); @@ -427,6 +438,10 @@ acpi_battery_units_sysctl(SYSCTL_HANDLER { int count, error; + /* + * Tolerate a race here in order to avoid a LOR between sysctl lock + * and newbus lock. + */ count = acpi_battery_get_units(); error = sysctl_handle_int(oidp, &count, 0, req); return (error); Modified: head/sys/dev/acpica/acpi_cpu.c ============================================================================== --- head/sys/dev/acpica/acpi_cpu.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/acpica/acpi_cpu.c Sun Aug 2 14:28:40 2009 (r196037) @@ -732,7 +732,9 @@ acpi_cpu_startup(void *arg) int i; /* Get set of CPU devices */ + newbus_slock(); devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices); + newbus_sunlock(); /* * Setup any quirks that might necessary now that we have probed Modified: head/sys/dev/acpica/acpi_dock.c ============================================================================== --- head/sys/dev/acpica/acpi_dock.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/acpica/acpi_dock.c Sun Aug 2 14:28:40 2009 (r196037) @@ -188,12 +188,12 @@ acpi_dock_attach_later(void *context) dev = (device_t)context; + newbus_xlock(); if (!device_is_enabled(dev)) device_enable(dev); - mtx_lock(&Giant); device_probe_and_attach(dev); - mtx_unlock(&Giant); + newbus_xunlock(); } static ACPI_STATUS @@ -299,11 +299,11 @@ acpi_dock_eject_child(ACPI_HANDLE handle "ejecting device for %s\n", acpi_name(handle)); dev = acpi_get_device(handle); + newbus_xlock(); if (dev != NULL && device_is_attached(dev)) { - mtx_lock(&Giant); device_detach(dev); - mtx_unlock(&Giant); } + newbus_xunlock(); acpi_SetInteger(handle, "_EJ0", 0); out: Modified: head/sys/dev/acpica/acpi_thermal.c ============================================================================== --- head/sys/dev/acpica/acpi_thermal.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/acpica/acpi_thermal.c Sun Aug 2 14:28:40 2009 (r196037) @@ -936,6 +936,8 @@ acpi_tz_thread(void *arg) sc = NULL; for (;;) { + newbus_slock(); + /* If the number of devices has changed, re-evaluate. */ if (devclass_get_count(acpi_tz_devclass) != devcount) { if (devs != NULL) { @@ -948,6 +950,7 @@ acpi_tz_thread(void *arg) for (i = 0; i < devcount; i++) sc[i] = device_get_softc(devs[i]); } + newbus_sunlock(); /* Check for temperature events and act on them. */ for (i = 0; i < devcount; i++) { Modified: head/sys/dev/adb/adb_bus.c ============================================================================== --- head/sys/dev/adb/adb_bus.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/adb/adb_bus.c Sun Aug 2 14:28:40 2009 (r196037) @@ -113,6 +113,7 @@ adb_bus_enumerate(void *xdev) uint8_t i, next_free; uint16_t r3; + newbus_xlock(); sc->sc_dev = dev; sc->parent = device_get_parent(dev); @@ -187,6 +188,7 @@ adb_bus_enumerate(void *xdev) } bus_generic_attach(dev); + newbus_xunlock(); config_intrhook_disestablish(&sc->enum_hook); } Modified: head/sys/dev/amdtemp/amdtemp.c ============================================================================== --- head/sys/dev/amdtemp/amdtemp.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/amdtemp/amdtemp.c Sun Aug 2 14:28:40 2009 (r196037) @@ -269,6 +269,7 @@ amdtemp_intrhook(void *arg) /* * dev.cpu.N.temperature. */ + newbus_xlock(); nexus = device_find_child(root_bus, "nexus", 0); acpi = device_find_child(nexus, "acpi", 0); @@ -285,6 +286,7 @@ amdtemp_intrhook(void *arg) "Max of sensor 0 / 1"); } } + newbus_xunlock(); config_intrhook_disestablish(&sc->sc_ich); } Modified: head/sys/dev/amr/amr.c ============================================================================== --- head/sys/dev/amr/amr.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/amr/amr.c Sun Aug 2 14:28:40 2009 (r196037) @@ -90,6 +90,10 @@ __FBSDID("$FreeBSD$"); SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD, 0, "AMR driver parameters"); +/* + * In order to get rid of Giant, amr_state should be protected by + * a proper softc lock for the cdev operations. + */ static d_open_t amr_open; static d_close_t amr_close; static d_ioctl_t amr_ioctl; @@ -312,9 +316,11 @@ amr_startup(void *arg) config_intrhook_disestablish(&sc->amr_ich); sc->amr_ich.ich_func = NULL; + newbus_xlock(); /* get up-to-date drive information */ if (amr_query_controller(sc)) { device_printf(sc->amr_dev, "can't scan controller for drives\n"); + newbus_xunlock(); return; } @@ -347,6 +353,7 @@ amr_startup(void *arg) /* interrupts will be enabled before we do anything more */ sc->amr_state |= AMR_STATE_INTEN; + newbus_xunlock(); /* * Start the timeout routine. @@ -434,7 +441,11 @@ static int amr_open(struct cdev *dev, int flags, int fmt, struct thread *td) { int unit = dev2unit(dev); - struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); + struct amr_softc *sc; + + newbus_slock(); + sc = devclass_get_softc(devclass_find("amr"), unit); + newbus_sunlock(); debug_called(1); @@ -490,7 +501,11 @@ static int amr_close(struct cdev *dev, int flags, int fmt, struct thread *td) { int unit = dev2unit(dev); - struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); + struct amr_softc *sc; + + newbus_slock(); + sc = devclass_get_softc(devclass_find("amr"), unit); + newbus_sunlock(); debug_called(1); @@ -507,6 +522,7 @@ amr_rescan_drives(struct cdev *dev) struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; int i, error = 0; + newbus_xlock(); sc->amr_state |= AMR_STATE_REMAP_LD; while (sc->amr_busyslots) { device_printf(sc->amr_dev, "idle controller\n"); @@ -530,6 +546,7 @@ amr_rescan_drives(struct cdev *dev) sc->amr_drive[i].al_disk = 0; } } + newbus_xunlock(); shutdown_out: amr_startup(sc); @@ -805,7 +822,9 @@ amr_ioctl(struct cdev *dev, u_long cmd, struct amr_linux_ioctl ali; int adapter, error; + newbus_slock(); devclass = devclass_find("amr"); + newbus_sunlock(); if (devclass == NULL) return (ENOENT); Modified: head/sys/dev/ata/ata-all.c ============================================================================== --- head/sys/dev/ata/ata-all.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/ata/ata-all.c Sun Aug 2 14:28:40 2009 (r196037) @@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$"); static d_ioctl_t ata_ioctl; static struct cdevsw ata_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, /* we need this as newbus isn't mpsafe */ .d_ioctl = ata_ioctl, .d_name = "ata", }; @@ -204,7 +203,9 @@ ata_conn_event(void *context, int dummy) { device_t dev = (device_t)context; + newbus_xlock(); ata_reinit(dev); + newbus_xunlock(); } int @@ -246,7 +247,6 @@ ata_reinit(device_t dev) /* reinit the children and delete any that fails */ if (!device_get_children(dev, &children, &nchildren)) { - mtx_lock(&Giant); /* newbus suckage it needs Giant */ for (i = 0; i < nchildren; i++) { /* did any children go missing ? */ if (children[i] && device_is_attached(children[i]) && @@ -269,7 +269,6 @@ ata_reinit(device_t dev) } } free(children, M_TEMP); - mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ } /* if we still have a good request put it on the queue again */ @@ -395,6 +394,7 @@ ata_ioctl(struct cdev *dev, u_long cmd, int *value = (int *)data; int i, nchildren, error = ENOTTY; + newbus_xlock(); switch (cmd) { case IOCATAGMAXCHANNEL: /* In case we have channel 0..n this will return n+1. */ @@ -405,32 +405,40 @@ ata_ioctl(struct cdev *dev, u_long cmd, case IOCATAREINIT: if (*value >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) + !device_is_attached(device)) { + newbus_xunlock(); return ENXIO; + } error = ata_reinit(device); break; case IOCATAATTACH: if (*value >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) + !device_is_attached(device)) { + newbus_xunlock(); return ENXIO; + } error = DEVICE_ATTACH(device); break; case IOCATADETACH: if (*value >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) + !device_is_attached(device)) { + newbus_xunlock(); return ENXIO; + } error = DEVICE_DETACH(device); break; case IOCATADEVICES: if (devices->channel >= devclass_get_maxunit(ata_devclass) || !(device = devclass_get_device(ata_devclass, devices->channel)) || - !device_is_attached(device)) + !device_is_attached(device)) { + newbus_xunlock(); return ENXIO; + } bzero(devices->name[0], 32); bzero(&devices->params[0], sizeof(struct ata_params)); bzero(devices->name[1], 32); @@ -465,6 +473,7 @@ ata_ioctl(struct cdev *dev, u_long cmd, if (ata_raid_ioctl_func) error = ata_raid_ioctl_func(cmd, data); } + newbus_xunlock(); return error; } @@ -572,7 +581,7 @@ ata_boot_attach(void) struct ata_channel *ch; int ctlr; - mtx_lock(&Giant); /* newbus suckage it needs Giant */ + newbus_xlock(); /* kick of probe and attach on all channels */ for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) { @@ -587,8 +596,7 @@ ata_boot_attach(void) free(ata_delayed_attach, M_TEMP); ata_delayed_attach = NULL; } - - mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ + newbus_xunlock(); } @@ -717,7 +725,6 @@ ata_identify(device_t dev) if (bootverbose) device_printf(dev, "Identifying devices: %08x\n", ch->devices); - mtx_lock(&Giant); /* Skip existing devices. */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) { @@ -729,10 +736,8 @@ ata_identify(device_t dev) /* Create new devices. */ if (bootverbose) device_printf(dev, "New devices: %08x\n", n); - if (n == 0) { - mtx_unlock(&Giant); + if (n == 0) return (0); - } for (i = 0; i < ATA_PM; ++i) { if (n & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) { int unit = -1; @@ -775,7 +780,6 @@ ata_identify(device_t dev) } bus_generic_probe(dev); bus_generic_attach(dev); - mtx_unlock(&Giant); return 0; } Modified: head/sys/dev/atkbdc/psm.c ============================================================================== --- head/sys/dev/atkbdc/psm.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/atkbdc/psm.c Sun Aug 2 14:28:40 2009 (r196037) @@ -1488,7 +1488,9 @@ psmopen(struct cdev *dev, int flag, int if (sc->state & PSM_OPEN) return (EBUSY); + newbus_xlock(); device_busy(devclass_get_device(psm_devclass, unit)); + newbus_xunlock(); /* Initialize state */ sc->mode.level = sc->dflt_mode.level; @@ -1643,7 +1645,9 @@ psmclose(struct cdev *dev, int flag, int /* close is almost always successful */ sc->state &= ~PSM_OPEN; kbdc_lock(sc->kbdc, FALSE); + newbus_xlock(); device_unbusy(devclass_get_device(psm_devclass, unit)); + newbus_xunlock(); return (0); } Modified: head/sys/dev/bktr/bktr_os.c ============================================================================== --- head/sys/dev/bktr/bktr_os.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/bktr/bktr_os.c Sun Aug 2 14:28:40 2009 (r196037) @@ -597,7 +597,9 @@ bktr_open( struct cdev *dev, int flags, return( ENXIO ); /* Record that the device is now busy */ + newbus_xlock(); device_busy(devclass_get_device(bktr_devclass, unit)); + newbus_xunlock(); if (bt848_card != -1) { @@ -668,8 +670,11 @@ bktr_open( struct cdev *dev, int flags, } /* If there was an error opening the device, undo the busy status */ - if (result != 0) + if (result != 0) { + newbus_xlock(); device_unbusy(devclass_get_device(bktr_devclass, unit)); + newbus_xunlock(); + } return( result ); } @@ -689,6 +694,7 @@ bktr_close( struct cdev *dev, int flags, /* Get the device data */ bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); if (bktr == NULL) { + /* the device is no longer valid/functioning */ return (ENXIO); } @@ -705,10 +711,11 @@ bktr_close( struct cdev *dev, int flags, break; default: return (ENXIO); - break; } + newbus_xlock(); device_unbusy(devclass_get_device(bktr_devclass, unit)); + newbus_xunlock(); return( result ); } Modified: head/sys/dev/drm/drm_drv.c ============================================================================== --- head/sys/dev/drm/drm_drv.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/drm/drm_drv.c Sun Aug 2 14:28:40 2009 (r196037) @@ -614,11 +614,13 @@ int drm_open(struct cdev *kdev, int flag if (!retcode) { atomic_inc(&dev->counts[_DRM_STAT_OPENS]); + newbus_xlock(); DRM_LOCK(); device_busy(dev->device); if (!dev->open_count++) retcode = drm_firstopen(dev); DRM_UNLOCK(); + newbus_xunlock(); } return retcode; @@ -632,6 +634,11 @@ void drm_close(void *data) DRM_DEBUG("open_count = %d\n", dev->open_count); + /* + * We require to lock newbus here for handling device_unbusy() and + * avoid a LOR with DRM_LOCK. + */ + newbus_xlock(); DRM_LOCK(); if (dev->driver->preclose != NULL) @@ -708,6 +715,7 @@ void drm_close(void *data) } DRM_UNLOCK(); + newbus_xunlock(); } /* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. Modified: head/sys/dev/ips/ips_pci.c ============================================================================== --- head/sys/dev/ips/ips_pci.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/ips/ips_pci.c Sun Aug 2 14:28:40 2009 (r196037) @@ -173,10 +173,12 @@ ips_intrhook(void *arg) struct ips_softc *sc = (struct ips_softc *)arg; config_intrhook_disestablish(&sc->ips_ich); + newbus_xlock(); if (ips_adapter_init(sc)) ips_pci_free(sc); else sc->configured = 1; + newbus_xunlock(); } static int ips_pci_free(ips_softc_t *sc) Modified: head/sys/dev/mfi/mfi.c ============================================================================== --- head/sys/dev/mfi/mfi.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/mfi/mfi.c Sun Aug 2 14:28:40 2009 (r196037) @@ -1327,11 +1327,11 @@ mfi_add_ld_complete(struct mfi_command * mfi_release_command(cm); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_xlock(); if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) { device_printf(sc->mfi_dev, "Failed to add logical disk\n"); free(ld_info, M_MFIBUF); - mtx_unlock(&Giant); + newbus_xunlock(); mtx_lock(&sc->mfi_io_lock); return; } @@ -1339,7 +1339,7 @@ mfi_add_ld_complete(struct mfi_command * device_set_ivars(child, ld_info); device_set_desc(child, "MFI Logical Disk"); bus_generic_attach(sc->mfi_dev); - mtx_unlock(&Giant); + newbus_xunlock(); mtx_lock(&sc->mfi_io_lock); } @@ -1805,9 +1805,9 @@ mfi_check_command_post(struct mfi_softc KASSERT(ld != NULL, ("volume dissappeared")); if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_xlock(); device_delete_child(sc->mfi_dev, ld->ld_dev); - mtx_unlock(&Giant); + newbus_xunlock(); mtx_lock(&sc->mfi_io_lock); } else mfi_disk_enable(ld); @@ -1815,11 +1815,11 @@ mfi_check_command_post(struct mfi_softc case MFI_DCMD_CFG_CLEAR: if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_xlock(); TAILQ_FOREACH_SAFE(ld, &sc->mfi_ld_tqh, ld_link, ldn) { device_delete_child(sc->mfi_dev, ld->ld_dev); } - mtx_unlock(&Giant); + newbus_xunlock(); mtx_lock(&sc->mfi_io_lock); } else { TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) @@ -1985,7 +1985,9 @@ mfi_ioctl(struct cdev *dev, u_long cmd, adapter = ioc->mfi_adapter_no; if (device_get_unit(sc->mfi_dev) == 0 && adapter != 0) { + newbus_slock(); devclass = devclass_find("mfi"); + newbus_sunlock(); sc = devclass_get_softc(devclass, adapter); } mtx_lock(&sc->mfi_io_lock); @@ -2173,7 +2175,9 @@ out: struct mfi_linux_ioc_packet l_ioc; int adapter; + newbus_slock(); devclass = devclass_find("mfi"); + newbus_sunlock(); if (devclass == NULL) return (ENOENT); @@ -2194,7 +2198,9 @@ out: struct mfi_linux_ioc_aen l_aen; int adapter; + newbus_slock(); devclass = devclass_find("mfi"); + newbus_sunlock(); if (devclass == NULL) return (ENOENT); Modified: head/sys/dev/mlx/mlx.c ============================================================================== --- head/sys/dev/mlx/mlx.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/mlx/mlx.c Sun Aug 2 14:28:40 2009 (r196037) @@ -772,7 +772,9 @@ mlx_ioctl(struct cdev *dev, u_long cmd, * Scan the controller to see whether new drives have appeared. */ case MLX_RESCAN_DRIVES: + newbus_xlock(); mlx_startup(sc); + newbus_xunlock(); return(0); /* Modified: head/sys/dev/mmc/mmc.c ============================================================================== --- head/sys/dev/mmc/mmc.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/mmc/mmc.c Sun Aug 2 14:28:40 2009 (r196037) @@ -1496,7 +1496,9 @@ mmc_delayed_attach(void *xsc) { struct mmc_softc *sc = xsc; + newbus_xlock(); mmc_scan(sc); + newbus_xunlock(); config_intrhook_disestablish(&sc->config_intrhook); } Modified: head/sys/dev/pccbb/pccbb.c ============================================================================== --- head/sys/dev/pccbb/pccbb.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/pccbb/pccbb.c Sun Aug 2 14:28:40 2009 (r196037) @@ -464,14 +464,7 @@ cbb_event_thread(void *arg) sc->flags |= CBB_KTHREAD_RUNNING; while ((sc->flags & CBB_KTHREAD_DONE) == 0) { mtx_unlock(&sc->mtx); - /* - * We take out Giant here because we need it deep, - * down in the bowels of the vm system for mapping the - * memory we need to read the CIS. In addition, since - * we are adding/deleting devices from the dev tree, - * and that code isn't MP safe, we have to hold Giant. - */ - mtx_lock(&Giant); + newbus_xlock(); status = cbb_get(sc, CBB_SOCKET_STATE); DPRINTF(("Status is 0x%x\n", status)); if (!CBB_CARD_PRESENT(status)) { @@ -497,7 +490,7 @@ cbb_event_thread(void *arg) not_a_card = 0; /* We know card type */ cbb_insert(sc); } - mtx_unlock(&Giant); + newbus_xunlock(); /* * First time through we need to tell mountroot that we're Modified: head/sys/dev/pst/pst-iop.c ============================================================================== --- head/sys/dev/pst/pst-iop.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/pst/pst-iop.c Sun Aug 2 14:28:40 2009 (r196037) @@ -152,7 +152,9 @@ iop_attach(void *arg) break; case I2O_CLASS_RANDOM_BLOCK_STORAGE: + newbus_xlock(); pst_add_raid(sc, &sc->lct[i]); + newbus_xunlock(); break; } } Modified: head/sys/dev/rp/rp.c ============================================================================== --- head/sys/dev/rp/rp.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/rp/rp.c Sun Aug 2 14:28:40 2009 (r196037) @@ -903,7 +903,9 @@ rpopen(struct tty *tp) rp_callout_handle = timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); + newbus_xlock(); device_busy(rp->rp_ctlp->dev); + newbus_xunlock(); return(0); } @@ -914,7 +916,9 @@ rpclose(struct tty *tp) rp = tty_softc(tp); rphardclose(tp); + newbus_xlock(); device_unbusy(rp->rp_ctlp->dev); + newbus_xunlock(); } static void Modified: head/sys/dev/sound/pci/hda/hdac.c ============================================================================== --- head/sys/dev/sound/pci/hda/hdac.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/sound/pci/hda/hdac.c Sun Aug 2 14:28:40 2009 (r196037) @@ -7435,6 +7435,7 @@ hdac_attach2(void *arg) quirks_on, quirks_off); ); + newbus_xlock(); hdac_lock(sc); /* Remove ourselves from the config hooks */ @@ -7674,6 +7675,7 @@ hdac_attach2(void *arg) SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, "pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev), sysctl_hdac_pindump, "I", "Dump pin states/data"); + newbus_xunlock(); } /**************************************************************************** Modified: head/sys/dev/twe/twe.c ============================================================================== --- head/sys/dev/twe/twe.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/twe/twe.c Sun Aug 2 14:28:40 2009 (r196037) @@ -294,8 +294,10 @@ twe_init(struct twe_softc *sc) /* * Scan for drives */ + newbus_xlock(); for (i = 0; i < TWE_MAX_UNITS; i++) twe_add_unit(sc, i); + newbus_xunlock(); /* * Initialise connection with controller. @@ -621,11 +623,15 @@ twe_ioctl(struct twe_softc *sc, int ioct break; case TWEIO_ADD_UNIT: + newbus_xlock(); error = twe_add_unit(sc, td->td_unit); + newbus_xunlock(); break; case TWEIO_DEL_UNIT: + newbus_xlock(); error = twe_del_unit(sc, td->td_unit); + newbus_xunlock(); break; /* XXX implement ATA PASSTHROUGH */ Modified: head/sys/dev/usb/controller/usb_controller.c ============================================================================== --- head/sys/dev/usb/controller/usb_controller.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/usb/controller/usb_controller.c Sun Aug 2 14:28:40 2009 (r196037) @@ -143,9 +143,7 @@ usb_attach(device_t dev) } if (usb_post_init_called) { - mtx_lock(&Giant); usb_attach_sub(dev, bus); - mtx_unlock(&Giant); usb_needs_explore(bus, 1); } return (0); /* return success */ @@ -228,20 +226,13 @@ usb_bus_explore(struct usb_proc_msg *pm) } USB_BUS_UNLOCK(bus); - mtx_lock(&Giant); - /* * First update the USB power state! */ usb_bus_powerd(bus); - /* - * Explore the Root USB HUB. This call can sleep, - * exiting Giant, which is actually Giant. - */ - (udev->hub->explore) (udev); - - mtx_unlock(&Giant); + /* Explore the Root USB HUB. */ + (udev->hub->explore) (udev); USB_BUS_LOCK(bus); } if (bus->bus_roothold != NULL) { @@ -269,7 +260,7 @@ usb_bus_detach(struct usb_proc_msg *pm) device_set_softc(dev, NULL); USB_BUS_UNLOCK(bus); - mtx_lock(&Giant); + newbus_xlock(); /* detach children first */ bus_generic_detach(dev); @@ -281,7 +272,7 @@ usb_bus_detach(struct usb_proc_msg *pm) usb_free_device(udev, USB_UNCFG_FLAG_FREE_EP0); - mtx_unlock(&Giant); + newbus_xunlock(); USB_BUS_LOCK(bus); /* clear bdev variable last */ bus->bdev = NULL; @@ -350,7 +341,7 @@ usb_bus_attach(struct usb_proc_msg *pm) } USB_BUS_UNLOCK(bus); - mtx_lock(&Giant); /* XXX not required by USB */ + newbus_xlock(); /* default power_mask value */ bus->hw_power_state = @@ -383,7 +374,7 @@ usb_bus_attach(struct usb_proc_msg *pm) err = USB_ERR_NOMEM; } - mtx_unlock(&Giant); + newbus_xunlock(); USB_BUS_LOCK(bus); if (err) { @@ -472,7 +463,7 @@ usb_post_init(void *arg) int max; int n; - mtx_lock(&Giant); + newbus_xlock(); usb_devclass_ptr = devclass_find("usbus"); @@ -483,11 +474,8 @@ usb_post_init(void *arg) dev = devclass_get_device(dc, n); if (dev && device_is_attached(dev)) { bus = device_get_ivars(dev); - if (bus) { - mtx_lock(&Giant); + if (bus) usb_attach_sub(dev, bus); - mtx_unlock(&Giant); - } } } } else { @@ -499,7 +487,7 @@ usb_post_init(void *arg) usb_needs_explore_all(); - mtx_unlock(&Giant); + newbus_xunlock(); } SYSINIT(usb_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_post_init, NULL); Modified: head/sys/dev/usb/input/ukbd.c ============================================================================== --- head/sys/dev/usb/input/ukbd.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/usb/input/ukbd.c Sun Aug 2 14:28:40 2009 (r196037) @@ -745,7 +745,7 @@ ukbd_attach(device_t dev) uint16_t n; uint16_t hid_len; - mtx_assert(&Giant, MA_OWNED); + mtx_lock(&Giant); kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0); @@ -854,9 +854,6 @@ ukbd_attach(device_t dev) if (bootverbose) { genkbd_diag(kbd, bootverbose); } - /* lock keyboard mutex */ - - mtx_lock(&Giant); /* start the keyboard */ @@ -879,7 +876,7 @@ ukbd_detach(device_t dev) struct ukbd_softc *sc = device_get_softc(dev); int error; - mtx_assert(&Giant, MA_OWNED); + mtx_lock(&Giant); DPRINTF("\n"); @@ -916,6 +913,8 @@ ukbd_detach(device_t dev) usb_callout_drain(&sc->sc_callout); + mtx_unlock(&Giant); + DPRINTF("%s: disconnected\n", device_get_nameunit(dev)); @@ -927,9 +926,9 @@ ukbd_resume(device_t dev) { struct ukbd_softc *sc = device_get_softc(dev); - mtx_assert(&Giant, MA_OWNED); - + mtx_lock(&Giant); ukbd_clear_state(&sc->sc_kbd); + mtx_unlock(&Giant); return (0); } Modified: head/sys/dev/usb/net/usb_ethernet.c ============================================================================== --- head/sys/dev/usb/net/usb_ethernet.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/usb/net/usb_ethernet.c Sun Aug 2 14:28:40 2009 (r196037) @@ -221,10 +221,10 @@ ue_attach_post_task(struct usb_proc_msg if (ue->ue_methods->ue_mii_upd != NULL && ue->ue_methods->ue_mii_sts != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ + newbus_xlock(); error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus, ue_ifmedia_upd, ue->ue_methods->ue_mii_sts); - mtx_unlock(&Giant); + newbus_xunlock(); if (error) { device_printf(ue->ue_dev, "MII without any PHY\n"); goto error; @@ -279,9 +279,12 @@ uether_ifdetach(struct usb_ether *ue) /* detach miibus */ if (ue->ue_miibus != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ + + /* + * It is up to the callers to provide the correct + * newbus locking. + */ device_delete_child(ue->ue_dev, ue->ue_miibus); - mtx_unlock(&Giant); } /* detach ethernet */ Modified: head/sys/dev/usb/usb_compat_linux.c ============================================================================== --- head/sys/dev/usb/usb_compat_linux.c Sun Aug 2 14:25:26 2009 (r196036) +++ head/sys/dev/usb/usb_compat_linux.c Sun Aug 2 14:28:40 2009 (r196037) @@ -215,14 +215,12 @@ usb_linux_probe(device_t dev) if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } - mtx_lock(&Giant); LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) { if (usb_linux_lookup_id(udrv->id_table, uaa)) { err = 0; break; } } - mtx_unlock(&Giant); return (err); } @@ -239,9 +237,7 @@ usb_linux_get_usb_driver(struct usb_linu { struct usb_driver *udrv; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***