From 0fc3c5eb61d0aee7f1b3d2f13e4115ee6cc5c992 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 29 Aug 2020 12:01:24 +0200 Subject: [PATCH] mt76: dma: queue more rx frames internally before passing them to the stack On MT7615 and MT7915, packets received from DMA can include TX_FREE events, which free up space for tx. In order to process those packets faster, keep keep a longer internal queue of packets and pass as many packets to the stack as the NAPI budget allows Signed-off-by: Felix Fietkau --- dma.c | 12 +++++++----- mac80211.c | 11 ++++++++--- mt76.h | 6 ++++-- sdio.c | 2 +- usb.c | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/dma.c b/dma.c index 09a684c8..08dc4596 100644 --- a/dma.c +++ b/dma.c @@ -599,7 +599,8 @@ static int mt76_dma_rx_poll(struct napi_struct *napi, int budget) { struct mt76_dev *dev; - int qid, done = 0, cur; + int qid, done = 0, cur, cur_dma; + int rxq_budget; dev = container_of(napi->dev, struct mt76_dev, napi_dev); qid = napi - dev->napi; @@ -607,17 +608,18 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget) rcu_read_lock(); do { - cur = mt76_dma_rx_process(dev, &dev->q_rx[qid], budget - done); - mt76_rx_poll_complete(dev, qid, napi); + rxq_budget = MT_RX_QUEUE_LEN - skb_queue_len(&dev->rx_skb[qid]); + cur_dma = mt76_dma_rx_process(dev, &dev->q_rx[qid], rxq_budget); + cur = mt76_rx_poll_complete(dev, qid, napi, budget - done); done += cur; - } while (cur && done < budget); + } while ((cur || cur_dma) && done < budget); rcu_read_unlock(); if (done < budget && napi_complete(napi)) dev->drv->rx_poll_complete(dev, qid); - return done; + return min(done, budget); } static int diff --git a/mac80211.c b/mac80211.c index 41fb76ee..87df1394 100644 --- a/mac80211.c +++ b/mac80211.c @@ -962,20 +962,25 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, } } -void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, - struct napi_struct *napi) +int mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, + struct napi_struct *napi, int budget) { struct sk_buff_head frames; struct sk_buff *skb; + int nframes; __skb_queue_head_init(&frames); - while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) { + while (budget > skb_queue_len(&frames) && + (skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) { mt76_check_sta(dev, skb); mt76_rx_aggr_reorder(skb, &frames); } + nframes = skb_queue_len(&frames); mt76_rx_complete(dev, &frames, napi); + + return nframes; } EXPORT_SYMBOL_GPL(mt76_rx_poll_complete); diff --git a/mt76.h b/mt76.h index a0abfeef..94a03c30 100644 --- a/mt76.h +++ b/mt76.h @@ -24,6 +24,8 @@ #define MT_MAX_NON_AQL_PKT 16 #define MT_TXQ_FREE_THR 32 +#define MT_RX_QUEUE_LEN 256 + struct mt76_dev; struct mt76_phy; struct mt76_wcid; @@ -1013,8 +1015,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, struct napi_struct *napi); -void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, - struct napi_struct *napi); +int mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, + struct napi_struct *napi, int budget); void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); void mt76_testmode_tx_pending(struct mt76_dev *dev); void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, diff --git a/sdio.c b/sdio.c index 7777d494..ae518f07 100644 --- a/sdio.c +++ b/sdio.c @@ -126,7 +126,7 @@ mt76s_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) nframes++; } if (qid == MT_RXQ_MAIN) - mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL); + mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL, MT_RX_QUEUE_LEN); return nframes; } diff --git a/usb.c b/usb.c index edbcabd2..bf22537d 100644 --- a/usb.c +++ b/usb.c @@ -666,7 +666,7 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) mt76u_submit_rx_buf(dev, qid, urb); } if (qid == MT_RXQ_MAIN) - mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL); + mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL, MT_RX_QUEUE_LEN); } static void mt76u_rx_tasklet(unsigned long data)