linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mac80211: fix IBSS lockdep complaint
@ 2010-07-21  8:52 Johannes Berg
  0 siblings, 0 replies; only message in thread
From: Johannes Berg @ 2010-07-21  8:52 UTC (permalink / raw)
  To: John Linville; +Cc: Bob Copeland, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

Bob reported a lockdep complaint originating in
the mac80211 IBSS code due to the common work
struct patch. The reason is that the IBSS and
station mode code have different locking orders
for the cfg80211 wdev lock and the work struct
(where "locking" implies running/canceling).

Fix this by simply not canceling the work in
the IBSS code, it is not necessary since when
the REQ_RUN bit is cleared, the work will run
without effect if it runs. When the interface
is set down, it is flushed anyway, so there's
no concern about it running after memory has
been invalidated either.

This fixes
https://bugzilla.kernel.org/show_bug.cgi?id=16419

Additionally, looking into this I noticed that
there's a small window while the IBSS is torn
down in which the work may be rescheduled and
the REQ_RUN bit be set again after leave() has
cleared it when a scan finishes at exactly the
same time. Avoid that by setting the ssid_len
to zero before clearing REQ_RUN which signals
to the scan finish code that this interface is
not active.

Reported-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/ibss.c |   19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

--- wireless-testing.orig/net/mac80211/ibss.c	2010-07-20 10:25:03.000000000 +0200
+++ wireless-testing/net/mac80211/ibss.c	2010-07-20 10:27:56.000000000 +0200
@@ -943,11 +943,6 @@ int ieee80211_ibss_leave(struct ieee8021
 		}
 	}
 
-	del_timer_sync(&sdata->u.ibss.timer);
-	clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
-	cancel_work_sync(&sdata->work);
-	clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
-
 	sta_info_flush(sdata->local, sdata);
 
 	/* remove beacon */
@@ -964,6 +959,20 @@ int ieee80211_ibss_leave(struct ieee8021
 	memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
 	sdata->u.ibss.ssid_len = 0;
 
+	/*
+	 * ssid_len indicates active or not, so needs to be visible to
+	 * everybody, especially ieee80211_ibss_notify_scan_completed,
+	 * so it won't restart the timer after we remove it here.
+	 */
+	mb();
+
+	del_timer_sync(&sdata->u.ibss.timer);
+	clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+	/*
+	 * Since the REQ_RUN bit is clear, the work won't do
+	 * anything if it runs after this.
+	 */
+
 	ieee80211_recalc_idle(sdata->local);
 
 	return 0;



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-07-21  8:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-21  8:52 [PATCH] mac80211: fix IBSS lockdep complaint Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).