Commit c8782078 authored by Johannes Berg's avatar Johannes Berg

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent d34ba216
...@@ -628,8 +628,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) ...@@ -628,8 +628,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
void ieee80211_free_sta_keys(struct ieee80211_local *local, void ieee80211_free_sta_keys(struct ieee80211_local *local,
struct sta_info *sta) struct sta_info *sta)
{ {
struct ieee80211_key *key, *tmp; struct ieee80211_key *key;
LIST_HEAD(keys);
int i; int i;
mutex_lock(&local->key_mtx); mutex_lock(&local->key_mtx);
...@@ -640,7 +639,7 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local, ...@@ -640,7 +639,7 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
ieee80211_key_replace(key->sdata, key->sta, ieee80211_key_replace(key->sdata, key->sta,
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
key, NULL); key, NULL);
list_add(&key->list, &keys); __ieee80211_key_destroy(key, true);
} }
for (i = 0; i < NUM_DEFAULT_KEYS; i++) { for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
...@@ -650,17 +649,8 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local, ...@@ -650,17 +649,8 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
ieee80211_key_replace(key->sdata, key->sta, ieee80211_key_replace(key->sdata, key->sta,
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
key, NULL); key, NULL);
list_add(&key->list, &keys);
}
/*
* NB: the station code relies on this being
* done even if there aren't any keys
*/
synchronize_net();
list_for_each_entry_safe(key, tmp, &keys, list)
__ieee80211_key_destroy(key, true); __ieee80211_key_destroy(key, true);
}
mutex_unlock(&local->key_mtx); mutex_unlock(&local->key_mtx);
} }
......
...@@ -831,7 +831,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta) ...@@ -831,7 +831,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
rcu_access_pointer(sdata->u.vlan.sta) == sta) rcu_access_pointer(sdata->u.vlan.sta) == sta)
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
/* this always calls synchronize_net() */ synchronize_net();
/* now keys can no longer be reached */
ieee80211_free_sta_keys(local, sta); ieee80211_free_sta_keys(local, sta);
sta->dead = true; sta->dead = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment