Date: Thu, 8 Sep 2011 12:35:46 +0800 From: Adrian Chadd <adrian@freebsd.org> To: Joel Dahl <joel@vnode.se> Cc: freebsd-wireless@freebsd.org, weongyo@freebsd.org, Bernhard Schmidt <bschmidt@freebsd.org> Subject: Re: BETA2 panic Message-ID: <CAJ-Vmomg1N5VoEeqpvs5fTGnn9w9Hw--vi6eZKNvzm-UbqPpbg@mail.gmail.com> In-Reply-To: <20110907174755.GR52426@goofy03.vnode.local> References: <09C13664-4FC0-41F3-8849-CE875B3A6CC0@vnode.se> <CAJ-VmokggV3r8cStQNOMRCKoWMF1tPsoXW6PhHPxSq-i8Pyf-Q@mail.gmail.com> <20110905062453.GM52426@goofy03.vnode.local> <CAAgh0_b6WKYQSyT22MegzxaEsdQBiP0huWgQC%2B9a7yAFvWdYJw@mail.gmail.com> <20110906204242.GP52426@goofy03.vnode.local> <CAAgh0_bOOT2j_y4AeJHpXQty36Gb32pYq_atyf6j9QqnhqeCsA@mail.gmail.com> <20110907105325.GQ52426@goofy03.vnode.local> <CAAgh0_Y6HEGmqW9-FXig5F5fQ%2B6HSz_j9SY0DupUjZidkMFRLA@mail.gmail.com> <20110907174755.GR52426@goofy03.vnode.local>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi,
Please try this patch.
I bet what's happening is:
* transition is going from RUN -> ! RUN;
* the state is changed before the swbmiss timer is cancelled;
* the callout gets called in another process context;
* bang!
This patch:
* changes the order of things so the callout is cancelled -before- the
state is changed;
* grabs the ic lock in the swbmiss task just to make sure nothing else
is fiddling with it.
Thanks,
cynthia:head adrian$ svn diff sys/net80211/
Index: sys/net80211/ieee80211_sta.c
===================================================================
--- sys/net80211/ieee80211_sta.c (revision 225421)
+++ sys/net80211/ieee80211_sta.c (working copy)
@@ -217,13 +217,14 @@
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
__func__, ieee80211_state_name[ostate],
ieee80211_state_name[nstate], arg);
+ /* Disable callout before changing state */
+ if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
+ callout_stop(&vap->iv_swbmiss);
vap->iv_state = nstate; /* state transition */
callout_stop(&vap->iv_mgtsend); /* XXX callout_drain */
if (ostate != IEEE80211_S_SCAN)
ieee80211_cancel_scan(vap); /* background scan */
ni = vap->iv_bss; /* NB: no reference held */
- if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
- callout_stop(&vap->iv_swbmiss);
switch (nstate) {
case IEEE80211_S_INIT:
switch (ostate) {
Index: sys/net80211/ieee80211_proto.c
===================================================================
--- sys/net80211/ieee80211_proto.c (revision 225421)
+++ sys/net80211/ieee80211_proto.c (working copy)
@@ -1440,6 +1440,12 @@
struct ieee80211vap *vap = arg;
struct ieee80211com *ic = vap->iv_ic;
+ /*
+ * Grab comlock; a state transition may be occuring
+ * in another context.
+ */
+ IEEE80211_LOCK(ic);
+
/* XXX sleep state? */
KASSERT(vap->iv_state == IEEE80211_S_RUN,
("wrong state %d", vap->iv_state));
@@ -1463,6 +1469,8 @@
vap->iv_swbmiss_count = 0;
callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period,
ieee80211_swbmiss, vap);
+
+ IEEE80211_UNLOCK(ic);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-Vmomg1N5VoEeqpvs5fTGnn9w9Hw--vi6eZKNvzm-UbqPpbg>
