[PATCH ath-next v2 6/9] wifi: ath11k: run the TXQ scheduler on tx completion
Julius Bairaktaris <[email protected]>
| Newsgroups | org.infradead.lists.ath11k,org.kernel.vger.linux-kernel,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
A station whose airtime queue limit is reached stops being served by ieee80211_tx_dequeue(), and the airtime it is waiting on is only returned when the hardware completes the frames already charged to it. ath11k starts a scheduling round from the wake_tx_queue callback and nowhere else, so once the limit binds, the backlog moves again only when the next frame arrives from the network stack. Under a saturated download the arrivals keep the round running; a flow that has just filled the intermediate queue, or one whose sender is waiting on the acknowledgements behind that queue, stalls for as long as it takes the next arrival to appear. Start a round for every radio whose completions were reaped, at the point where the airtime has been returned. The airtime queue limit then bounds a queue that is refilled as it drains, rather than one that is refilled when the network stack happens to push. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1 Assisted-by: Claude:claude-opus-5 Signed-off-by: Julius Bairaktaris <[email protected]> --- drivers/net/wireless/ath/ath11k/dp_tx.c | 12 +++++++++++- drivers/net/wireless/ath/ath11k/mac.c | 10 ++++++++++ drivers/net/wireless/ath/ath11k/mac.h | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 52c4a9924a31..2270b2079297 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -694,9 +694,10 @@ void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id) struct sk_buff *msdu; struct hal_tx_status ts = {}; struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + unsigned long push = 0; u32 *desc; u32 msdu_id; - u8 mac_id; + u8 mac_id, i; spin_lock_bh(&status_ring->lock); @@ -756,12 +757,21 @@ void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id) spin_unlock(&tx_ring->tx_idr_lock); ar = ab->pdevs[mac_id].ar; + __set_bit(mac_id, &push); if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); ath11k_dp_tx_complete_msdu(ar, msdu, &ts); } + + /* A completion returns the airtime the frame was charged, which is + * what an airtime-limited station is waiting on. Nothing else starts a + * scheduling round once the arrivals that would have started one are + * queued behind that limit. + */ + for_each_set_bit(i, &push, ab->num_radios) + ath11k_mac_tx_push_pending(ab->pdevs[i].ar); } int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index e5b2a5e56a28..996f421b6957 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6582,6 +6582,16 @@ static void ath11k_mac_op_wake_tx_queue(struct ieee80211_hw *hw, ath11k_mac_schedule_txq(hw->priv, txq->ac); } +void ath11k_mac_tx_push_pending(struct ath11k *ar) +{ + u8 ac; + + rcu_read_lock(); + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + ath11k_mac_schedule_txq(ar, ac); + rcu_read_unlock(); +} + void ath11k_mac_drain_tx(struct ath11k *ar) { /* make sure rcu-protected mac80211 tx path itself is drained */ diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 59f83c7175fd..4012155dddb6 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -161,6 +161,7 @@ struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id) struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id); void ath11k_mac_drain_tx(struct ath11k *ar); +void ath11k_mac_tx_push_pending(struct ath11k *ar); void ath11k_mac_peer_cleanup_all(struct ath11k *ar); int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); u8 ath11k_mac_bw_to_mac80211_bw(u8 bw); -- 2.53.0