git: c6df6f5322f7 - main - Create wrapper for Giant taken for newbus

From: Warner Losh <imp_at_FreeBSD.org>
Date: Fri, 10 Dec 2021 00:05:10 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=c6df6f5322f7004c71216391e1c0b374d853704a

commit c6df6f5322f7004c71216391e1c0b374d853704a
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2021-12-10 00:04:45 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2021-12-10 00:04:45 +0000

    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
---
 sys/compat/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 @@ repeat:
 	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 @@ backout:
     }
     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 @@ getconfexit:
 		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);
+}
*** 132 LINES SKIPPED ***