Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Apr 2025 18:30:38 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: ee08e8455170 - stable/14 - mmc: Use bus_topo_lock and taskqueue_bus while adding/removing child devices
Message-ID:  <202504291830.53TIUcvB022592@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by jhb:

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

commit ee08e8455170b65b85e85aa44374494b95fc5f0c
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-03-10 17:32:53 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-04-29 14:40:47 +0000

    mmc: Use bus_topo_lock and taskqueue_bus while adding/removing child devices
    
    Some drivers held regular mutexes across some new-bus calls; instead
    depend on bus_topo_lock to protect the relevant softc members.  This
    also fixes the bus_topo_lock to be explicit in these drivers rather
    than relying on the implicit Giant from taskqueue_swi_giant.  It
    avoids calling sleepable routines like device_probe_and_attach from an
    swi context.
    
    Differential Revision:  https://reviews.freebsd.org/D49270
    
    (cherry picked from commit c0bed9bd0bda2ca9239f5913cd2d5c1bd5d29bfa)
---
 sys/arm/allwinner/aw_mmc.c    | 11 ++++-------
 sys/dev/mmc/host/dwmmc.c      | 22 +++++++++-------------
 sys/dev/mmc/mmc_fdt_helpers.c | 10 +++++-----
 sys/dev/rtsx/rtsx.c           | 18 +++++++++++-------
 4 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/sys/arm/allwinner/aw_mmc.c b/sys/arm/allwinner/aw_mmc.c
index 8b0d825e4d4f..37dc95778105 100644
--- a/sys/arm/allwinner/aw_mmc.c
+++ b/sys/arm/allwinner/aw_mmc.c
@@ -323,32 +323,29 @@ aw_mmc_helper_cd_handler(device_t dev, bool present)
 #ifdef MMCCAM
 	mmc_cam_sim_discover(&sc->mmc_sim);
 #else
-	AW_MMC_LOCK(sc);
+	bus_topo_lock();
 	if (present) {
 		if (sc->child == NULL) {
 			if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_CARD))
 				device_printf(sc->aw_dev, "Card inserted\n");
 
 			sc->child = device_add_child(sc->aw_dev, "mmc", -1);
-			AW_MMC_UNLOCK(sc);
 			if (sc->child) {
 				device_set_ivars(sc->child, sc);
 				(void)device_probe_and_attach(sc->child);
 			}
-		} else
-			AW_MMC_UNLOCK(sc);
+		}
 	} else {
 		/* Card isn't present, detach if necessary */
 		if (sc->child != NULL) {
 			if (__predict_false(aw_mmc_debug & AW_MMC_DEBUG_CARD))
 				device_printf(sc->aw_dev, "Card removed\n");
 
-			AW_MMC_UNLOCK(sc);
 			device_delete_child(sc->aw_dev, sc->child);
 			sc->child = NULL;
-		} else
-			AW_MMC_UNLOCK(sc);
+		}
 	}
+	bus_topo_unlock();
 #endif /* MMCCAM */
 }
 
diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c
index be6f5e9de2d1..965a40f45505 100644
--- a/sys/dev/mmc/host/dwmmc.c
+++ b/sys/dev/mmc/host/dwmmc.c
@@ -463,10 +463,10 @@ dwmmc_handle_card_present(struct dwmmc_softc *sc, bool is_present)
 	was_present = sc->child != NULL;
 
 	if (!was_present && is_present) {
-		taskqueue_enqueue_timeout(taskqueue_swi_giant,
+		taskqueue_enqueue_timeout(taskqueue_bus,
 		  &sc->card_delayed_task, -(hz / 2));
 	} else if (was_present && !is_present) {
-		taskqueue_enqueue(taskqueue_swi_giant, &sc->card_task);
+		taskqueue_enqueue(taskqueue_bus, &sc->card_task);
 	}
 }
 
@@ -478,8 +478,7 @@ dwmmc_card_task(void *arg, int pending __unused)
 #ifdef MMCCAM
 	mmc_cam_sim_discover(&sc->mmc_sim);
 #else
-	DWMMC_LOCK(sc);
-
+	bus_topo_lock();
 	if (READ4(sc, SDMMC_CDETECT) == 0 ||
 	    (sc->mmc_helper.props & MMC_PROP_BROKEN_CD)) {
 		if (sc->child == NULL) {
@@ -487,25 +486,22 @@ dwmmc_card_task(void *arg, int pending __unused)
 				device_printf(sc->dev, "Card inserted\n");
 
 			sc->child = device_add_child(sc->dev, "mmc", -1);
-			DWMMC_UNLOCK(sc);
 			if (sc->child) {
 				device_set_ivars(sc->child, sc);
 				(void)device_probe_and_attach(sc->child);
 			}
-		} else
-			DWMMC_UNLOCK(sc);
+		}
 	} else {
 		/* Card isn't present, detach if necessary */
 		if (sc->child != NULL) {
 			if (bootverbose)
 				device_printf(sc->dev, "Card removed\n");
 
-			DWMMC_UNLOCK(sc);
 			device_delete_child(sc->dev, sc->child);
 			sc->child = NULL;
-		} else
-			DWMMC_UNLOCK(sc);
+		}
 	}
+	bus_topo_unlock();
 #endif /* MMCCAM */
 }
 
@@ -752,7 +748,7 @@ dwmmc_attach(device_t dev)
 	WRITE4(sc, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE);
 
 	TASK_INIT(&sc->card_task, 0, dwmmc_card_task, sc);
-	TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->card_delayed_task, 0,
+	TIMEOUT_TASK_INIT(taskqueue_bus, &sc->card_delayed_task, 0,
 		dwmmc_card_task, sc);
 
 #ifdef MMCCAM
@@ -783,8 +779,8 @@ dwmmc_detach(device_t dev)
 	if (ret != 0)
 		return (ret);
 
-	taskqueue_drain(taskqueue_swi_giant, &sc->card_task);
-	taskqueue_drain_timeout(taskqueue_swi_giant, &sc->card_delayed_task);
+	taskqueue_drain(taskqueue_bus, &sc->card_task);
+	taskqueue_drain_timeout(taskqueue_bus, &sc->card_delayed_task);
 
 	if (sc->intr_cookie != NULL) {
 		ret = bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
diff --git a/sys/dev/mmc/mmc_fdt_helpers.c b/sys/dev/mmc/mmc_fdt_helpers.c
index 30538ea20ca3..47c8c6ce1c79 100644
--- a/sys/dev/mmc/mmc_fdt_helpers.c
+++ b/sys/dev/mmc/mmc_fdt_helpers.c
@@ -112,7 +112,7 @@ cd_intr(void *arg)
 {
 	struct mmc_helper *helper = arg;
 
-	taskqueue_enqueue_timeout(taskqueue_swi_giant,
+	taskqueue_enqueue_timeout(taskqueue_bus,
 	    &helper->cd_delayed_task, -(hz / 2));
 }
 
@@ -130,7 +130,7 @@ cd_card_task(void *arg, int pending __unused)
 
 	/* If we're polling re-schedule the task */
 	if (helper->cd_ihandler == NULL)
-		taskqueue_enqueue_timeout_sbt(taskqueue_swi_giant,
+		taskqueue_enqueue_timeout_sbt(taskqueue_bus,
 		    &helper->cd_delayed_task, mstosbt(500), 0, C_PREL(2));
 }
 
@@ -146,7 +146,7 @@ cd_setup(struct mmc_helper *helper, phandle_t node)
 
 	dev = helper->dev;
 
-	TIMEOUT_TASK_INIT(taskqueue_swi_giant, &helper->cd_delayed_task, 0,
+	TIMEOUT_TASK_INIT(taskqueue_bus, &helper->cd_delayed_task, 0,
 	    cd_card_task, helper);
 
 	/*
@@ -281,7 +281,7 @@ mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_helper *helper,
 	/* 
 	 * Schedule a card detection
 	 */
-	taskqueue_enqueue_timeout_sbt(taskqueue_swi_giant,
+	taskqueue_enqueue_timeout_sbt(taskqueue_bus,
 	    &helper->cd_delayed_task, mstosbt(500), 0, C_PREL(2));
 	return (0);
 }
@@ -302,7 +302,7 @@ mmc_fdt_gpio_teardown(struct mmc_helper *helper)
 	if (helper->cd_ires != NULL)
 		bus_release_resource(helper->dev, SYS_RES_IRQ, 0, helper->cd_ires);
 
-	taskqueue_drain_timeout(taskqueue_swi_giant, &helper->cd_delayed_task);
+	taskqueue_drain_timeout(taskqueue_bus, &helper->cd_delayed_task);
 }
 
 bool
diff --git a/sys/dev/rtsx/rtsx.c b/sys/dev/rtsx/rtsx.c
index b02e7fd2d24a..461f39e3d3c4 100644
--- a/sys/dev/rtsx/rtsx.c
+++ b/sys/dev/rtsx/rtsx.c
@@ -634,10 +634,10 @@ rtsx_handle_card_present(struct rtsx_softc *sc)
 		 * (sometimes the card detect pin stabilizes
 		 * before the other pins have made good contact).
 		 */
-		taskqueue_enqueue_timeout(taskqueue_swi_giant,
+		taskqueue_enqueue_timeout(taskqueue_bus,
 					  &sc->rtsx_card_insert_task, -hz);
 	} else if (was_present && !is_present) {
-		taskqueue_enqueue(taskqueue_swi_giant, &sc->rtsx_card_remove_task);
+		taskqueue_enqueue(taskqueue_bus, &sc->rtsx_card_remove_task);
 	}
 }
 
@@ -649,6 +649,9 @@ rtsx_card_task(void *arg, int pending __unused)
 {
 	struct rtsx_softc *sc = arg;
 
+#ifndef MMCCAM
+	bus_topo_lock();
+#endif
 	if (rtsx_is_card_present(sc)) {
 		sc->rtsx_flags |= RTSX_F_CARD_PRESENT;
 		/* Card is present, attach if necessary. */
@@ -665,9 +668,7 @@ rtsx_card_task(void *arg, int pending __unused)
 			sc->rtsx_cam_status = 1;
 			mmc_cam_sim_discover(&sc->rtsx_mmc_sim);
 #else  /* !MMCCAM */
-			RTSX_LOCK(sc);
 			sc->rtsx_mmc_dev = device_add_child(sc->rtsx_dev, "mmc", -1);
-			RTSX_UNLOCK(sc);
 			if (sc->rtsx_mmc_dev == NULL) {
 				device_printf(sc->rtsx_dev, "Adding MMC bus failed\n");
 			} else {
@@ -700,6 +701,9 @@ rtsx_card_task(void *arg, int pending __unused)
 #endif /* MMCCAM */
 		}
 	}
+#ifndef MMCCAM
+	bus_topo_unlock();
+#endif
 }
 
 static bool
@@ -3690,7 +3694,7 @@ rtsx_attach(device_t dev)
 	sc->rtsx_mem_btag = rman_get_bustag(sc->rtsx_mem_res);
 	sc->rtsx_mem_bhandle = rman_get_bushandle(sc->rtsx_mem_res);
 
-	TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->rtsx_card_insert_task, 0,
+	TIMEOUT_TASK_INIT(taskqueue_bus, &sc->rtsx_card_insert_task, 0,
 			  rtsx_card_task, sc);
 	TASK_INIT(&sc->rtsx_card_remove_task, 0, rtsx_card_task, sc);
 
@@ -3789,8 +3793,8 @@ rtsx_detach(device_t dev)
 	if (error)
 		return (error);
 
-	taskqueue_drain_timeout(taskqueue_swi_giant, &sc->rtsx_card_insert_task);
-	taskqueue_drain(taskqueue_swi_giant, &sc->rtsx_card_remove_task);
+	taskqueue_drain_timeout(taskqueue_bus, &sc->rtsx_card_insert_task);
+	taskqueue_drain(taskqueue_bus, &sc->rtsx_card_remove_task);
 
 	/* Teardown the state in our softc created in our attach routine. */
 	rtsx_dma_free(sc);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202504291830.53TIUcvB022592>