From c6df6f5322f7004c71216391e1c0b374d853704a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 9 Dec 2021 17:04:45 -0700 Subject: [PATCH] Create wrapper for Giant taken for newbus Create a wrapper for newbus to take giant and for busses to take it too. bus_topo_lock() should be called before interacting with newbus routines and unlocked with bus_topo_unlock(). If you need the topology lock for some reason, bus_topo_mtx() will provide that. Sponsored by: Netflix Reviewed by: mav Differential Revision: https://reviews.freebsd.org/D31831 --- .../linuxkpi/common/include/linux/device.h | 8 ++--- sys/compat/linuxkpi/common/src/linux_pci.c | 12 +++---- sys/compat/linuxkpi/common/src/linux_usb.c | 2 ++ sys/dev/aac/aac.c | 8 ++--- sys/dev/acpica/acpi.c | 7 ++-- sys/dev/acpica/acpi_dock.c | 8 ++--- sys/dev/acpica/acpi_pci.c | 16 +++++----- sys/dev/bhnd/cores/chipc/chipc.c | 6 ++-- sys/dev/cardbus/cardbus.c | 8 ++--- sys/dev/drm2/drm_dp_iic_helper.c | 8 ++--- sys/dev/hyperv/pcib/vmbus_pcib.c | 4 +-- sys/dev/ida/ida.c | 4 +-- sys/dev/mfi/mfi.c | 32 +++++++++---------- sys/dev/mfi/mfi_cam.c | 4 +-- sys/dev/mlx/mlx.c | 8 ++--- sys/dev/mlx5/mlx5_core/mlx5_fwdump.c | 4 +-- sys/dev/mlx5/mlx5_core/mlx5_health.c | 5 +-- sys/dev/pccard/pccard.c | 4 +-- sys/dev/pci/pci_pci.c | 2 +- sys/dev/pci/pci_user.c | 9 ++++-- sys/dev/sdio/sdiob.c | 4 +-- sys/dev/twe/twe_freebsd.c | 10 +++--- sys/dev/usb/controller/usb_controller.c | 8 ++--- sys/dev/usb/net/if_axe.c | 4 +-- sys/dev/usb/net/if_axge.c | 4 +-- sys/dev/usb/net/if_muge.c | 4 +-- sys/dev/usb/net/if_smsc.c | 4 +-- sys/dev/usb/net/if_ure.c | 4 +-- sys/dev/usb/net/usb_ethernet.c | 9 +++--- sys/dev/usb/usb_device.c | 10 +++--- sys/dev/xen/control/control.c | 9 +++--- sys/kern/subr_bus.c | 27 ++++++++++++++-- sys/net/iflib_clone.c | 12 +++---- sys/sys/bus.h | 10 +++++- sys/xen/xenbus/xenbusb.c | 7 ++-- 35 files changed, 157 insertions(+), 128 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index abafcd7ba5c4..e79a101169c6 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -465,9 +465,9 @@ device_unregister(struct device *dev) dev->bsddev = NULL; if (bsddev != NULL && dev->bsddev_attached_here) { - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(device_get_parent(bsddev), bsddev); - mtx_unlock(&Giant); + bus_topo_unlock(); } put_device(dev); } @@ -481,9 +481,9 @@ device_del(struct device *dev) dev->bsddev = NULL; if (bsddev != NULL && dev->bsddev_attached_here) { - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(device_get_parent(bsddev), bsddev); - mtx_unlock(&Giant); + bus_topo_unlock(); } } diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index bf28c10fbf96..c388da87ac15 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -646,10 +646,10 @@ _linux_pci_register_driver(struct pci_driver *pdrv, devclass_t dc) pdrv->bsddriver.methods = pci_methods; pdrv->bsddriver.size = sizeof(struct pci_dev); - mtx_lock(&Giant); + bus_topo_lock(); error = devclass_add_driver(dc, &pdrv->bsddriver, BUS_PASS_DEFAULT, &pdrv->bsdclass); - mtx_unlock(&Giant); + bus_topo_unlock(); return (-error); } @@ -739,10 +739,10 @@ linux_pci_unregister_driver(struct pci_driver *pdrv) spin_lock(&pci_lock); list_del(&pdrv->node); spin_unlock(&pci_lock); - mtx_lock(&Giant); + bus_topo_lock(); if (bus != NULL) devclass_delete_driver(bus, &pdrv->bsddriver); - mtx_unlock(&Giant); + bus_topo_unlock(); } void @@ -755,10 +755,10 @@ linux_pci_unregister_drm_driver(struct pci_driver *pdrv) spin_lock(&pci_lock); list_del(&pdrv->node); spin_unlock(&pci_lock); - mtx_lock(&Giant); + bus_topo_lock(); if (bus != NULL) devclass_delete_driver(bus, &pdrv->bsddriver); - mtx_unlock(&Giant); + bus_topo_unlock(); } CTASSERT(sizeof(dma_addr_t) <= sizeof(uint64_t)); diff --git a/sys/compat/linuxkpi/common/src/linux_usb.c b/sys/compat/linuxkpi/common/src/linux_usb.c index 72aa561fcfbb..fec5936e7640 100644 --- a/sys/compat/linuxkpi/common/src/linux_usb.c +++ b/sys/compat/linuxkpi/common/src/linux_usb.c @@ -1166,7 +1166,9 @@ usb_linux_deregister(void *arg) LIST_FOREACH(sc, &usb_linux_attached_list, sc_attached_list) { if (sc->sc_udrv == drv) { mtx_unlock(&Giant); + bus_topo_lock(); device_detach(sc->sc_fbsd_dev); + bus_topo_unlock(); goto repeat; } } diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 6e3cca084fe0..c783c390872b 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -3305,10 +3305,10 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) while (co != NULL) { if (co->co_found == 0) { mtx_unlock(&sc->aac_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(sc->aac_dev, co->co_disk); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->aac_io_lock); co_next = TAILQ_NEXT(co, co_link); mtx_lock(&sc->aac_container_lock); @@ -3326,9 +3326,9 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) /* Attach the newly created containers */ if (added) { mtx_unlock(&sc->aac_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); bus_generic_attach(sc->aac_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->aac_io_lock); } diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 9b728b84bd12..ce396a835b4f 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -3233,10 +3233,9 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state) #endif /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE - * drivers need this. + * Be sure to hold Giant across DEVICE_SUSPEND/RESUME */ - mtx_lock(&Giant); + bus_topo_lock(); slp_state = ACPI_SS_NONE; @@ -3362,7 +3361,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state) } sc->acpi_next_sstate = 0; - mtx_unlock(&Giant); + bus_topo_unlock(); #ifdef EARLY_AP_STARTUP thread_lock(curthread); diff --git a/sys/dev/acpica/acpi_dock.c b/sys/dev/acpica/acpi_dock.c index 4c1b1e7c3175..5f1991e42649 100644 --- a/sys/dev/acpica/acpi_dock.c +++ b/sys/dev/acpica/acpi_dock.c @@ -193,9 +193,9 @@ acpi_dock_attach_later(void *context) if (!device_is_enabled(dev)) device_enable(dev); - mtx_lock(&Giant); + bus_topo_lock(); device_probe_and_attach(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); } static ACPI_STATUS @@ -306,9 +306,9 @@ acpi_dock_eject_child(ACPI_HANDLE handle, UINT32 level, void *context, dev = acpi_get_device(handle); if (dev != NULL && device_is_attached(dev)) { - mtx_lock(&Giant); + bus_topo_lock(); device_detach(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); } acpi_SetInteger(handle, "_EJ0", 0); diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c index 90618f43bbef..ba7ad3a76e64 100644 --- a/sys/dev/acpica/acpi_pci.c +++ b/sys/dev/acpica/acpi_pci.c @@ -340,9 +340,9 @@ acpi_pci_bus_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) switch (notify) { case ACPI_NOTIFY_BUS_CHECK: - mtx_lock(&Giant); + bus_topo_lock(); BUS_RESCAN(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); break; default: device_printf(dev, "unknown notify %#x\n", notify); @@ -361,9 +361,9 @@ acpi_pci_device_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) switch (notify) { case ACPI_NOTIFY_DEVICE_CHECK: - mtx_lock(&Giant); + bus_topo_lock(); BUS_RESCAN(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); break; case ACPI_NOTIFY_EJECT_REQUEST: child = acpi_get_device(h); @@ -372,23 +372,23 @@ acpi_pci_device_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) acpi_name(h)); return; } - mtx_lock(&Giant); + bus_topo_lock(); error = device_detach(child); if (error) { - mtx_unlock(&Giant); + bus_topo_unlock(); device_printf(dev, "failed to detach %s: %d\n", device_get_nameunit(child), error); return; } status = acpi_SetInteger(h, "_EJ0", 1); if (ACPI_FAILURE(status)) { - mtx_unlock(&Giant); + bus_topo_unlock(); device_printf(dev, "failed to eject %s: %s\n", acpi_name(h), AcpiFormatException(status)); return; } BUS_RESCAN(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); break; default: device_printf(dev, "unknown notify %#x for %s\n", notify, diff --git a/sys/dev/bhnd/cores/chipc/chipc.c b/sys/dev/bhnd/cores/chipc/chipc.c index 314f214d08b1..72d92ba682bc 100644 --- a/sys/dev/bhnd/cores/chipc/chipc.c +++ b/sys/dev/bhnd/cores/chipc/chipc.c @@ -1145,13 +1145,13 @@ chipc_should_enable_muxed_sprom(struct chipc_softc *sc) if (!CHIPC_QUIRK(sc, MUX_SPROM)) return (true); - mtx_lock(&Giant); /* for newbus */ + bus_topo_lock(); parent = device_get_parent(sc->dev); hostb = bhnd_bus_find_hostb_device(parent); if ((error = device_get_children(parent, &devs, &devcount))) { - mtx_unlock(&Giant); + bus_topo_unlock(); return (false); } @@ -1174,7 +1174,7 @@ chipc_should_enable_muxed_sprom(struct chipc_softc *sc) } free(devs, M_TEMP); - mtx_unlock(&Giant); + bus_topo_unlock(); return (result); } diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index f13e0ac4675c..17bcc4715308 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -199,7 +199,7 @@ cardbus_attach_card(device_t cbdev) domain = pcib_get_domain(cbdev); bus = pcib_get_bus(cbdev); slot = 0; - mtx_lock(&Giant); + bus_topo_lock(); /* For each function, set it up and try to attach a driver to it */ for (func = 0; func <= cardbusfunchigh; func++) { struct cardbus_devinfo *dinfo; @@ -233,7 +233,7 @@ cardbus_attach_card(device_t cbdev) else pci_cfg_save(dinfo->pci.cfg.dev, &dinfo->pci, 1); } - mtx_unlock(&Giant); + bus_topo_unlock(); if (cardattached > 0) return (0); /* POWER_DISABLE_SOCKET(brdev, cbdev); */ @@ -256,11 +256,11 @@ cardbus_detach_card(device_t cbdev) { int err = 0; - mtx_lock(&Giant); + bus_topo_lock(); err = bus_generic_detach(cbdev); if (err == 0) err = device_delete_children(cbdev); - mtx_unlock(&Giant); + bus_topo_unlock(); if (err) return (err); diff --git a/sys/dev/drm2/drm_dp_iic_helper.c b/sys/dev/drm2/drm_dp_iic_helper.c index 35318c11c388..c3f980a3342f 100644 --- a/sys/dev/drm2/drm_dp_iic_helper.c +++ b/sys/dev/drm2/drm_dp_iic_helper.c @@ -228,12 +228,12 @@ iic_dp_aux_add_bus(device_t dev, const char *name, int idx, error; static int dp_bus_counter; - mtx_lock(&Giant); + bus_topo_lock(); idx = atomic_fetchadd_int(&dp_bus_counter, 1); ibus = device_add_child(dev, "drm_iic_dp_aux", idx); if (ibus == NULL) { - mtx_unlock(&Giant); + bus_topo_unlock(); DRM_ERROR("drm_iic_dp_aux bus %d creation error\n", idx); return (-ENXIO); } @@ -241,7 +241,7 @@ iic_dp_aux_add_bus(device_t dev, const char *name, error = device_probe_and_attach(ibus); if (error != 0) { device_delete_child(dev, ibus); - mtx_unlock(&Giant); + bus_topo_unlock(); DRM_ERROR("drm_iic_dp_aux bus %d attach failed, %d\n", idx, error); return (-error); @@ -256,7 +256,7 @@ iic_dp_aux_add_bus(device_t dev, const char *name, *bus = ibus; *adapter = data->port; } - mtx_unlock(&Giant); + bus_topo_unlock(); return (-error); } diff --git a/sys/dev/hyperv/pcib/vmbus_pcib.c b/sys/dev/hyperv/pcib/vmbus_pcib.c index c7df32044678..fd2b732267f0 100644 --- a/sys/dev/hyperv/pcib/vmbus_pcib.c +++ b/sys/dev/hyperv/pcib/vmbus_pcib.c @@ -560,14 +560,14 @@ hv_pci_delete_device(struct hv_pci_dev *hpdev) devfn = wslot_to_devfn(hpdev->desc.wslot.val); - mtx_lock(&Giant); + bus_topo_lock(); pci_dev = pci_find_dbsf(hbus->pci_domain, 0, PCI_SLOT(devfn), PCI_FUNC(devfn)); if (pci_dev) device_delete_child(hbus->pci_bus, pci_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&hbus->device_list_lock); TAILQ_REMOVE(&hbus->children, hpdev, link); diff --git a/sys/dev/ida/ida.c b/sys/dev/ida/ida.c index d45395a1febf..c34d55b0d7b8 100644 --- a/sys/dev/ida/ida.c +++ b/sys/dev/ida/ida.c @@ -334,9 +334,9 @@ ida_startup(void *arg) config_intrhook_disestablish(&ida->ich); - mtx_lock(&Giant); + bus_topo_lock(); bus_generic_attach(ida->dev); - mtx_unlock(&Giant); + bus_topo_unlock(); } int diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c index 0cf0bdb478af..556d2a9a3fbe 100644 --- a/sys/dev/mfi/mfi.c +++ b/sys/dev/mfi/mfi.c @@ -1425,9 +1425,9 @@ mfi_syspdprobe(struct mfi_softc *sc) if (found == 0) { printf("DELETE\n"); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(sc->mfi_dev, syspd->pd_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); } } @@ -1585,9 +1585,9 @@ mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail) KASSERT(ld != NULL, ("volume dissappeared")); */ if (ld != NULL) { - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(sc->mfi_dev, ld->ld_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); } } break; @@ -1602,11 +1602,11 @@ mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail) pd_link) { if (syspd->pd_id == detail->args.pd.device_id) { - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child( sc->mfi_dev, syspd->pd_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); break; } } @@ -1923,11 +1923,11 @@ mfi_add_ld_complete(struct mfi_command *cm) mfi_release_command(cm); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); 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); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); return; } @@ -1935,7 +1935,7 @@ mfi_add_ld_complete(struct mfi_command *cm) device_set_ivars(child, ld_info); device_set_desc(child, "MFI Logical Disk"); bus_generic_attach(sc->mfi_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); } @@ -2011,11 +2011,11 @@ mfi_add_sys_pd_complete(struct mfi_command *cm) mfi_release_command(cm); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); if ((child = device_add_child(sc->mfi_dev, "mfisyspd", -1)) == NULL) { device_printf(sc->mfi_dev, "Failed to add system pd\n"); free(pd_info, M_MFIBUF); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); return; } @@ -2023,7 +2023,7 @@ mfi_add_sys_pd_complete(struct mfi_command *cm) device_set_ivars(child, pd_info); device_set_desc(child, "MFI System PD"); bus_generic_attach(sc->mfi_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); } @@ -2832,9 +2832,9 @@ mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm) KASSERT(ld != NULL, ("volume dissappeared")); if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(sc->mfi_dev, ld->ld_dev); - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); } else mfi_disk_enable(ld); @@ -2842,11 +2842,11 @@ mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm) case MFI_DCMD_CFG_CLEAR: if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + bus_topo_lock(); TAILQ_FOREACH_SAFE(ld, &sc->mfi_ld_tqh, ld_link, ldn) { device_delete_child(sc->mfi_dev, ld->ld_dev); } - mtx_unlock(&Giant); + bus_topo_unlock(); mtx_lock(&sc->mfi_io_lock); } else { TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) diff --git a/sys/dev/mfi/mfi_cam.c b/sys/dev/mfi/mfi_cam.c index 431dc7b4c129..fdbfaaf08250 100644 --- a/sys/dev/mfi/mfi_cam.c +++ b/sys/dev/mfi/mfi_cam.c @@ -298,9 +298,9 @@ mfip_cam_rescan(struct mfi_softc *sc, uint32_t tid) struct cam_sim *sim; device_t mfip_dev; - mtx_lock(&Giant); + bus_topo_lock(); mfip_dev = device_find_child(sc->mfi_dev, "mfip", -1); - mtx_unlock(&Giant); + bus_topo_unlock(); if (mfip_dev == NULL) { device_printf(sc->mfi_dev, "Couldn't find mfip child device!\n"); return; diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c index f5b023eafc9c..2f961d23e304 100644 --- a/sys/dev/mlx/mlx.c +++ b/sys/dev/mlx/mlx.c @@ -830,9 +830,9 @@ mlx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct threa * Scan the controller to see whether new drives have appeared. */ case MLX_RESCAN_DRIVES: - mtx_lock(&Giant); + bus_topo_lock(); mlx_startup(sc); - mtx_unlock(&Giant); + bus_topo_unlock(); return(0); /* @@ -979,9 +979,9 @@ mlx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct threa case MLX_GET_SYSDRIVE: error = ENOENT; MLX_CONFIG_LOCK(sc); - mtx_lock(&Giant); + bus_topo_lock(); mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg); - mtx_unlock(&Giant); + bus_topo_unlock(); if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) && (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) { error = 0; diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c b/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c index a23de943f4aa..3b56a5994856 100644 --- a/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c +++ b/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c @@ -340,11 +340,11 @@ mlx5_fw_reset(struct mlx5_core_dev *mdev) error = -mlx5_set_mfrl_reg(mdev, MLX5_FRL_LEVEL3); if (error == 0) { dev = mdev->pdev->dev.bsddev; - mtx_lock(&Giant); + bus_topo_lock(); bus = device_get_parent(dev); error = BUS_RESET_CHILD(device_get_parent(bus), bus, DEVF_RESET_DETACH); - mtx_unlock(&Giant); + bus_topo_unlock(); } return (error); } diff --git a/sys/dev/mlx5/mlx5_core/mlx5_health.c b/sys/dev/mlx5/mlx5_core/mlx5_health.c index 7df7870d006f..02d52ebee2ac 100644 --- a/sys/dev/mlx5/mlx5_core/mlx5_health.c +++ b/sys/dev/mlx5/mlx5_core/mlx5_health.c @@ -374,7 +374,8 @@ static void health_recover(struct work_struct *work) priv = container_of(health, struct mlx5_priv, health); dev = container_of(priv, struct mlx5_core_dev, priv); - mtx_lock(&Giant); /* XXX newbus needs this */ + /* This might likely be wrong, cut and paste from elsewhere? */ + bus_topo_lock(); if (sensor_pci_no_comm(dev)) { mlx5_core_err(dev, @@ -401,7 +402,7 @@ static void health_recover(struct work_struct *work) mlx5_recover_device(dev); } - mtx_unlock(&Giant); + bus_topo_unlock(); } /* How much time to wait until health resetting the driver (in msecs) */ diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c index 48d2e6973a38..8b1c437a8c27 100644 --- a/sys/dev/pccard/pccard.c +++ b/sys/dev/pccard/pccard.c @@ -238,7 +238,7 @@ pccard_attach_card(device_t dev) DEVPRINTF((dev, "Card has %d functions. pccard_mfc is %d\n", i + 1, pccard_mfc(sc))); - mtx_lock(&Giant); + bus_topo_lock(); STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { if (STAILQ_EMPTY(&pf->cfe_head)) continue; @@ -251,7 +251,7 @@ pccard_attach_card(device_t dev) pf->dev = child; pccard_probe_and_attach_child(dev, child, pf); } - mtx_unlock(&Giant); + bus_topo_unlock(); return (0); } diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index cecf75024d3f..0945606bbc50 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -1397,7 +1397,7 @@ pcib_setup_hotplug(struct pcib_softc *sc) pcib_pcie_cc_timeout, sc); TIMEOUT_TASK_INIT(taskqueue_pci_hp, &sc->pcie_dll_task, 0, pcib_pcie_dll_timeout, sc); - sc->pcie_hp_lock = &Giant; + sc->pcie_hp_lock = bus_topo_mtx(); /* Allocate IRQ. */ if (pcib_alloc_pcie_irq(sc) != 0) diff --git a/sys/dev/pci/pci_user.c b/sys/dev/pci/pci_user.c index ce63122128c5..a5f849e85c2d 100644 --- a/sys/dev/pci/pci_user.c +++ b/sys/dev/pci/pci_user.c @@ -1059,8 +1059,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t } } - /* Giant because newbus is Giant locked revisit with newbus locking */ - mtx_lock(&Giant); + /* + * Use bus topology lock to ensure that the pci list of devies doesn't + * change while we're traversing the list, in some cases multiple times. + */ + bus_topo_lock(); switch (cmd) { case PCIOCGETCONF: @@ -1412,7 +1415,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t break; } - mtx_unlock(&Giant); + bus_topo_unlock(); return (error); } diff --git a/sys/dev/sdio/sdiob.c b/sys/dev/sdio/sdiob.c index 6209aa1f242e..b21ee3b7ce35 100644 --- a/sys/dev/sdio/sdiob.c +++ b/sys/dev/sdio/sdiob.c @@ -945,10 +945,10 @@ sdio_newbus_sim_add(struct sdiob_softc *sc) return (ENXIO); } - mtx_lock(&Giant); + bus_topo_lock(); error = devclass_add_driver(bus_devclass, &sdiob_driver, BUS_PASS_DEFAULT, &sdiob_devclass); - mtx_unlock(&Giant); + bus_topo_unlock(); if (error != 0) { printf("%s: Failed to add driver to devclass: %d.\n", __func__, error); diff --git a/sys/dev/twe/twe_freebsd.c b/sys/dev/twe/twe_freebsd.c index ad793eb906f4..952d5f133b8f 100644 --- a/sys/dev/twe/twe_freebsd.c +++ b/sys/dev/twe/twe_freebsd.c @@ -583,10 +583,10 @@ twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) char buf[80]; int error; - mtx_lock(&Giant); + bus_topo_lock(); dr->td_disk = device_add_child(sc->twe_dev, NULL, -1); if (dr->td_disk == NULL) { - mtx_unlock(&Giant); + bus_topo_unlock(); twe_printf(sc, "Cannot add unit\n"); return (EIO); } @@ -603,7 +603,7 @@ twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) device_set_desc_copy(dr->td_disk, buf); error = device_probe_and_attach(dr->td_disk); - mtx_unlock(&Giant); + bus_topo_unlock(); if (error != 0) { twe_printf(sc, "Cannot attach unit to controller. error = %d\n", error); return (EIO); @@ -622,9 +622,9 @@ twe_detach_drive(struct twe_softc *sc, int unit) int error = 0; TWE_CONFIG_ASSERT_LOCKED(sc); - mtx_lock(&Giant); + bus_topo_lock(); error = device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk); - mtx_unlock(&Giant); + bus_topo_unlock(); if (error != 0) { twe_printf(sc, "failed to delete unit %d\n", unit); return(error); diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index fe8e48efa01c..fd9bcd5ee524 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -438,9 +438,9 @@ usb_bus_detach(struct usb_proc_msg *pm) USB_BUS_UNLOCK(bus); /* detach children first */ - mtx_lock(&Giant); + bus_topo_lock(); bus_generic_detach(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); /* * Free USB device and all subdevices, if any. @@ -803,10 +803,10 @@ usb_bus_attach(struct usb_proc_msg *pm) static void usb_attach_sub(device_t dev, struct usb_bus *bus) { - mtx_lock(&Giant); + bus_topo_lock(); if (usb_devclass_ptr == NULL) usb_devclass_ptr = devclass_find("usbus"); - mtx_unlock(&Giant); + bus_topo_unlock(); #if USB_HAVE_PF usbpf_attach(bus); diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c index 6da8d7f9b971..314a69b17c01 100644 --- a/sys/dev/usb/net/if_axe.c +++ b/sys/dev/usb/net/if_axe.c @@ -904,11 +904,11 @@ axe_attach_post_sub(struct usb_ether *ue) adv_pause = MIIF_DOPAUSE; else adv_pause = 0; - mtx_lock(&Giant); + bus_topo_lock(); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, adv_pause); - mtx_unlock(&Giant); + bus_topo_unlock(); return (error); } diff --git a/sys/dev/usb/net/if_axge.c b/sys/dev/usb/net/if_axge.c index 4a4bef564c7a..be5bb67156ec 100644 --- a/sys/dev/usb/net/if_axge.c +++ b/sys/dev/usb/net/if_axge.c @@ -470,11 +470,11 @@ axge_attach_post_sub(struct usb_ether *ue) ifp->if_hwassist = AXGE_CSUM_FEATURES; ifp->if_capenable = ifp->if_capabilities; - mtx_lock(&Giant); + bus_topo_lock(); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, AXGE_PHY_ADDR, MII_OFFSET_ANY, MIIF_DOPAUSE); - mtx_unlock(&Giant); + bus_topo_unlock(); return (error); } diff --git a/sys/dev/usb/net/if_muge.c b/sys/dev/usb/net/if_muge.c index 3d008ea3c66a..cf2420875e72 100644 --- a/sys/dev/usb/net/if_muge.c +++ b/sys/dev/usb/net/if_muge.c @@ -1638,11 +1638,11 @@ muge_attach_post_sub(struct usb_ether *ue) ifp->if_capenable = ifp->if_capabilities; - mtx_lock(&Giant); + bus_topo_lock(); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); + bus_topo_unlock(); return (0); } diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c index 33a90259b464..b28f24eec4c7 100644 --- a/sys/dev/usb/net/if_smsc.c +++ b/sys/dev/usb/net/if_smsc.c @@ -1641,11 +1641,11 @@ smsc_attach_post_sub(struct usb_ether *ue) ifp->if_capenable = ifp->if_capabilities; - mtx_lock(&Giant); + bus_topo_lock(); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); + bus_topo_unlock(); return (error); } diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c index 6439a0bfd71d..fa04a6a212ba 100644 --- a/sys/dev/usb/net/if_ure.c +++ b/sys/dev/usb/net/if_ure.c @@ -1014,7 +1014,6 @@ ure_attach_post_sub(struct usb_ether *ue) #endif if_setcapenable(ifp, if_getcapabilities(ifp)); - mtx_lock(&Giant); if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { ifmedia_init(&sc->sc_ifmedia, IFM_IMASK, ure_ifmedia_upd, ure_ifmedia_sts); @@ -1024,11 +1023,12 @@ ure_attach_post_sub(struct usb_ether *ue) sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_AUTO; error = 0; } else { + bus_topo_lock(); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); + bus_topo_unlock(); } - mtx_unlock(&Giant); sctx = device_get_sysctl_ctx(sc->sc_ue.ue_dev); soid = device_get_sysctl_tree(sc->sc_ue.ue_dev); diff --git a/sys/dev/usb/net/usb_ethernet.c b/sys/dev/usb/net/usb_ethernet.c index 33659049f970..fe9fe12c9221 100644 --- a/sys/dev/usb/net/usb_ethernet.c +++ b/sys/dev/usb/net/usb_ethernet.c @@ -249,12 +249,11 @@ ue_attach_post_task(struct usb_proc_msg *_task) if (ue->ue_methods->ue_mii_upd != NULL && ue->ue_methods->ue_mii_sts != NULL) { - /* device_xxx() depends on this */ - mtx_lock(&Giant); + bus_topo_lock(); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, ue_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); + bus_topo_unlock(); } } @@ -327,9 +326,9 @@ uether_ifdetach(struct usb_ether *ue) /* detach miibus */ if (ue->ue_miibus != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ + bus_topo_lock(); device_delete_child(ue->ue_dev, ue->ue_miibus); - mtx_unlock(&Giant); + bus_topo_unlock(); } /* free interface instance */ diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 322e4f5401ba..634507fc65ca 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -2902,7 +2902,7 @@ usbd_enum_lock(struct usb_device *udev) * are locked before locking Giant. Else the lock can be * locked multiple times. */ - mtx_lock(&Giant); + bus_topo_lock(); return (1); } @@ -2922,7 +2922,7 @@ usbd_enum_lock_sig(struct usb_device *udev) sx_xunlock(&udev->enum_sx); return (255); } - mtx_lock(&Giant); + bus_topo_lock(); return (1); } #endif @@ -2932,7 +2932,7 @@ usbd_enum_lock_sig(struct usb_device *udev) void usbd_enum_unlock(struct usb_device *udev) { - mtx_unlock(&Giant); + bus_topo_unlock(); sx_xunlock(&udev->enum_sx); sx_xunlock(&udev->sr_sx); } @@ -2948,7 +2948,7 @@ usbd_sr_lock(struct usb_device *udev) * are locked before locking Giant. Else the lock can be * locked multiple times. */ - mtx_lock(&Giant); + bus_topo_lock(); } /* The following function unlocks suspend and resume. */ @@ -2956,7 +2956,7 @@ usbd_sr_lock(struct usb_device *udev) void usbd_sr_unlock(struct usb_device *udev) { - mtx_unlock(&Giant); + bus_topo_unlock(); sx_xunlock(&udev->sr_sx); } diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c index 234ebdf530b0..426682a8f2d9 100644 --- a/sys/dev/xen/control/control.c +++ b/sys/dev/xen/control/control.c @@ -232,12 +232,11 @@ xctrl_suspend() KASSERT((PCPU_GET(cpuid) == 0), ("Not running on CPU#0")); /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE - * drivers need this. + * Be sure to hold Giant across DEVICE_SUSPEND/RESUME. */ - mtx_lock(&Giant); + bus_topo_lock(); if (DEVICE_SUSPEND(root_bus) != 0) { - mtx_unlock(&Giant); + bus_topo_unlock(); printf("%s: device_suspend failed\n", __func__); return; } @@ -310,7 +309,7 @@ xctrl_suspend() * similar. */ DEVICE_RESUME(root_bus); - mtx_unlock(&Giant); + bus_topo_unlock(); /* * Warm up timecounter again and reset system clock. diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 0cde2c781719..008cec6b5417 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -864,6 +864,27 @@ static kobj_method_t null_methods[] = { DEFINE_CLASS(null, null_methods, 0); +struct mtx * +bus_topo_mtx(void) +{ + + return (&Giant); +} + +void +bus_topo_lock(void) +{ + + mtx_lock(bus_topo_mtx()); +} + +void +bus_topo_unlock(void) +{ + + mtx_unlock(bus_topo_mtx()); +} + /* * Bus pass implementation */ @@ -5707,7 +5728,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, int error, old; /* Locate the device to control. */ - mtx_lock(&Giant); + bus_topo_lock(); req = (struct devreq *)data; switch (cmd) { case DEV_ATTACH: @@ -5734,7 +5755,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, break; } if (error) { - mtx_unlock(&Giant); + bus_topo_unlock(); return (error); } @@ -5955,7 +5976,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, req->dr_flags); break; } - mtx_unlock(&Giant); + bus_topo_unlock(); return (error); } diff --git a/sys/net/iflib_clone.c b/sys/net/iflib_clone.c index fc4e71806926..89d37a586f8d 100644 --- a/sys/net/iflib_clone.c +++ b/sys/net/iflib_clone.c @@ -182,9 +182,9 @@ iflib_clone_create(struct if_clone *ifc, int unit, caddr_t params) if (__predict_false(iflib_pseudodev == NULL)) { /* SYSINIT initialization would panic !?! */ - mtx_lock(&Giant); + bus_topo_lock(); iflib_pseudodev = device_add_child(root_bus, "ifpseudo", 0); - mtx_unlock(&Giant); + bus_topo_unlock(); MPASS(iflib_pseudodev != NULL); } ip = iflib_ip_lookup(name); @@ -208,9 +208,9 @@ iflib_clone_create(struct if_clone *ifc, int unit, caddr_t params) MPASS(devclass_get_device(ip->ip_dc, unit) == dev); rc = iflib_pseudo_register(dev, ip->ip_sctx, &ctx, &clctx); if (rc) { - mtx_lock(&Giant); + bus_topo_lock(); device_delete_child(iflib_pseudodev, dev); - mtx_unlock(&Giant); + bus_topo_unlock(); } else device_set_softc(dev, ctx); @@ -236,9 +236,9 @@ iflib_clone_destroy(if_t ifp) iflib_stop(ctx); sx_xunlock(ctx_lock); - mtx_lock(&Giant); + bus_topo_lock(); rc = device_delete_child(iflib_pseudodev, dev); - mtx_unlock(&Giant); + bus_topo_unlock(); if (rc == 0) iflib_pseudo_deregister(ctx); } diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 4a1afa864c2f..f5e31e5a6d00 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -738,6 +738,14 @@ extern int bus_current_pass; void bus_set_pass(int pass); +/** + * Routines to lock / unlock the newbus lock. + * Must be taken out to interact with newbus. + */ +void bus_topo_lock(void); +void bus_topo_unlock(void); +struct mtx * bus_topo_mtx(void); + /** * Shorthands for constructing method tables. */ @@ -768,7 +776,7 @@ struct driver_module_data { #define EARLY_DRIVER_MODULE_ORDERED(name, busname, driver, devclass, \ evh, arg, order, pass) \ - \ + \ static struct driver_module_data name##_##busname##_driver_mod = { \ evh, arg, \ #busname, \ diff --git a/sys/xen/xenbus/xenbusb.c b/sys/xen/xenbus/xenbusb.c index 74e095f6cda2..09b59a64ab4e 100644 --- a/sys/xen/xenbus/xenbusb.c +++ b/sys/xen/xenbus/xenbusb.c @@ -533,12 +533,9 @@ xenbusb_probe_children_cb(void *arg, int pending __unused) { device_t dev = (device_t)arg; - /* - * Hold Giant until the Giant free newbus changes are committed. - */ - mtx_lock(&Giant); + bus_topo_lock(); xenbusb_probe_children(dev); - mtx_unlock(&Giant); + bus_topo_unlock(); } /**