aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-05-10 13:07:52 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-05-24 18:02:18 -0400
commitdb2424c58e5962a87888d25d29ceb0873eef6348 (patch)
tree6979069932dd9b37d30a849b3946891a20f03dc7 /net/wireless
parent1cdd59ce8dcfa850ebb8ac2ab000a2ea572d1d69 (diff)
regulatory: use RCU in regulatory_hint_11d()
Since it just does a quick check of the last regulatory request, the function doesn't have to hold the reg mutex but can use RCU instead. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/reg.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e76559618588..17e5eccb42c8 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1715,20 +1715,18 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1715{ 1715{
1716 char alpha2[2]; 1716 char alpha2[2];
1717 enum environment_cap env = ENVIRON_ANY; 1717 enum environment_cap env = ENVIRON_ANY;
1718 struct regulatory_request *request, *lr; 1718 struct regulatory_request *request = NULL, *lr;
1719
1720 mutex_lock(&reg_mutex);
1721 lr = get_last_request();
1722
1723 if (unlikely(!lr))
1724 goto out;
1725 1719
1726 /* IE len must be evenly divisible by 2 */ 1720 /* IE len must be evenly divisible by 2 */
1727 if (country_ie_len & 0x01) 1721 if (country_ie_len & 0x01)
1728 goto out; 1722 return;
1729 1723
1730 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 1724 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1731 goto out; 1725 return;
1726
1727 request = kzalloc(sizeof(*request), GFP_KERNEL);
1728 if (!request)
1729 return;
1732 1730
1733 alpha2[0] = country_ie[0]; 1731 alpha2[0] = country_ie[0];
1734 alpha2[1] = country_ie[1]; 1732 alpha2[1] = country_ie[1];
@@ -1738,6 +1736,12 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1738 else if (country_ie[2] == 'O') 1736 else if (country_ie[2] == 'O')
1739 env = ENVIRON_OUTDOOR; 1737 env = ENVIRON_OUTDOOR;
1740 1738
1739 rcu_read_lock();
1740 lr = get_last_request();
1741
1742 if (unlikely(!lr))
1743 goto out;
1744
1741 /* 1745 /*
1742 * We will run this only upon a successful connection on cfg80211. 1746 * We will run this only upon a successful connection on cfg80211.
1743 * We leave conflict resolution to the workqueue, where can hold 1747 * We leave conflict resolution to the workqueue, where can hold
@@ -1747,10 +1751,6 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1747 lr->wiphy_idx != WIPHY_IDX_INVALID) 1751 lr->wiphy_idx != WIPHY_IDX_INVALID)
1748 goto out; 1752 goto out;
1749 1753
1750 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1751 if (!request)
1752 goto out;
1753
1754 request->wiphy_idx = get_wiphy_idx(wiphy); 1754 request->wiphy_idx = get_wiphy_idx(wiphy);
1755 request->alpha2[0] = alpha2[0]; 1755 request->alpha2[0] = alpha2[0];
1756 request->alpha2[1] = alpha2[1]; 1756 request->alpha2[1] = alpha2[1];
@@ -1758,8 +1758,10 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1758 request->country_ie_env = env; 1758 request->country_ie_env = env;
1759 1759
1760 queue_regulatory_request(request); 1760 queue_regulatory_request(request);
1761 request = NULL;
1761out: 1762out:
1762 mutex_unlock(&reg_mutex); 1763 kfree(request);
1764 rcu_read_unlock();
1763} 1765}
1764 1766
1765static void restore_alpha2(char *alpha2, bool reset_user) 1767static void restore_alpha2(char *alpha2, bool reset_user)