Search Linux Wireless

[PATCH 2/2] wifi: iwlwifi: Fix emlsr exit due to tput sampling too fast.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ben Greear <greearb@xxxxxxxxxxxxxxx>

I noticed that the tput check was running very often (and often
right after we entered emlsr mode), putting the radio in and
out of emlsr mode often.  That caused link instability as well
as poor performance.  Add timer so that we only
check stats after at least 5 seconds.

Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx>
---
 drivers/net/wireless/intel/iwlwifi/mvm/link.c |  5 +++++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c   | 12 ++++++++++--
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
index f3fb37fec8a8..d4e232d2818b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
@@ -1112,6 +1112,11 @@ static void iwl_mvm_esr_unblocked(struct iwl_mvm *mvm,
 
 	IWL_DEBUG_INFO(mvm, "EMLSR is unblocked\n");
 
+	/* Don't block based on tput until at least our sample period,
+	 * by faking that we sampled just now.
+	 */
+	mvm->esr_tpt_ts = jiffies;
+
 	/* If we exited due to an EXIT reason, and the exit was in less than
 	 * 30 seconds, then a MLO scan was scheduled already.
 	 */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 22bec9ca46bb..5bbb8063bd1f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1101,6 +1101,7 @@ struct iwl_mvm {
 	unsigned long init_status;
 
 	unsigned long status;
+	unsigned long esr_tpt_ts; /* last time we compared tput for ESR */
 
 	u32 queue_sync_cookie;
 	unsigned long queue_sync_state;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index 41301070d23c..49442dd7ddd5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -1035,6 +1035,8 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
 #define SEC_LINK_MIN_PERC 10
 #define SEC_LINK_MIN_TX 3000
 #define SEC_LINK_MIN_RX 400
+/* Compare tput over this interval to determine in/out of ESR mode */
+#define MVM_ESR_TPT_INTERVAL (5 * HZ)
 
 static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
 {
@@ -1061,6 +1063,10 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
 	if (!mvmsta->mpdu_counters)
 		return;
 
+	if (!time_after(jiffies, mvm->esr_tpt_ts + MVM_ESR_TPT_INTERVAL))
+		return; /* check back later */
+	mvm->esr_tpt_ts = jiffies;
+
 	/* Get the FW ID of the secondary link */
 	sec_link = iwl_mvm_get_other_link(bss_vif,
 					  iwl_mvm_get_primary_link(bss_vif));
@@ -1084,6 +1090,8 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
 		/*
 		 * In EMLSR we have statistics every 5 seconds, so we can reset
 		 * the counters upon every statistics notification.
+		 * NOTE:  This is not actually correct, I see this method called
+		 * often.  Thus the back-off timer 'esr_tpt_ts' above. --Ben
 		 */
 		memset(mvmsta->mpdu_counters[q].per_link, 0,
 		       sizeof(mvmsta->mpdu_counters[q].per_link));
@@ -1091,8 +1099,8 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
 		spin_unlock_bh(&mvmsta->mpdu_counters[q].lock);
 	}
 
-	IWL_DEBUG_STATS(mvm, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n",
-			total_tx, total_rx);
+	IWL_DEBUG_INFO(mvm, "EMLSR: total Tx MPDUs: %ld. Rx: %ld sec-link tx: %ld  rx: %ld mvm-tput-thresh: %d\n",
+		       total_tx, total_rx, sec_link_tx, sec_link_rx, IWL_MVM_ENTER_ESR_TPT_THRESH);
 
 	/* If we don't have enough MPDUs - exit EMLSR */
 	if (total_tx < IWL_MVM_ENTER_ESR_TPT_THRESH &&
-- 
2.42.0





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux