cfg80211: vastly simplify locking

Virtually all code paths in cfg80211 already (need to) hold
the RTNL. As such, there's little point in having another
four mutexes for various parts of the code, they just cause
lock ordering issues (and much of the time, the RTNL and a
few of the others need thus be held.)

Simplify all this by getting rid of the extra four mutexes
and just use the RTNL throughout. Only a few code changes
were needed to do this and we can get rid of a work struct
for bonus points.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cc35fba..e765596 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -377,7 +377,7 @@
 	const struct ieee80211_regdomain *curdom, *regdom = NULL;
 	int i;
 
-	mutex_lock(&cfg80211_mutex);
+	rtnl_lock();
 
 	mutex_lock(&reg_regdb_search_mutex);
 	while (!list_empty(&reg_regdb_search_list)) {
@@ -402,7 +402,7 @@
 	if (!IS_ERR_OR_NULL(regdom))
 		set_regdom(regdom);
 
-	mutex_unlock(&cfg80211_mutex);
+	rtnl_unlock();
 }
 
 static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -1225,7 +1225,7 @@
 	struct cfg80211_registered_device *rdev;
 	struct wiphy *wiphy;
 
-	assert_cfg80211_lock();
+	ASSERT_RTNL();
 
 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
 		wiphy = &rdev->wiphy;
@@ -1570,21 +1570,19 @@
 {
 	struct regulatory_request *reg_request, *lr;
 
-	mutex_lock(&cfg80211_mutex);
-	mutex_lock(&reg_mutex);
 	lr = get_last_request();
 
 	/* When last_request->processed becomes true this will be rescheduled */
 	if (lr && !lr->processed) {
 		REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n");
-		goto out;
+		return;
 	}
 
 	spin_lock(&reg_requests_lock);
 
 	if (list_empty(&reg_requests_list)) {
 		spin_unlock(&reg_requests_lock);
-		goto out;
+		return;
 	}
 
 	reg_request = list_first_entry(&reg_requests_list,
@@ -1595,10 +1593,6 @@
 	spin_unlock(&reg_requests_lock);
 
 	reg_process_hint(reg_request, reg_request->initiator);
-
-out:
-	mutex_unlock(&reg_mutex);
-	mutex_unlock(&cfg80211_mutex);
 }
 
 /* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1607,9 +1601,6 @@
 	struct cfg80211_registered_device *rdev;
 	struct reg_beacon *pending_beacon, *tmp;
 
-	mutex_lock(&cfg80211_mutex);
-	mutex_lock(&reg_mutex);
-
 	/* This goes through the _pending_ beacon list */
 	spin_lock_bh(&reg_pending_beacons_lock);
 
@@ -1626,14 +1617,16 @@
 	}
 
 	spin_unlock_bh(&reg_pending_beacons_lock);
-	mutex_unlock(&reg_mutex);
-	mutex_unlock(&cfg80211_mutex);
 }
 
 static void reg_todo(struct work_struct *work)
 {
+	rtnl_lock();
+	mutex_lock(&reg_mutex);
 	reg_process_pending_hints();
 	reg_process_pending_beacon_hints();
+	mutex_unlock(&reg_mutex);
+	rtnl_unlock();
 }
 
 static void queue_regulatory_request(struct regulatory_request *request)
@@ -1717,10 +1710,6 @@
 }
 EXPORT_SYMBOL(regulatory_hint);
 
-/*
- * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
- * therefore cannot iterate over the rdev list here.
- */
 void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
 			 const u8 *country_ie, u8 country_ie_len)
 {
@@ -1752,7 +1741,7 @@
 	/*
 	 * We will run this only upon a successful connection on cfg80211.
 	 * We leave conflict resolution to the workqueue, where can hold
-	 * cfg80211_mutex.
+	 * the RTNL.
 	 */
 	if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
 	    lr->wiphy_idx != WIPHY_IDX_INVALID)
@@ -1858,7 +1847,8 @@
 	LIST_HEAD(tmp_reg_req_list);
 	struct cfg80211_registered_device *rdev;
 
-	mutex_lock(&cfg80211_mutex);
+	ASSERT_RTNL();
+
 	mutex_lock(&reg_mutex);
 
 	reset_regdomains(true, &world_regdom);
@@ -1915,7 +1905,6 @@
 	spin_unlock(&reg_requests_lock);
 
 	mutex_unlock(&reg_mutex);
-	mutex_unlock(&cfg80211_mutex);
 
 	REG_DBG_PRINT("Kicking the queue\n");
 
@@ -2297,7 +2286,6 @@
 	mutex_unlock(&reg_mutex);
 }
 
-/* Caller must hold cfg80211_mutex */
 void wiphy_regulatory_deregister(struct wiphy *wiphy)
 {
 	struct wiphy *request_wiphy = NULL;