From: Felix Fietkau 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 --- --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3185,6 +3185,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; @@ -3216,12 +3217,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; nfrags = 1 + skb_shinfo(skb)->nr_frags; nfrags += 1 + skb_shinfo(head)->nr_frags; @@ -3279,6 +3281,9 @@ out_recalc: fq_recalc_backlog(fq, tin, flow); } out: + fq->memory_usage += head->truesize - orig_truesize; + +unlock: spin_unlock_bh(&fq->lock); return ret;