git: c0bed9bd0bda - main - mmc: Use bus_topo_lock and taskqueue_bus while adding/removing child devices
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 10 Mar 2025 17:35:41 UTC
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=c0bed9bd0bda2ca9239f5913cd2d5c1bd5d29bfa commit c0bed9bd0bda2ca9239f5913cd2d5c1bd5d29bfa Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2025-03-10 17:32:53 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2025-03-10 17:32:53 +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 --- 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 9f61e1560658..6bebf5e5fb5e 100644 --- a/sys/arm/allwinner/aw_mmc.c +++ b/sys/arm/allwinner/aw_mmc.c @@ -322,32 +322,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", DEVICE_UNIT_ANY); - 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 51709bcbb7e9..57992571982c 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -462,10 +462,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); } } @@ -477,8 +477,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) { @@ -486,25 +485,22 @@ dwmmc_card_task(void *arg, int pending __unused) device_printf(sc->dev, "Card inserted\n"); sc->child = device_add_child(sc->dev, "mmc", DEVICE_UNIT_ANY); - 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 */ } @@ -751,7 +747,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 @@ -782,8 +778,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 752e5d14bcb0..aed85dab55f4 100644 --- a/sys/dev/mmc/mmc_fdt_helpers.c +++ b/sys/dev/mmc/mmc_fdt_helpers.c @@ -111,7 +111,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)); } @@ -129,7 +129,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)); } @@ -145,7 +145,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); /* @@ -280,7 +280,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); } @@ -301,7 +301,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 f06b493e0c15..aed0bd6c8b8c 100644 --- a/sys/dev/rtsx/rtsx.c +++ b/sys/dev/rtsx/rtsx.c @@ -633,10 +633,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); } } @@ -648,6 +648,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. */ @@ -664,9 +667,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", DEVICE_UNIT_ANY); - RTSX_UNLOCK(sc); if (sc->rtsx_mmc_dev == NULL) { device_printf(sc->rtsx_dev, "Adding MMC bus failed\n"); } else { @@ -699,6 +700,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) return (error); sc->rtsx_mmc_dev = NULL; - 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);