summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLior Cohen <lior2.cohen@intel.com>2019-08-30 07:24:49 -0400
committerJohannes Berg <johannes.berg@intel.com>2019-09-11 03:33:28 -0400
commit624ff4b210ecccb0a39387993302b1a6af74176e (patch)
tree4e99e2fd624d4bc1aeaae2bf6675c72c7497eb8a
parent1c9559734eca3dc03a4c805fbf5103349d7a7cf3 (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.c40
-rw-r--r--net/mac80211/key.h4
-rw-r--r--net/mac80211/util.c6
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
846void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) 846void 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
875void 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);
157void ieee80211_free_sta_keys(struct ieee80211_local *local, 158void ieee80211_free_sta_keys(struct ieee80211_local *local,
158 struct sta_info *sta); 159 struct sta_info *sta);
159void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 160void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata);
160void 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);