Search Linux Wireless

[PATCH] cfg80211: fix locking and lockdep complaints

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johannes Berg <johannes.berg@xxxxxxxxx>

To call cfg80211_get_chan_state() we need to lock
the wdev, so we need to lock the wdev_iter mutex
in cfg80211_can_use_iftype_chan(). This needs to
use nested locking for lockdep.

Also, cfg80211_get_chan_state() doesn't actually
use the rdev, so remove that completely including
the lock assertion that isn't needed.

Reported-by: Eliad Peller <eliad@xxxxxxxxxx>
Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
---
 net/wireless/chan.c |    4 +---
 net/wireless/core.h |    3 +--
 net/wireless/util.c |   11 ++++++++++-
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 434c56b..1cc4b7c 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -103,15 +103,13 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
 }
 
 void
-cfg80211_get_chan_state(struct cfg80211_registered_device *rdev,
-		        struct wireless_dev *wdev,
+cfg80211_get_chan_state(struct wireless_dev *wdev,
 		        struct ieee80211_channel **chan,
 		        enum cfg80211_chan_mode *chanmode)
 {
 	*chan = NULL;
 	*chanmode = CHAN_MODE_UNDEFINED;
 
-	ASSERT_RDEV_LOCK(rdev);
 	ASSERT_WDEV_LOCK(wdev);
 
 	if (!netif_running(wdev->netdev))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index eae5a25..bac97da 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -463,8 +463,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev,
 }
 
 void
-cfg80211_get_chan_state(struct cfg80211_registered_device *rdev,
-		        struct wireless_dev *wdev,
+cfg80211_get_chan_state(struct wireless_dev *wdev,
 		        struct ieee80211_channel **chan,
 		        enum cfg80211_chan_mode *chanmode);
 
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f7a0647..26f8cd3 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1059,7 +1059,16 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
 		if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype))
 			continue;
 
-		cfg80211_get_chan_state(rdev, wdev_iter, &ch, &chmode);
+		/*
+		 * We may be holding the "wdev" mutex, but now need to lock
+		 * wdev_iter. This is OK because once we get here wdev_iter
+		 * is not wdev (tested above), but we need to use the nested
+		 * locking for lockdep.
+		 */
+		mutex_lock_nested(&wdev_iter->mtx, 1);
+		__acquire(wdev_iter->mtx);
+		cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
+		wdev_unlock(wdev_iter);
 
 		switch (chmode) {
 		case CHAN_MODE_UNDEFINED:
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux