mt76: rely on AQL for burst size limits on tx queueing
authorFelix Fietkau <nbd@nbd.name>
Sun, 23 Aug 2020 19:22:20 +0000 (21:22 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 24 Sep 2020 16:10:17 +0000 (18:10 +0200)
Now that AQL works well on all mt76 drivers, completely replace the arbitrary
burst sizing and number of bursts logic for tx scheduling.
For the short period of time in which AQL does not work well yet, limit each
stations to 16 in-flight packets that have no estimated tx time.
This should avoid filling the queue if a station connects and queues up a
large number of packets before rate control information is available, especially
with hardware rate control

Signed-off-by: Felix Fietkau <nbd@nbd.name>
12 files changed:
drivers/net/wireless/mediatek/mt76/debugfs.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7603/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/sdio.c
drivers/net/wireless/mediatek/mt76/tx.c
drivers/net/wireless/mediatek/mt76/usb.c

index 5d58b16bfe9fc83133b54b1309de6275f44a3fbc..4a06d10e15ac1c334a0397fbdf414a89d2140bd7 100644 (file)
@@ -31,15 +31,14 @@ int mt76_queues_read(struct seq_file *s, void *data)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
-               struct mt76_sw_queue *q = &dev->q_tx[i];
+               struct mt76_queue *q = dev->q_tx[i].q;
 
-               if (!q->q)
+               if (!q)
                        continue;
 
                seq_printf(s,
-                          "%d: queued=%d head=%d tail=%d swq_queued=%d\n",
-                          i, q->q->queued, q->q->head, q->q->tail,
-                          q->swq_queued);
+                          "%d: queued=%d head=%d tail=%d\n",
+                          i, q->queued, q->head, q->tail);
        }
 
        return 0;
index 6cb69e87e8a75984185814bc687cb26ada975acd..37f33f4d12800bf3816f7ccba77378a1d0e448c1 100644 (file)
@@ -22,6 +22,9 @@
 #define MT_RX_BUF_SIZE      2048
 #define MT_SKB_HEAD_LEN     128
 
+#define MT_MAX_NON_AQL_PKT  16
+#define MT_TXQ_FREE_THR     32
+
 struct mt76_dev;
 struct mt76_phy;
 struct mt76_wcid;
@@ -100,10 +103,9 @@ struct mt76_queue_entry {
                struct urb *urb;
                int buf_sz;
        };
-       enum mt76_txq_id qid;
+       u16 wcid;
        bool skip_buf0:1;
        bool skip_buf1:1;
-       bool schedule:1;
        bool done:1;
 };
 
@@ -139,8 +141,6 @@ struct mt76_queue {
 
 struct mt76_sw_queue {
        struct mt76_queue *q;
-
-       int swq_queued;
 };
 
 struct mt76_mcu_ops {
@@ -205,6 +205,7 @@ DECLARE_EWMA(signal, 10, 8);
 struct mt76_wcid {
        struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS];
 
+       atomic_t non_aql_packets;
        unsigned long flags;
 
        struct ewma_signal rssi;
@@ -943,7 +944,7 @@ struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev,
                                       struct sk_buff_head *list);
 void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
                             struct sk_buff_head *list);
-void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
+void mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb);
 void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
                          bool flush);
 int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
index cb99b7c39f51bf35aef0fec013eacf805cca688c..15fb31fe9cf8434e0af47a4625251555921dca5b 100644 (file)
@@ -1282,7 +1282,7 @@ void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
        }
 
        dev->tx_hang_check = 0;
-       mt76_tx_complete_skb(mdev, skb);
+       mt76_tx_complete_skb(mdev, e->wcid, skb);
 }
 
 static bool
index 9b8fbf26cd1eb62af921ec4e212b3ccfcc0519da..9d0edbaa67bc01a7cb72926cc58b18a01a8f8e84 100644 (file)
@@ -1400,6 +1400,9 @@ mt7615_mac_tx_free_token(struct mt7615_dev *dev, u16 token)
 {
        struct mt76_dev *mdev = &dev->mt76;
        struct mt76_txwi_cache *txwi;
+       __le32 *txwi_data;
+       u32 val;
+       u8 wcid;
 
        trace_mac_tx_free(dev, token);
 
@@ -1410,9 +1413,13 @@ mt7615_mac_tx_free_token(struct mt7615_dev *dev, u16 token)
        if (!txwi)
                return;
 
+       txwi_data = (__le32 *)mt76_get_txwi_ptr(mdev, txwi);
+       val = le32_to_cpu(txwi_data[1]);
+       wcid = FIELD_GET(MT_TXD1_WLAN_IDX, val);
+
        mt7615_txp_skb_unmap(mdev, txwi);
        if (txwi->skb) {
-               mt76_tx_complete_skb(mdev, txwi->skb);
+               mt76_tx_complete_skb(mdev, wcid, txwi->skb);
                txwi->skb = NULL;
        }
 
index ba53606c458649cb2f7518a91f6b9dd2d19fb27e..4cf7c5d343258cdbebcd20b704204e57273cb066 100644 (file)
@@ -44,7 +44,7 @@ void mt7615_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
        }
 
        if (e->skb)
-               mt76_tx_complete_skb(mdev, e->skb);
+               mt76_tx_complete_skb(mdev, e->wcid, e->skb);
 }
 
 static void
index 30065b01577655b78e60f750b2a0361d90892dcc..56d82bd3a6158fd14a7bf255a8c7800a7550db0c 100644 (file)
@@ -234,7 +234,7 @@ void mt7663_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
                headroom += MT_USB_HDR_SIZE;
        skb_pull(e->skb, headroom);
 
-       mt76_tx_complete_skb(mdev, e->skb);
+       mt76_tx_complete_skb(mdev, e->wcid, e->skb);
 }
 EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_complete_skb);
 
index 4c7a0482b344025bbf515ff2189facb180596849..8529837a846a98f402937a1107cf144446eac322 100644 (file)
@@ -917,7 +917,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
        txwi = (struct mt76x02_txwi *)txwi_ptr;
        trace_mac_txdone(mdev, txwi->wcid, txwi->pktid);
 
-       mt76_tx_complete_skb(mdev, e->skb);
+       mt76_tx_complete_skb(mdev, e->wcid, e->skb);
 }
 EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
 
index cc28583226ff2b6e4ad887aef249bba2fbf41ffa..693daab5ddfc5125972c2a73c0da0b104bb9cb42 100644 (file)
@@ -18,7 +18,7 @@ static void mt76x02u_remove_dma_hdr(struct sk_buff *skb)
 void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
 {
        mt76x02u_remove_dma_hdr(e->skb);
-       mt76_tx_complete_skb(mdev, e->skb);
+       mt76_tx_complete_skb(mdev, e->wcid, e->skb);
 }
 EXPORT_SYMBOL_GPL(mt76x02u_tx_complete_skb);
 
index cbcdd30a24d7604fc88d4a8890f84168375b9e0d..4d6e4143e346f222e440caea5bc7285c8265db8f 100644 (file)
@@ -927,10 +927,21 @@ void mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
 
                mt7915_txp_skb_unmap(mdev, txwi);
                if (txwi->skb) {
+                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txwi->skb);
                        void *txwi_ptr = mt76_get_txwi_ptr(mdev, txwi);
 
                        if (likely(txwi->skb->protocol != cpu_to_be16(ETH_P_PAE)))
                                mt7915_tx_check_aggr(sta, txwi_ptr);
+
+                       if (sta && !info->tx_time_est) {
+                               struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+                               int pending;
+
+                               pending = atomic_dec_return(&wcid->non_aql_packets);
+                               if (pending < 0)
+                                       atomic_cmpxchg(&wcid->non_aql_packets, pending, 0);
+                       }
+
                        mt7915_tx_complete_status(mdev, txwi->skb, sta, stat);
                        txwi->skb = NULL;
                }
index e41037ac0867e2486784d2a486ada0cbec358520..8ed18c9517addc45f5311209a6040df9f33225e4 100644 (file)
@@ -144,7 +144,6 @@ static void mt76s_process_tx_queue(struct mt76_dev *dev, enum mt76_txq_id qid)
 
                entry = q->entry[q->tail];
                q->entry[q->tail].done = false;
-               q->entry[q->tail].schedule = false;
 
                if (qid == MT_TXQ_MCU) {
                        dev_kfree_skb(entry.skb);
index 3dac8f7dbff68d952bb59675dc34d06fa30ce428..702fbfd2e1b50c205b91452431c28e20fe38942b 100644 (file)
@@ -241,7 +241,32 @@ mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid, bool flush)
 }
 EXPORT_SYMBOL_GPL(mt76_tx_status_check);
 
-void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb)
+static void
+mt76_tx_check_non_aql(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct mt76_wcid *wcid;
+       int pending;
+
+       if (info->tx_time_est)
+               return;
+
+       if (wcid_idx >= ARRAY_SIZE(dev->wcid))
+               return;
+
+       rcu_read_lock();
+
+       wcid = rcu_dereference(dev->wcid[wcid_idx]);
+       if (wcid) {
+               pending = atomic_dec_return(&wcid->non_aql_packets);
+               if (pending < 0)
+                       atomic_cmpxchg(&wcid->non_aql_packets, pending, 0);
+       }
+
+       rcu_read_unlock();
+}
+
+void mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *skb)
 {
        struct ieee80211_hw *hw;
        struct sk_buff_head list;
@@ -254,6 +279,8 @@ void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb)
        }
 #endif
 
+       mt76_tx_check_non_aql(dev, wcid_idx, skb);
+
        if (!skb->prev) {
                hw = mt76_tx_status_get_hw(dev, skb);
                ieee80211_free_txskb(hw, skb);
@@ -266,6 +293,32 @@ void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(mt76_tx_complete_skb);
 
+static int
+__mt76_tx_queue_skb(struct mt76_dev *dev, int qid, struct sk_buff *skb,
+                   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+                   bool *stop)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct mt76_queue *q;
+       bool non_aql;
+       int pending;
+       int idx;
+
+       non_aql = !info->tx_time_est;
+       idx = dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid, sta);
+       if (idx < 0 || !sta || !non_aql)
+               return idx;
+
+       wcid = (struct mt76_wcid *)sta->drv_priv;
+       q = dev->q_tx[qid].q;
+       q->entry[idx].wcid = wcid->idx;
+       pending = atomic_inc_return(&wcid->non_aql_packets);
+       if (stop && pending >= MT_MAX_NON_AQL_PKT)
+               *stop = true;
+
+       return idx;
+}
+
 void
 mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
        struct mt76_wcid *wcid, struct sk_buff *skb)
@@ -304,7 +357,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
        q = dev->q_tx[qid].q;
 
        spin_lock_bh(&q->lock);
-       dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid, sta);
+       __mt76_tx_queue_skb(dev, qid, skb, wcid, sta, NULL);
        dev->queue_ops->kick(dev, q);
 
        if (q->queued > q->ndesc - 8 && !q->stopped) {
@@ -358,7 +411,7 @@ mt76_queue_ps_skb(struct mt76_dev *dev, struct ieee80211_sta *sta,
                               IEEE80211_TX_CTL_REQ_TX_STATUS;
 
        mt76_skb_set_moredata(skb, !last);
-       dev->queue_ops->tx_queue_skb(dev, MT_TXQ_PSD, skb, wcid, sta);
+       __mt76_tx_queue_skb(dev, MT_TXQ_PSD, skb, wcid, sta, NULL);
 }
 
 void
@@ -417,15 +470,16 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_sw_queue *sq,
        struct mt76_queue *hwq = sq->q;
        struct ieee80211_tx_info *info;
        struct sk_buff *skb;
-       int n_frames = 1, limit;
-       struct ieee80211_tx_rate tx_rate;
-       bool ampdu;
-       bool probe;
+       int n_frames = 1;
+       bool stop = false;
        int idx;
 
        if (test_bit(MT_WCID_FLAG_PS, &wcid->flags))
                return 0;
 
+       if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
+               return 0;
+
        skb = mt76_txq_dequeue(phy, mtxq, false);
        if (!skb)
                return 0;
@@ -434,55 +488,37 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_sw_queue *sq,
        if (!(wcid->tx_info & MT_WCID_TX_INFO_SET))
                ieee80211_get_tx_rates(txq->vif, txq->sta, skb,
                                       info->control.rates, 1);
-       tx_rate = info->control.rates[0];
-
-       probe = (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
-       ampdu = IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU;
-       limit = ampdu ? 16 : 3;
-
-       idx = dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid, txq->sta);
 
+       idx = __mt76_tx_queue_skb(dev, qid, skb, wcid, txq->sta, &stop);
        if (idx < 0)
                return idx;
 
        do {
-               bool cur_ampdu;
-
-               if (probe)
-                       break;
-
                if (test_bit(MT76_STATE_PM, &phy->state) ||
                    test_bit(MT76_RESET, &phy->state))
                        return -EBUSY;
 
-               skb = mt76_txq_dequeue(phy, mtxq, false);
-               if (!skb)
+               if (stop)
                        break;
 
-               info = IEEE80211_SKB_CB(skb);
-               cur_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
+               if (q->queued + MT_TXQ_FREE_THR >= q->ndesc)
+                       break;
 
-               if (ampdu != cur_ampdu ||
-                   (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
-                       skb_queue_tail(&mtxq->retry_q, skb);
+               skb = mt76_txq_dequeue(phy, mtxq, false);
+               if (!skb)
                        break;
-               }
 
-               info->control.rates[0] = tx_rate;
+               info = IEEE80211_SKB_CB(skb);
+               if (!(wcid->tx_info & MT_WCID_TX_INFO_SET))
+                       ieee80211_get_tx_rates(txq->vif, txq->sta, skb,
+                                              info->control.rates, 1);
 
-               idx = dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid,
-                                                  txq->sta);
+               idx = __mt76_tx_queue_skb(dev, qid, skb, wcid, txq->sta, &stop);
                if (idx < 0)
-                       return idx;
+                       break;
 
                n_frames++;
-       } while (n_frames < limit);
-
-       if (!probe) {
-               hwq->entry[idx].qid = sq - dev->q_tx;
-               hwq->entry[idx].schedule = true;
-               sq->swq_queued++;
-       }
+       } while (1);
 
        dev->queue_ops->kick(dev, hwq);
 
@@ -502,15 +538,15 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
 
        spin_lock_bh(&hwq->lock);
        while (1) {
-               if (sq->swq_queued >= 4)
-                       break;
-
                if (test_bit(MT76_STATE_PM, &phy->state) ||
                    test_bit(MT76_RESET, &phy->state)) {
                        ret = -EBUSY;
                        break;
                }
 
+               if (q->queued + MT_TXQ_FREE_THR >= q->ndesc)
+                       break;
+
                txq = ieee80211_next_txq(phy->hw, qid);
                if (!txq)
                        break;
@@ -544,16 +580,11 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
 
 void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid)
 {
-       struct mt76_dev *dev = phy->dev;
-       struct mt76_sw_queue *sq = &dev->q_tx[qid];
        int len;
 
        if (qid >= 4)
                return;
 
-       if (sq->swq_queued >= 4)
-               return;
-
        rcu_read_lock();
 
        do {
@@ -700,21 +731,12 @@ EXPORT_SYMBOL_GPL(mt76_skb_adjust_pad);
 void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q,
                            struct mt76_queue_entry *e)
 {
-       enum mt76_txq_id qid = e->qid % 4;
-       bool ext_phy = e->qid >= 4;
-
        if (e->skb)
                dev->drv->tx_complete_skb(dev, e);
 
        spin_lock_bh(&q->lock);
        q->tail = (q->tail + 1) % q->ndesc;
        q->queued--;
-
-       if (ext_phy)
-               qid += __MT_TXQ_MAX;
-
-       if (e->schedule)
-               dev->q_tx[qid].swq_queued--;
        spin_unlock_bh(&q->lock);
 }
 EXPORT_SYMBOL_GPL(mt76_queue_tx_complete);
index 14b93a0ef534c8a3b306c78061702ac2e95f5a9d..79e06c54a9732e9f373aef379024660a24c330ae 100644 (file)
@@ -811,7 +811,6 @@ static void mt76u_tx_tasklet(unsigned long data)
 
                        entry = q->entry[q->tail];
                        q->entry[q->tail].done = false;
-                       q->entry[q->tail].schedule = false;
 
                        mt76_queue_tx_complete(dev, q, &entry);
                }
@@ -1053,7 +1052,6 @@ void mt76u_stop_tx(struct mt76_dev *dev)
 
                        entry = q->entry[q->tail];
                        q->entry[q->tail].done = false;
-                       q->entry[q->tail].schedule = false;
 
                        mt76_queue_tx_complete(dev, q, &entry);
                }