[openwrt/openwrt] mac80211: fix a tx queue memory accounting error

LEDE Commits lede-commits at lists.infradead.org
Sat Mar 10 02:58:41 PST 2018


nbd pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/6011f7bcf0bfab0d65fb0522de0c210565fe4e74

commit 6011f7bcf0bfab0d65fb0522de0c210565fe4e74
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Thu Mar 8 21:13:25 2018 +0100

    mac80211: fix a tx queue memory accounting error
    
    Fixes rare hard to trigger tx hangs after some time
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 ...x-memory-accounting-with-A-MSDU-aggregati.patch | 66 ++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch b/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch
new file mode 100644
index 0000000..af98f61
--- /dev/null
+++ b/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch
@@ -0,0 +1,66 @@
+From: Felix Fietkau <nbd at nbd.name>
+Date: Thu, 8 Mar 2018 21:00:56 +0100
+Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation
+
+fq uses skb->truesize for memory usage tracking. Increments/decrements
+are done on enqueue/dequeue.
+When A-MSDU aggregation is performed on tx side, the packet is
+aggregated with the last packet in the queue belonging to the same flow.
+There are multiple bugs here:
+- The truesize field of the aggregated packet isn't updated, so memory
+usage is underestimated
+- fq->memory_usage isn't adjusted.
+
+Because of the combination of both bugs, this only causes tx issues in
+rare cases, mainly when the A-MSDU head needs to be reallocated.
+
+Fix this by adjusting both truesize of the A-MSDU head and adding the
+truesize delta to fq->memory_usage.
+
+Signed-off-by: Felix Fietkau <nbd at nbd.name>
+---
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3171,6 +3171,7 @@ static bool ieee80211_amsdu_aggregate(st
+ 	u8 max_subframes = sta->sta.max_amsdu_subframes;
+ 	int max_frags = local->hw.max_tx_fragments;
+ 	int max_amsdu_len = sta->sta.max_amsdu_len;
++	int orig_truesize;
+ 	__be16 len;
+ 	void *data;
+ 	bool ret = false;
+@@ -3201,12 +3202,13 @@ static bool ieee80211_amsdu_aggregate(st
+ 	flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func);
+ 	head = skb_peek_tail(&flow->queue);
+ 	if (!head)
+-		goto out;
++		goto unlock;
+ 
++	orig_truesize = head->truesize;
+ 	orig_len = head->len;
+ 
+ 	if (skb->len + head->len > max_amsdu_len)
+-		goto out;
++		goto unlock;
+ 
+ 	if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
+ 		goto out;
+@@ -3241,6 +3243,7 @@ static bool ieee80211_amsdu_aggregate(st
+ 
+ 	head->len += skb->len;
+ 	head->data_len += skb->len;
++	head->truesize += skb->truesize;
+ 	*frag_tail = skb;
+ 
+ 	flow->backlog += head->len - orig_len;
+@@ -3249,6 +3252,9 @@ static bool ieee80211_amsdu_aggregate(st
+ 	fq_recalc_backlog(fq, tin, flow);
+ 
+ out:
++	fq->memory_usage += head->truesize - orig_truesize;
++
++unlock:
+ 	spin_unlock_bh(&fq->lock);
+ 
+ 	return ret;



More information about the lede-commits mailing list