1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Thu, 8 Mar 2018 21:00:56 +0100
3 Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation
5 fq uses skb->truesize for memory usage tracking. Increments/decrements
6 are done on enqueue/dequeue.
7 When A-MSDU aggregation is performed on tx side, the packet is
8 aggregated with the last packet in the queue belonging to the same flow.
9 There are multiple bugs here:
10 - The truesize field of the aggregated packet isn't updated, so memory
11 usage is underestimated
12 - fq->memory_usage isn't adjusted.
14 Because of the combination of both bugs, this only causes tx issues in
15 rare cases, mainly when the A-MSDU head needs to be reallocated.
17 Fix this by adjusting both truesize of the A-MSDU head and adding the
18 truesize delta to fq->memory_usage.
20 Signed-off-by: Felix Fietkau <nbd@nbd.name>
23 --- a/net/mac80211/tx.c
24 +++ b/net/mac80211/tx.c
25 @@ -3214,6 +3214,7 @@ static bool ieee80211_amsdu_aggregate(st
26 u8 max_subframes = sta->sta.max_amsdu_subframes;
27 int max_frags = local->hw.max_tx_fragments;
28 int max_amsdu_len = sta->sta.max_amsdu_len;
33 @@ -3252,12 +3253,13 @@ static bool ieee80211_amsdu_aggregate(st
34 flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func);
35 head = skb_peek_tail(&flow->queue);
36 if (!head || skb_is_gso(head))
40 + orig_truesize = head->truesize;
43 if (skb->len + head->len > max_amsdu_len)
47 nfrags = 1 + skb_shinfo(skb)->nr_frags;
48 nfrags += 1 + skb_shinfo(head)->nr_frags;
49 @@ -3318,6 +3320,9 @@ out_recalc:
50 fq_recalc_backlog(fq, tin, flow);
53 + fq->memory_usage += head->truesize - orig_truesize;
56 spin_unlock_bh(&fq->lock);