From 7bf442ed4e000a4c0cfe767af868f9aa8242892f Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 14 Feb 2008 12:53:52 +0000 Subject: [PATCH] Release serializer around firmware_load_image() to avoid possible dead lock. Add comment about it. --- sys/dev/netif/acx/if_acx.c | 30 +++++++++++++++++++++++------- sys/dev/netif/bwi/bwimac.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/sys/dev/netif/acx/if_acx.c b/sys/dev/netif/acx/if_acx.c index e0c7fd075..c4c0a6f3c 100644 --- a/sys/dev/netif/acx/if_acx.c +++ b/sys/dev/netif/acx/if_acx.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/acx/if_acx.c,v 1.25 2008/02/06 08:21:22 sephe Exp $ + * $DragonFly: src/sys/dev/netif/acx/if_acx.c,v 1.26 2008/02/14 12:53:52 sephe Exp $ */ /* @@ -1669,9 +1669,17 @@ static int acx_alloc_firmware(struct acx_softc *sc) { struct acx_firmware *fw = &sc->sc_firmware; + struct ifnet *ifp = &sc->sc_ic.ic_if; + struct fw_image *img; char filename[64]; int error = 0; + /* + * NB: serializer need to be released before loading firmware + * image to avoid possible dead lock + */ + ASSERT_SERIALIZED(ifp->if_serializer); + if (fw->base_fw_image == NULL) { if (fw->combined_radio_fw) { ksnprintf(filename, sizeof(filename), @@ -1681,10 +1689,14 @@ acx_alloc_firmware(struct acx_softc *sc) ksnprintf(filename, sizeof(filename), ACX_BASE_FW_PATH, fw->fwdir); } - fw->base_fw_image = firmware_image_load(filename, NULL); + + lwkt_serialize_exit(ifp->if_serializer); + img = firmware_image_load(filename, NULL); + lwkt_serialize_enter(ifp->if_serializer); + + fw->base_fw_image = img; if (fw->base_fw_image == NULL) { - if_printf(&sc->sc_ic.ic_if, "load %s base fw failed\n", - filename); + if_printf(ifp, "load %s base fw failed\n", filename); error = EIO; goto back; } @@ -1698,10 +1710,14 @@ acx_alloc_firmware(struct acx_softc *sc) if (!fw->combined_radio_fw && fw->radio_fw_image == NULL) { ksnprintf(filename, sizeof(filename), ACX_RADIO_FW_PATH, fw->fwdir, sc->sc_radio_type); - fw->radio_fw_image = firmware_image_load(filename, NULL); + + lwkt_serialize_exit(ifp->if_serializer); + img = firmware_image_load(filename, NULL); + lwkt_serialize_enter(ifp->if_serializer); + + fw->radio_fw_image = img; if (fw->radio_fw_image == NULL) { - if_printf(&sc->sc_ic.ic_if, "load %s radio fw failed\n", - filename); + if_printf(ifp, "load %s radio fw failed\n", filename); error = EIO; goto back; } diff --git a/sys/dev/netif/bwi/bwimac.c b/sys/dev/netif/bwi/bwimac.c index 786635892..04b87a28f 100644 --- a/sys/dev/netif/bwi/bwimac.c +++ b/sys/dev/netif/bwi/bwimac.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.11 2008/01/15 09:01:13 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.12 2008/02/14 12:53:51 sephe Exp $ */ #include @@ -870,15 +870,26 @@ bwi_mac_fw_alloc(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; struct ifnet *ifp = &sc->sc_ic.ic_if; + struct fw_image *img; char fwname[64]; int idx; + /* + * NB: serializer need to be released before loading firmware + * image to avoid possible dead lock + */ + ASSERT_SERIALIZED(ifp->if_serializer); + if (mac->mac_ucode == NULL) { ksnprintf(fwname, sizeof(fwname), BWI_FW_UCODE_PATH, sc->sc_fw_version, mac->mac_rev >= 5 ? 5 : mac->mac_rev); - mac->mac_ucode = firmware_image_load(fwname, NULL); + lwkt_serialize_exit(ifp->if_serializer); + img = firmware_image_load(fwname, NULL); + lwkt_serialize_enter(ifp->if_serializer); + + mac->mac_ucode = img; if (mac->mac_ucode == NULL) { if_printf(ifp, "request firmware %s failed\n", fwname); return ENOMEM; @@ -893,7 +904,11 @@ bwi_mac_fw_alloc(struct bwi_mac *mac) sc->sc_fw_version, mac->mac_rev < 5 ? 4 : 5); - mac->mac_pcm = firmware_image_load(fwname, NULL); + lwkt_serialize_exit(ifp->if_serializer); + img = firmware_image_load(fwname, NULL); + lwkt_serialize_enter(ifp->if_serializer); + + mac->mac_pcm = img; if (mac->mac_pcm == NULL) { if_printf(ifp, "request firmware %s failed\n", fwname); return ENOMEM; @@ -918,7 +933,11 @@ bwi_mac_fw_alloc(struct bwi_mac *mac) ksnprintf(fwname, sizeof(fwname), BWI_FW_IV_PATH, sc->sc_fw_version, idx); - mac->mac_iv = firmware_image_load(fwname, NULL); + lwkt_serialize_exit(ifp->if_serializer); + img = firmware_image_load(fwname, NULL); + lwkt_serialize_enter(ifp->if_serializer); + + mac->mac_iv = img; if (mac->mac_iv == NULL) { if_printf(ifp, "request firmware %s failed\n", fwname); return ENOMEM; @@ -944,7 +963,11 @@ bwi_mac_fw_alloc(struct bwi_mac *mac) ksnprintf(fwname, sizeof(fwname), BWI_FW_IV_EXT_PATH, sc->sc_fw_version, idx); - mac->mac_iv_ext = firmware_image_load(fwname, NULL); + lwkt_serialize_exit(ifp->if_serializer); + img = firmware_image_load(fwname, NULL); + lwkt_serialize_enter(ifp->if_serializer); + + mac->mac_iv_ext = img; if (mac->mac_iv_ext == NULL) { if_printf(ifp, "request firmware %s failed\n", fwname); return ENOMEM; -- 2.11.4.GIT