From: stsp Date: Thu, 30 Sep 2021 09:27:47 +0000 (+0000) Subject: In iwm(4) and iwx(4), prevent attemps to transition towards the same state X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=c99d53f17120fbb0451e6c68bf346967c3f6450b;p=openbsd In iwm(4) and iwx(4), prevent attemps to transition towards the same state in cases where this would result in a redundant or illegal state transition. jmc@ observed ASSOC -> ASSOC transitions which would result in a hang. Such transitions are invalid and never intentionally triggered by net80211. They imply a race between the Rx interrupt handler and the newstate task. Tested by jmc@ on AX200 for a week and several known issues seem to be fixed. --- diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index cb75fbf0f19..c8229ae3802 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.368 2021/09/24 19:02:16 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.369 2021/09/30 09:27:47 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -9004,6 +9004,14 @@ iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) struct iwm_softc *sc = ifp->if_softc; int i; + /* + * Prevent attemps to transition towards the same state, unless + * we are scanning in which case a SCAN -> SCAN transition + * triggers another scan iteration. + */ + if (sc->ns_nstate == nstate && nstate != IEEE80211_S_SCAN) + return 0; + if (ic->ic_state == IEEE80211_S_RUN) { timeout_del(&sc->sc_calib_to); iwm_del_task(sc, systq, &sc->ba_task); diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index f9c68a2865e..053507687d9 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.111 2021/09/23 16:27:58 stsp Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.112 2021/09/30 09:27:47 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh @@ -7921,6 +7921,14 @@ iwx_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) struct iwx_softc *sc = ifp->if_softc; int i; + /* + * Prevent attemps to transition towards the same state, unless + * we are scanning in which case a SCAN -> SCAN transition + * triggers another scan iteration. + */ + if (sc->ns_nstate == nstate && nstate != IEEE80211_S_SCAN) + return 0; + if (ic->ic_state == IEEE80211_S_RUN) { iwx_del_task(sc, systq, &sc->ba_task); iwx_del_task(sc, systq, &sc->setkey_task);