From: Felix Fietkau <nbd@nbd.name>
To: linux-wireless@vger.kernel.org
Subject: [PATCH 6/9] mt76: mt7615: significantly reduce interrupt load
Date: Tue, 25 Aug 2020 07:29:06 +0200 [thread overview]
Message-ID: <20200825052909.36955-6-nbd@nbd.name> (raw)
In-Reply-To: <20200825052909.36955-1-nbd@nbd.name>
On 7615 and newer, DMA completion only triggers unmap, but not free of queued
skbs, since pointers to packets are queued internally.
Because of that, there is no need to process the main data queue immediately
on DMA completion.
To improve performance, mask out the DMA data queue completion interrupt and
process the queue only when we receive a txfree event.
This brings the number of interrupts under load down to a small fraction.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
.../net/wireless/mediatek/mt76/mt7615/dma.c | 24 +++----------------
.../net/wireless/mediatek/mt76/mt7615/mac.c | 8 +++++++
.../net/wireless/mediatek/mt76/mt7615/mmio.c | 8 +++----
.../wireless/mediatek/mt76/mt7615/mt7615.h | 5 ++++
4 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
index 3b375fdf31b8..abb83d4e7712 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
@@ -94,34 +94,16 @@ mt7615_init_tx_queues(struct mt7615_dev *dev)
return 0;
}
-static void
-mt7615_tx_cleanup(struct mt7615_dev *dev)
-{
- int i;
-
- mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false);
- mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false);
- if (is_mt7615(&dev->mt76)) {
- mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false);
- } else {
- for (i = 0; i < IEEE80211_NUM_ACS; i++)
- mt76_queue_tx_cleanup(dev, i, false);
- }
-}
-
static int mt7615_poll_tx(struct napi_struct *napi, int budget)
{
struct mt7615_dev *dev;
dev = container_of(napi, struct mt7615_dev, mt76.tx_napi);
- mt7615_tx_cleanup(dev);
-
- mt7615_pm_power_save_sched(dev);
- tasklet_schedule(&dev->mt76.tx_tasklet);
+ mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false);
if (napi_complete_done(napi, 0))
- mt7615_irq_enable(dev, MT_INT_TX_DONE_ALL);
+ mt7615_irq_enable(dev, mt7615_tx_mcu_int_mask(dev));
return 0;
}
@@ -305,7 +287,7 @@ int mt7615_dma_init(struct mt7615_dev *dev)
MT_WPDMA_GLO_CFG_RX_DMA_EN);
/* enable interrupts for TX/RX rings */
- mt7615_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
+ mt7615_irq_enable(dev, MT_INT_RX_DONE_ALL | mt7615_tx_mcu_int_mask(dev) |
MT_INT_MCU_CMD);
if (is_mt7622(&dev->mt76))
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index e4aeba17da67..9b8fbf26cd1e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -1424,6 +1424,14 @@ static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
struct mt7615_tx_free *free = (struct mt7615_tx_free *)skb->data;
u8 i, count;
+ mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false);
+ if (is_mt7615(&dev->mt76)) {
+ mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false);
+ } else {
+ for (i = 0; i < IEEE80211_NUM_ACS; i++)
+ mt76_queue_tx_cleanup(dev, i, false);
+ }
+
count = FIELD_GET(MT_TX_FREE_MSDU_ID_CNT, le16_to_cpu(free->ctrl));
if (is_mt7615(&dev->mt76)) {
__le16 *token = &free->token[0];
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
index 99ece641bdef..6de492a4cf02 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
@@ -101,7 +101,7 @@ static irqreturn_t mt7615_irq_handler(int irq, void *dev_instance)
static void mt7615_irq_tasklet(unsigned long data)
{
struct mt7615_dev *dev = (struct mt7615_dev *)data;
- u32 intr, mask = 0;
+ u32 intr, mask = 0, tx_mcu_mask = mt7615_tx_mcu_int_mask(dev);
mt76_wr(dev, MT_INT_MASK_CSR, 0);
@@ -112,11 +112,11 @@ static void mt7615_irq_tasklet(unsigned long data)
trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
mask |= intr & MT_INT_RX_DONE_ALL;
- if (intr & MT_INT_TX_DONE_ALL)
- mask |= MT_INT_TX_DONE_ALL;
+ if (intr & tx_mcu_mask)
+ mask |= tx_mcu_mask;
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
- if (intr & MT_INT_TX_DONE_ALL)
+ if (intr & tx_mcu_mask)
napi_schedule(&dev->mt76.tx_napi);
if (intr & MT_INT_RX_DONE(0))
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index 7567485256f8..bcd09cc52ce8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -540,6 +540,11 @@ static inline u8 mt7615_lmac_mapping(struct mt7615_dev *dev, u8 ac)
return lmac_queue_map[ac];
}
+static inline u32 mt7615_tx_mcu_int_mask(struct mt7615_dev *dev)
+{
+ return MT_INT_TX_DONE(dev->mt76.q_tx[MT_TXQ_MCU].q->hw_idx);
+}
+
void mt7615_dma_reset(struct mt7615_dev *dev);
void mt7615_scan_work(struct work_struct *work);
void mt7615_roc_work(struct work_struct *work);
--
2.28.0
next prev parent reply other threads:[~2020-08-25 5:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-25 5:29 [PATCH 1/9] mt76: mt7615: fix reading airtime statistics Felix Fietkau
2020-08-25 5:29 ` [PATCH 2/9] mt76: mt7915: optimize mt7915_mac_sta_poll Felix Fietkau
2020-08-25 5:29 ` [PATCH 3/9] mt76: dma: update q->queued immediately on cleanup Felix Fietkau
2020-08-25 5:29 ` [PATCH 4/9] mt76: mt7915: schedule tx tasklet in mt7915_mac_tx_free Felix Fietkau
2020-08-25 5:29 ` [PATCH 5/9] mt76: mt7915: significantly reduce interrupt load Felix Fietkau
2020-08-25 5:29 ` Felix Fietkau [this message]
2020-08-25 5:29 ` [PATCH 7/9] mt76: mt7915: add support for accessing mapped registers via bus ops Felix Fietkau
2020-08-25 5:29 ` [PATCH 8/9] mt76: add memory barrier to DMA queue kick Felix Fietkau
2020-08-25 5:29 ` [PATCH 9/9] mt76: mt7603: check for single-stream EEPROM configuration Felix Fietkau
2020-08-25 11:42 ` [PATCH v2 " Felix Fietkau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200825052909.36955-6-nbd@nbd.name \
--to=nbd@nbd.name \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox