Skip site navigation (1)Skip section navigation (2)
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>