mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 21:44:27 -04:00 
			
		
		
		
	This updates mac80211 to backports based on kernel 4.19-rc4. I plan to integrate all the patches which are in this tar into upstream backports soon. I used the backports generated from this code: https://github.com/hauke/backports/commits/wip2 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From: Felix Fietkau <nbd@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@nbd.name>
 | |
| ---
 | |
| 
 | |
| --- a/net/mac80211/tx.c
 | |
| +++ b/net/mac80211/tx.c
 | |
| @@ -3184,6 +3184,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;
 | |
| @@ -3215,12 +3216,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;
 | |
| @@ -3278,6 +3280,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;
 |