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>