diff options
author | 2017-01-21 11:21:41 +0000 | |
---|---|---|
committer | 2017-01-21 11:21:41 +0000 | |
commit | 2ea2d5439ce2e3bfaf9062e47f281c4708a67421 (patch) | |
tree | 2b437dcd63f54c643e2cf08b5961ab05c0c18f51 | |
parent | Move if_vio.c to sys/dev/pv/if_vio.c (diff) | |
download | wireguard-openbsd-2ea2d5439ce2e3bfaf9062e47f281c4708a67421.tar.xz wireguard-openbsd-2ea2d5439ce2e3bfaf9062e47f281c4708a67421.zip |
In iwm(4), cancel mira timeouts in iwm_stop() and iwm_newstate() instead of
relying on the newstate task to do so. Fixes races of driver code against
mira timeouts leading to crashes in some situations, e.g. occasionally when
changing channels while the interface is up.
ok procter@
-rw-r--r-- | sys/dev/pci/if_iwm.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index 74334359a79..7f866c49c29 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.156 2017/01/12 18:06:57 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.157 2017/01/21 11:21:41 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -5496,10 +5496,8 @@ iwm_newstate_task(void *psc) if (ostate == IEEE80211_S_SCAN && nstate != ostate) iwm_led_blink_stop(sc); - if (ostate == IEEE80211_S_RUN && nstate != ostate) { + if (ostate == IEEE80211_S_RUN && nstate != ostate) iwm_disable_beacon_filter(sc); - ieee80211_mira_cancel_timeouts(&in->in_mn); - } /* Reset the device if moving out of AUTH, ASSOC, or RUN. */ /* XXX Is there a way to switch states without a full reset? */ @@ -5632,8 +5630,11 @@ iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) { struct ifnet *ifp = IC2IFP(ic); struct iwm_softc *sc = ifp->if_softc; + struct iwm_node *in = (void *)ic->ic_bss; timeout_del(&sc->sc_calib_to); + if (ic->ic_state == IEEE80211_S_RUN) + ieee80211_mira_cancel_timeouts(&in->in_mn); sc->ns_nstate = nstate; sc->ns_arg = arg; @@ -6116,6 +6117,8 @@ iwm_stop(struct ifnet *ifp, int disable) ifq_clr_oactive(&ifp->if_snd); in->in_phyctxt = NULL; + if (ic->ic_state == IEEE80211_S_RUN) + ieee80211_mira_cancel_timeouts(&in->in_mn); task_del(systq, &sc->init_task); task_del(sc->sc_nswq, &sc->newstate_task); |