From: Felix Fietkau Date: Sun, 28 Mar 2021 10:15:42 +0000 (+0200) Subject: mac80211: merge a few pending tx related fixes X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=571aedbc6cbb7a9bfc96bcad543a39d158925cbc;p=openwrt%2Fstaging%2Fldir.git mac80211: merge a few pending tx related fixes Improve performance and fix potential mgmt tx hangs/warnings Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch b/package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch new file mode 100644 index 0000000000..0b7c8dd49b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch @@ -0,0 +1,61 @@ +From: Johannes Berg +Date: Tue, 23 Mar 2021 21:05:01 +0100 +Subject: [PATCH] mac80211: fix TXQ AC confusion + +Normally, TXQs have + + txq->tid = tid; + txq->ac = ieee80211_ac_from_tid(tid); + +However, the special management TXQ actually has + + txq->tid = IEEE80211_NUM_TIDS; // 16 + txq->ac = IEEE80211_AC_VO; + +This makes sense, but ieee80211_ac_from_tid(16) is the same +as ieee80211_ac_from_tid(0) which is just IEEE80211_AC_BE. + +Now, normally this is fine. However, if the netdev queues +were stopped, then the code in ieee80211_tx_dequeue() will +propagate the stop from the interface (vif->txqs_stopped[]) +if the AC 2 (ieee80211_ac_from_tid(txq->tid)) is marked as +stopped. On wake, however, __ieee80211_wake_txqs() will wake +the TXQ if AC 0 (txq->ac) is woken up. + +If a driver stops all queues with ieee80211_stop_tx_queues() +and then wakes them again with ieee80211_wake_tx_queues(), +the ieee80211_wake_txqs() tasklet will run to resync queue +and TXQ state. If all queues were woken, then what'll happen +is that _ieee80211_wake_txqs() will run in order of HW queues +0-3, typically (and certainly for iwlwifi) corresponding to +ACs 0-3, so it'll call __ieee80211_wake_txqs() for each AC in +order 0-3. + +When __ieee80211_wake_txqs() is called for AC 0 (VO) that'll +wake up the management TXQ (remember its tid is 16), and the +driver's wake_tx_queue() will be called. That tries to get a +frame, which will immediately *stop* the TXQ again, because +now we check against AC 2, and AC 2 hasn't yet been marked as +woken up again in sdata->vif.txqs_stopped[] since we're only +in the __ieee80211_wake_txqs() call for AC 0. + +Thus, the management TXQ will never be started again. + +Fix this by checking txq->ac directly instead of calculating +the AC as ieee80211_ac_from_tid(txq->tid). + +Fixes: adf8ed01e4fd ("mac80211: add an optional TXQ for other PS-buffered frames") +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3589,7 +3589,7 @@ begin: + test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags)) + goto out; + +- if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) { ++ if (vif->txqs_stopped[txq->ac]) { + set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags); + goto out; + } diff --git a/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch b/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch new file mode 100644 index 0000000000..b439a3814c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch @@ -0,0 +1,60 @@ +From: Johannes Berg +Date: Fri, 19 Mar 2021 23:28:01 +0100 +Subject: [PATCH] mac80211: don't apply flow control on management frames + +In some cases (depending on the driver, but it's true e.g. for +iwlwifi) we're using an internal TXQ for management packets, +mostly to simplify the code and to have a place to queue them. +However, it appears that in certain cases we can confuse the +code and management frames are dropped, which is certainly not +what we want. + +Short-circuit the processing of management frames. To keep the +impact minimal, only put them on the frags queue and check the +tid == management only for doing that and to skip the airtime +fairness checks, if applicable. + +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -5,7 +5,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2007 Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + * + * Transmit and frame generation functions. + */ +@@ -1403,8 +1403,17 @@ static void ieee80211_txq_enqueue(struct + ieee80211_set_skb_enqueue_time(skb); + + spin_lock_bh(&fq->lock); +- fq_tin_enqueue(fq, tin, flow_idx, skb, +- fq_skb_free_func); ++ /* ++ * For management frames, don't really apply codel etc., ++ * we don't want to apply any shaping or anything we just ++ * want to simplify the driver API by having them on the ++ * txqi. ++ */ ++ if (unlikely(txqi->txq.tid == IEEE80211_NUM_TIDS)) ++ __skb_queue_tail(&txqi->frags, skb); ++ else ++ fq_tin_enqueue(fq, tin, flow_idx, skb, ++ fq_skb_free_func); + spin_unlock_bh(&fq->lock); + } + +@@ -3846,6 +3855,9 @@ bool ieee80211_txq_airtime_check(struct + if (!txq->sta) + return true; + ++ if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) ++ return true; ++ + sta = container_of(txq->sta, struct sta_info, sta); + if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < + sta->airtime[txq->ac].aql_limit_low) diff --git a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch new file mode 100644 index 0000000000..4d8a91a413 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch @@ -0,0 +1,21 @@ +From: Lorenzo Bianconi +Date: Mon, 8 Mar 2021 23:01:49 +0100 +Subject: [PATCH] mac80211: set sk_pacing_shift for 802.3 txpath + +Similar to 802.11 txpath, set socket sk_pacing_shift for 802.3 tx path. + +Signed-off-by: Lorenzo Bianconi +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4173,6 +4173,9 @@ static bool ieee80211_tx_8023(struct iee + unsigned long flags; + int q = info->hw_queue; + ++ if (sta) ++ sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); ++ + if (ieee80211_queue_skb(local, sdata, sta, skb)) + return true; +