git: ee08e8455170 - stable/14 - mmc: Use bus_topo_lock and taskqueue_bus while adding/removing child devices
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 29 Apr 2025 18:30:38 UTC
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);