diff options
author | Lior Cohen <lior2.cohen@intel.com> | 2019-08-30 07:24:49 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-09-11 03:33:28 -0400 |
commit | 624ff4b210ecccb0a39387993302b1a6af74176e (patch) | |
tree | 4e99e2fd624d4bc1aeaae2bf6675c72c7497eb8a | |
parent | 1c9559734eca3dc03a4c805fbf5103349d7a7cf3 (diff) |
mac80211: clear crypto tx tailroom counter upon keys enable
In case we got a fw restart while roaming from encrypted AP to
non-encrypted one, we might end up with hitting a warning on the pending
counter crypto_tx_tailroom_pending_dec having a non-zero value.
The following comment taken from net/mac80211/key.c explains the rational
for the delayed tailroom needed:
/*
* The reason for the delayed tailroom needed decrementing is to
* make roaming faster: during roaming, all keys are first deleted
* and then new keys are installed. The first new key causes the
* crypto_tx_tailroom_needed_cnt to go from 0 to 1, which invokes
* the cost of synchronize_net() (which can be slow). Avoid this
* by deferring the crypto_tx_tailroom_needed_cnt decrementing on
* key removal for a while, so if we roam the value is larger than
* zero and no 0->1 transition happens.
*
* The cost is that if the AP switching was from an AP with keys
* to one without, we still allocate tailroom while it would no
* longer be needed. However, in the typical (fast) roaming case
* within an ESS this usually won't happen.
*/
The next flow lead to the warning eventually reported as a bug:
1. Disconnect from encrypted AP
2. Set crypto_tx_tailroom_pending_dec = 1 for the key
3. Schedule work
4. Reconnect to non-encrypted AP
5. Add a new key, setting the tailroom counter = 1
6. Got FW restart while pending counter is set ---> hit the warning
While on it, the ieee80211_reset_crypto_tx_tailroom() func was merged into
its single caller ieee80211_reenable_keys (previously called
ieee80211_enable_keys). Also, we reset the crypto_tx_tailroom_pending_dec
and remove the counters warning as we just reset both.
Signed-off-by: Lior Cohen <lior2.cohen@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/20190830112451.21655-7-luca@coelho.fi
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/key.c | 40 | ||||
-rw-r--r-- | net/mac80211/key.h | 4 | ||||
-rw-r--r-- | net/mac80211/util.c | 6 |
3 files changed, 15 insertions, 35 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1be3686562ee..93ea03b86b80 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -843,46 +843,30 @@ void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) | |||
843 | ieee80211_key_destroy(key, delay_tailroom); | 843 | ieee80211_key_destroy(key, delay_tailroom); |
844 | } | 844 | } |
845 | 845 | ||
846 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | 846 | void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata) |
847 | { | 847 | { |
848 | struct ieee80211_key *key; | 848 | struct ieee80211_key *key; |
849 | struct ieee80211_sub_if_data *vlan; | 849 | struct ieee80211_sub_if_data *vlan; |
850 | 850 | ||
851 | ASSERT_RTNL(); | 851 | ASSERT_RTNL(); |
852 | 852 | ||
853 | if (WARN_ON(!ieee80211_sdata_running(sdata))) | ||
854 | return; | ||
855 | |||
856 | mutex_lock(&sdata->local->key_mtx); | ||
857 | |||
858 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || | ||
859 | sdata->crypto_tx_tailroom_pending_dec); | ||
860 | |||
861 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
862 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
863 | WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || | ||
864 | vlan->crypto_tx_tailroom_pending_dec); | ||
865 | } | ||
866 | |||
867 | list_for_each_entry(key, &sdata->key_list, list) { | ||
868 | increment_tailroom_need_count(sdata); | ||
869 | ieee80211_key_enable_hw_accel(key); | ||
870 | } | ||
871 | |||
872 | mutex_unlock(&sdata->local->key_mtx); | ||
873 | } | ||
874 | |||
875 | void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata) | ||
876 | { | ||
877 | struct ieee80211_sub_if_data *vlan; | ||
878 | |||
879 | mutex_lock(&sdata->local->key_mtx); | 853 | mutex_lock(&sdata->local->key_mtx); |
880 | 854 | ||
881 | sdata->crypto_tx_tailroom_needed_cnt = 0; | 855 | sdata->crypto_tx_tailroom_needed_cnt = 0; |
856 | sdata->crypto_tx_tailroom_pending_dec = 0; | ||
882 | 857 | ||
883 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 858 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
884 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 859 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { |
885 | vlan->crypto_tx_tailroom_needed_cnt = 0; | 860 | vlan->crypto_tx_tailroom_needed_cnt = 0; |
861 | vlan->crypto_tx_tailroom_pending_dec = 0; | ||
862 | } | ||
863 | } | ||
864 | |||
865 | if (ieee80211_sdata_running(sdata)) { | ||
866 | list_for_each_entry(key, &sdata->key_list, list) { | ||
867 | increment_tailroom_need_count(sdata); | ||
868 | ieee80211_key_enable_hw_accel(key); | ||
869 | } | ||
886 | } | 870 | } |
887 | 871 | ||
888 | mutex_unlock(&sdata->local->key_mtx); | 872 | mutex_unlock(&sdata->local->key_mtx); |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index b8b9cd743bf4..d6d6e89cf7dd 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -2,6 +2,7 @@ | |||
2 | /* | 2 | /* |
3 | * Copyright 2002-2004, Instant802 Networks, Inc. | 3 | * Copyright 2002-2004, Instant802 Networks, Inc. |
4 | * Copyright 2005, Devicescape Software, Inc. | 4 | * Copyright 2005, Devicescape Software, Inc. |
5 | * Copyright (C) 2019 Intel Corporation | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | #ifndef IEEE80211_KEY_H | 8 | #ifndef IEEE80211_KEY_H |
@@ -156,8 +157,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, | |||
156 | bool force_synchronize); | 157 | bool force_synchronize); |
157 | void ieee80211_free_sta_keys(struct ieee80211_local *local, | 158 | void ieee80211_free_sta_keys(struct ieee80211_local *local, |
158 | struct sta_info *sta); | 159 | struct sta_info *sta); |
159 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); | 160 | void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata); |
160 | void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata); | ||
161 | 161 | ||
162 | #define key_mtx_dereference(local, ref) \ | 162 | #define key_mtx_dereference(local, ref) \ |
163 | rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) | 163 | rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx))) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 286c7ee35e63..92bfedfd3fd2 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2420,11 +2420,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
2420 | 2420 | ||
2421 | /* add back keys */ | 2421 | /* add back keys */ |
2422 | list_for_each_entry(sdata, &local->interfaces, list) | 2422 | list_for_each_entry(sdata, &local->interfaces, list) |
2423 | ieee80211_reset_crypto_tx_tailroom(sdata); | 2423 | ieee80211_reenable_keys(sdata); |
2424 | |||
2425 | list_for_each_entry(sdata, &local->interfaces, list) | ||
2426 | if (ieee80211_sdata_running(sdata)) | ||
2427 | ieee80211_enable_keys(sdata); | ||
2428 | 2424 | ||
2429 | /* Reconfigure sched scan if it was interrupted by FW restart */ | 2425 | /* Reconfigure sched scan if it was interrupted by FW restart */ |
2430 | mutex_lock(&local->mtx); | 2426 | mutex_lock(&local->mtx); |