| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- From: Nicolas Escande <[email protected]>
- Date: Mon, 14 Feb 2022 18:32:14 +0100
- Subject: [PATCH] mac80211: fix forwarded mesh frames AC & queue selection
- There are two problems with the current code that have been highlighted
- with the AQL feature that is now enbaled by default.
- First problem is in ieee80211_rx_h_mesh_fwding(),
- ieee80211_select_queue_80211() is used on received packets to choose
- the sending AC queue of the forwarding packet although this function
- should only be called on TX packet (it uses ieee80211_tx_info).
- This ends with forwarded mesh packets been sent on unrelated random AC
- queue. To fix that, AC queue can directly be infered from skb->priority
- which has been extracted from QOS info (see ieee80211_parse_qos()).
- Second problem is the value of queue_mapping set on forwarded mesh
- frames via skb_set_queue_mapping() is not the AC of the packet but a
- hardware queue index. This may or may not work depending on AC to HW
- queue mapping which is driver specific.
- Both of these issues lead to improper AC selection while forwarding
- mesh packets but more importantly due to improper airtime accounting
- (which is done on a per STA, per AC basis) caused traffic stall with
- the introduction of AQL.
- Fixes: cf44012810cc ("mac80211: fix unnecessary frame drops in mesh fwding")
- Fixes: d3c1597b8d1b ("mac80211: fix forwarded mesh frame queue mapping")
- Co-developed-by: Remi Pommarel <[email protected]>
- Signed-off-by: Remi Pommarel <[email protected]>
- Signed-off-by: Nicolas Escande <[email protected]>
- ---
- --- a/net/mac80211/rx.c
- +++ b/net/mac80211/rx.c
- @@ -2921,13 +2921,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
- ether_addr_equal(sdata->vif.addr, hdr->addr3))
- return RX_CONTINUE;
-
- - ac = ieee80211_select_queue_80211(sdata, skb, hdr);
- + ac = ieee802_1d_to_ac[skb->priority];
- q = sdata->vif.hw_queue[ac];
- if (ieee80211_queue_stopped(&local->hw, q)) {
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
- return RX_DROP_MONITOR;
- }
- - skb_set_queue_mapping(skb, q);
- + skb_set_queue_mapping(skb, ac);
-
- if (!--mesh_hdr->ttl) {
- if (!is_multicast_ether_addr(hdr->addr1))
|