aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-12-04 17:05:45 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-12-16 05:29:46 -0500
commitc87820784454bbf7fc63a9e7d9c36762a46f393c (patch)
tree2b46b2dded299efa1f07e41cb9ce8ac1750a0a6c /net
parentd34ba2168a3c10e7301cca06069c39865b4c3ec6 (diff)
mac80211: move synchronize_net() before sta key removal
There's no reason to do this inside the sta key removal since the keys can only be reached through the sta (and not by the driver at all) so once the sta can no longer be reached, the keys are safe. This will allow further optimisation opportunities with multiple stations. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/key.c16
-rw-r--r--net/mac80211/sta_info.c3
2 files changed, 5 insertions, 14 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index e568d98167d0..12e61543a37c 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -628,8 +628,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
628void ieee80211_free_sta_keys(struct ieee80211_local *local, 628void ieee80211_free_sta_keys(struct ieee80211_local *local,
629 struct sta_info *sta) 629 struct sta_info *sta)
630{ 630{
631 struct ieee80211_key *key, *tmp; 631 struct ieee80211_key *key;
632 LIST_HEAD(keys);
633 int i; 632 int i;
634 633
635 mutex_lock(&local->key_mtx); 634 mutex_lock(&local->key_mtx);
@@ -640,7 +639,7 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
640 ieee80211_key_replace(key->sdata, key->sta, 639 ieee80211_key_replace(key->sdata, key->sta,
641 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 640 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
642 key, NULL); 641 key, NULL);
643 list_add(&key->list, &keys); 642 __ieee80211_key_destroy(key, true);
644 } 643 }
645 644
646 for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 645 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
@@ -650,17 +649,8 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
650 ieee80211_key_replace(key->sdata, key->sta, 649 ieee80211_key_replace(key->sdata, key->sta,
651 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 650 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
652 key, NULL); 651 key, NULL);
653 list_add(&key->list, &keys);
654 }
655
656 /*
657 * NB: the station code relies on this being
658 * done even if there aren't any keys
659 */
660 synchronize_net();
661
662 list_for_each_entry_safe(key, tmp, &keys, list)
663 __ieee80211_key_destroy(key, true); 652 __ieee80211_key_destroy(key, true);
653 }
664 654
665 mutex_unlock(&local->key_mtx); 655 mutex_unlock(&local->key_mtx);
666} 656}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 7241f3229a27..08e50760e092 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -831,7 +831,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
831 rcu_access_pointer(sdata->u.vlan.sta) == sta) 831 rcu_access_pointer(sdata->u.vlan.sta) == sta)
832 RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); 832 RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
833 833
834 /* this always calls synchronize_net() */ 834 synchronize_net();
835 /* now keys can no longer be reached */
835 ieee80211_free_sta_keys(local, sta); 836 ieee80211_free_sta_keys(local, sta);
836 837
837 sta->dead = true; 838 sta->dead = true;