forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mac80211: fix spurious disconnect issues with disassoc_low_ack=1 (def…
…ault) mac80211 reports a packet loss event to user space when 50 consecutive packets were not acked. On a high throughput link with long aggregates and sudden link changes, this can trigger way too easily. Mitigate false positives by only triggering the event on a packet loss if no ACK was received for at least a second Signed-off-by: Felix Fietkau <[email protected]>
- Loading branch information
Showing
1 changed file
with
116 additions
and
0 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
...ernel/mac80211/patches/subsys/310-mac80211-reduce-packet-loss-event-false-positives.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
From: Felix Fietkau <[email protected]> | ||
Date: Sat, 8 Aug 2020 19:20:02 +0200 | ||
Subject: [PATCH] mac80211: reduce packet loss event false positives | ||
|
||
When running a large number of packets per second with a high data rate | ||
and long A-MPDUs, the packet loss threshold can be reached very quickly | ||
when the link conditions change. This frequently shows up as spurious | ||
disconnects. | ||
Mitigate false positives by using a similar logic for regular stations | ||
as the one being used for TDLS, though with a more aggressive timeout. | ||
Packet loss events are only reported if no ACK was received for a second. | ||
|
||
Signed-off-by: Felix Fietkau <[email protected]> | ||
--- | ||
|
||
--- a/net/mac80211/sta_info.h | ||
+++ b/net/mac80211/sta_info.h | ||
@@ -522,7 +522,7 @@ struct ieee80211_sta_rx_stats { | ||
* @status_stats.retry_failed: # of frames that failed after retry | ||
* @status_stats.retry_count: # of retries attempted | ||
* @status_stats.lost_packets: # of lost packets | ||
- * @status_stats.last_tdls_pkt_time: timestamp of last TDLS packet | ||
+ * @status_stats.last_pkt_time: timestamp of last ACKed packet | ||
* @status_stats.msdu_retries: # of MSDU retries | ||
* @status_stats.msdu_failed: # of failed MSDUs | ||
* @status_stats.last_ack: last ack timestamp (jiffies) | ||
@@ -595,7 +595,7 @@ struct sta_info { | ||
unsigned long filtered; | ||
unsigned long retry_failed, retry_count; | ||
unsigned int lost_packets; | ||
- unsigned long last_tdls_pkt_time; | ||
+ unsigned long last_pkt_time; | ||
u64 msdu_retries[IEEE80211_NUM_TIDS + 1]; | ||
u64 msdu_failed[IEEE80211_NUM_TIDS + 1]; | ||
unsigned long last_ack; | ||
--- a/net/mac80211/status.c | ||
+++ b/net/mac80211/status.c | ||
@@ -749,12 +749,16 @@ static void ieee80211_report_used_skb(st | ||
* - current throughput (higher value for higher tpt)? | ||
*/ | ||
#define STA_LOST_PKT_THRESHOLD 50 | ||
+#define STA_LOST_PKT_TIME HZ /* 1 sec since last ACK */ | ||
#define STA_LOST_TDLS_PKT_THRESHOLD 10 | ||
#define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */ | ||
|
||
static void ieee80211_lost_packet(struct sta_info *sta, | ||
struct ieee80211_tx_info *info) | ||
{ | ||
+ unsigned long pkt_time = STA_LOST_PKT_TIME; | ||
+ unsigned int pkt_thr = STA_LOST_PKT_THRESHOLD; | ||
+ | ||
/* If driver relies on its own algorithm for station kickout, skip | ||
* mac80211 packet loss mechanism. | ||
*/ | ||
@@ -767,21 +771,20 @@ static void ieee80211_lost_packet(struct | ||
return; | ||
|
||
sta->status_stats.lost_packets++; | ||
- if (!sta->sta.tdls && | ||
- sta->status_stats.lost_packets < STA_LOST_PKT_THRESHOLD) | ||
- return; | ||
+ if (sta->sta.tdls) { | ||
+ pkt_time = STA_LOST_TDLS_PKT_TIME; | ||
+ pkt_thr = STA_LOST_PKT_THRESHOLD; | ||
+ } | ||
|
||
/* | ||
* If we're in TDLS mode, make sure that all STA_LOST_TDLS_PKT_THRESHOLD | ||
* of the last packets were lost, and that no ACK was received in the | ||
* last STA_LOST_TDLS_PKT_TIME ms, before triggering the CQM packet-loss | ||
* mechanism. | ||
+ * For non-TDLS, use STA_LOST_PKT_THRESHOLD and STA_LOST_PKT_TIME | ||
*/ | ||
- if (sta->sta.tdls && | ||
- (sta->status_stats.lost_packets < STA_LOST_TDLS_PKT_THRESHOLD || | ||
- time_before(jiffies, | ||
- sta->status_stats.last_tdls_pkt_time + | ||
- STA_LOST_TDLS_PKT_TIME))) | ||
+ if (sta->status_stats.lost_packets < pkt_thr || | ||
+ !time_after(jiffies, sta->status_stats.last_pkt_time + pkt_time)) | ||
return; | ||
|
||
cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, | ||
@@ -1034,9 +1037,7 @@ static void __ieee80211_tx_status(struct | ||
sta->status_stats.lost_packets = 0; | ||
|
||
/* Track when last TDLS packet was ACKed */ | ||
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) | ||
- sta->status_stats.last_tdls_pkt_time = | ||
- jiffies; | ||
+ sta->status_stats.last_pkt_time = jiffies; | ||
} else if (noack_success) { | ||
/* nothing to do here, do not account as lost */ | ||
} else { | ||
@@ -1169,9 +1170,8 @@ void ieee80211_tx_status_ext(struct ieee | ||
if (sta->status_stats.lost_packets) | ||
sta->status_stats.lost_packets = 0; | ||
|
||
- /* Track when last TDLS packet was ACKed */ | ||
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) | ||
- sta->status_stats.last_tdls_pkt_time = jiffies; | ||
+ /* Track when last packet was ACKed */ | ||
+ sta->status_stats.last_pkt_time = jiffies; | ||
} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) { | ||
return; | ||
} else if (noack_success) { | ||
@@ -1260,8 +1260,7 @@ void ieee80211_tx_status_8023(struct iee | ||
if (sta->status_stats.lost_packets) | ||
sta->status_stats.lost_packets = 0; | ||
|
||
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) | ||
- sta->status_stats.last_tdls_pkt_time = jiffies; | ||
+ sta->status_stats.last_pkt_time = jiffies; | ||
} else { | ||
ieee80211_lost_packet(sta, info); | ||
} |