linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: Ben Greear <greearb@candelatech.com>
Cc: "linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Subject: [PATCH] mac80211: fix deadlock with multiple interfaces
Date: Tue, 05 Oct 2010 10:41:47 +0200	[thread overview]
Message-ID: <1286268107.3641.9.camel@jlt3.sipsolutions.net> (raw)
In-Reply-To: <4CAA6468.3030706@candelatech.com>

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

The locking around ieee80211_recalc_smps is
buggy -- it cannot acquire another interface's
mutex while the iflist mutex is held because
another code path could be holding the iface
mutex and trying to acquire the iflist mutex.

But the locking is also unnecessary, we only
check "ifmgd->associated" as a bool, and don't
use the pointer (in check_mgd_smps).

Reported-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/cfg.c         |    2 +-
 net/mac80211/ieee80211_i.h |    3 +--
 net/mac80211/main.c        |    2 +-
 net/mac80211/mlme.c        |    2 +-
 net/mac80211/util.c        |   20 +++-----------------
 5 files changed, 7 insertions(+), 22 deletions(-)

--- wirelmac80211: fix deadlock with multiple interfacesess-testing.orig/net/mac80211/cfg.c	2010-10-05 10:37:21.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2010-10-05 10:37:29.000000000 +0200
@@ -1380,7 +1380,7 @@ int __ieee80211_request_smps(struct ieee
 	if (!sdata->u.mgd.associated ||
 	    sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
 		mutex_lock(&sdata->local->iflist_mtx);
-		ieee80211_recalc_smps(sdata->local, sdata);
+		ieee80211_recalc_smps(sdata->local);
 		mutex_unlock(&sdata->local->iflist_mtx);
 		return 0;
 	}
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2010-10-05 10:37:11.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2010-10-05 10:37:16.000000000 +0200
@@ -1292,8 +1292,7 @@ u32 ieee80211_sta_get_rates(struct ieee8
 			    enum ieee80211_band band);
 int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
 			     enum ieee80211_smps_mode smps_mode);
-void ieee80211_recalc_smps(struct ieee80211_local *local,
-			   struct ieee80211_sub_if_data *forsdata);
+void ieee80211_recalc_smps(struct ieee80211_local *local);
 
 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
 			  const u8 *ids, int n_ids, size_t offset);
--- wireless-testing.orig/net/mac80211/main.c	2010-10-05 10:37:36.000000000 +0200
+++ wireless-testing/net/mac80211/main.c	2010-10-05 10:37:43.000000000 +0200
@@ -329,7 +329,7 @@ static void ieee80211_recalc_smps_work(s
 		container_of(work, struct ieee80211_local, recalc_smps);
 
 	mutex_lock(&local->iflist_mtx);
-	ieee80211_recalc_smps(local, NULL);
+	ieee80211_recalc_smps(local);
 	mutex_unlock(&local->iflist_mtx);
 }
 
--- wireless-testing.orig/net/mac80211/mlme.c	2010-10-05 10:37:36.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2010-10-05 10:37:48.000000000 +0200
@@ -913,7 +913,7 @@ static void ieee80211_set_associated(str
 
 	mutex_lock(&local->iflist_mtx);
 	ieee80211_recalc_ps(local, -1);
-	ieee80211_recalc_smps(local, sdata);
+	ieee80211_recalc_smps(local);
 	mutex_unlock(&local->iflist_mtx);
 
 	netif_tx_start_all_queues(sdata->dev);
--- wireless-testing.orig/net/mac80211/util.c	2010-10-05 10:36:21.000000000 +0200
+++ wireless-testing/net/mac80211/util.c	2010-10-05 10:37:06.000000000 +0200
@@ -1297,16 +1297,12 @@ static int check_mgd_smps(struct ieee802
 }
 
 /* must hold iflist_mtx */
-void ieee80211_recalc_smps(struct ieee80211_local *local,
-			   struct ieee80211_sub_if_data *forsdata)
+void ieee80211_recalc_smps(struct ieee80211_local *local)
 {
 	struct ieee80211_sub_if_data *sdata;
 	enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
 	int count = 0;
 
-	if (forsdata)
-		lockdep_assert_held(&forsdata->u.mgd.mtx);
-
 	lockdep_assert_held(&local->iflist_mtx);
 
 	/*
@@ -1324,18 +1320,8 @@ void ieee80211_recalc_smps(struct ieee80
 			continue;
 		if (sdata->vif.type != NL80211_IFTYPE_STATION)
 			goto set;
-		if (sdata != forsdata) {
-			/*
-			 * This nested is ok -- we are holding the iflist_mtx
-			 * so can't get here twice or so. But it's required
-			 * since normally we acquire it first and then the
-			 * iflist_mtx.
-			 */
-			mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING);
-			count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
-			mutex_unlock(&sdata->u.mgd.mtx);
-		} else
-			count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
+
+		count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
 
 		if (count > 1) {
 			smps_mode = IEEE80211_SMPS_OFF;



      parent reply	other threads:[~2010-10-05  8:41 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-04 23:34 Lockup with ath5k, rtnl_mutex related? Ben Greear
2010-10-05  8:29 ` Johannes Berg
2010-10-05  8:41 ` Johannes Berg [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1286268107.3641.9.camel@jlt3.sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=greearb@candelatech.com \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).