Skip to content

Commit

Permalink
mac80211: move synchronize_net() before sta key removal
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Berg committed Dec 16, 2013
1 parent d34ba21 commit c878207
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 14 deletions.
16 changes: 3 additions & 13 deletions net/mac80211/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
void ieee80211_free_sta_keys(struct ieee80211_local *local,
struct sta_info *sta)
{
struct ieee80211_key *key, *tmp;
LIST_HEAD(keys);
struct ieee80211_key *key;
int i;

mutex_lock(&local->key_mtx);
Expand All @@ -640,7 +639,7 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
ieee80211_key_replace(key->sdata, key->sta,
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
key, NULL);
list_add(&key->list, &keys);
__ieee80211_key_destroy(key, true);
}

for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
Expand All @@ -650,17 +649,8 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
ieee80211_key_replace(key->sdata, key->sta,
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
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);
}

mutex_unlock(&local->key_mtx);
}
Expand Down
3 changes: 2 additions & 1 deletion net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
rcu_access_pointer(sdata->u.vlan.sta) == sta)
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);

sta->dead = true;
Expand Down

0 comments on commit c878207

Please sign in to comment.