All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] mt7663s: move tx/rx processing in a dedicated wq
@ 2020-07-30 14:09 Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 1/4] mt76: mt76s: move tx " Lorenzo Bianconi
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Lorenzo Bianconi @ 2020-07-30 14:09 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, sean.wang, linux-wireless

Introduce mt76s_txrx_wq workqueue and move tx/rx processing from
kthreads to dedicated works.
Split tx/rx status processing in two separated works.
This series improves device throughput increasing tx/rx parallelization

Lorenzo Bianconi (4):
  mt76: mt76s: move tx processing in a dedicated wq
  mt76: mt7663s: move rx processing in txrx wq
  mt76: mt76s: move status processing in txrx wq
  mt76: mt76s: move tx/rx processing in 2 separate works

 drivers/net/wireless/mediatek/mt76/mt76.h     |  12 +-
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |   3 +-
 .../net/wireless/mediatek/mt76/mt7615/sdio.c  |  10 +-
 .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 134 ++++++++++--------
 drivers/net/wireless/mediatek/mt76/sdio.c     |  75 +++++-----
 5 files changed, 127 insertions(+), 107 deletions(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] mt76: mt76s: move tx processing in a dedicated wq
  2020-07-30 14:09 [PATCH 0/4] mt7663s: move tx/rx processing in a dedicated wq Lorenzo Bianconi
@ 2020-07-30 14:09 ` Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 2/4] mt76: mt7663s: move rx processing in txrx wq Lorenzo Bianconi
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Lorenzo Bianconi @ 2020-07-30 14:09 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, sean.wang, linux-wireless

Introduce mt76s_txrx_wq workqueue and move tx processing from kthread to
a dedicated work. This is preliminary patch to improve mt7663s throughput

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt76.h     |  4 +-
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  2 +-
 .../net/wireless/mediatek/mt76/mt7615/sdio.c  |  9 +--
 .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 56 +++++++------------
 drivers/net/wireless/mediatek/mt76/sdio.c     | 16 +++++-
 5 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 4482eeb91a64..4570770e9b1d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -447,10 +447,12 @@ struct mt76_usb {
 };
 
 struct mt76_sdio {
-	struct task_struct *tx_kthread;
 	struct task_struct *kthread;
 	struct work_struct stat_work;
 
+	struct workqueue_struct *txrx_wq;
+	struct work_struct tx_work;
+
 	unsigned long state;
 
 	struct sdio_func *func;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index e93f87af3d2a..18b0b7b614ef 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -678,7 +678,7 @@ u32 mt7663s_read_pcr(struct mt7615_dev *dev);
 int mt7663s_mcu_init(struct mt7615_dev *dev);
 int mt7663s_driver_own(struct mt7615_dev *dev);
 int mt7663s_firmware_own(struct mt7615_dev *dev);
-int mt7663s_kthread_run(void *data);
+void mt7663s_tx_work(struct work_struct *work);
 void mt7663s_sdio_irq(struct sdio_func *func);
 
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index dabce51117b0..3ab033e0f440 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -364,18 +364,15 @@ static int mt7663s_probe(struct sdio_func *func,
 	dev->ops = ops;
 	sdio_set_drvdata(func, dev);
 
-	mdev->sdio.tx_kthread = kthread_create(mt7663s_kthread_run, dev,
-					       "mt7663s_tx");
-	if (IS_ERR(mdev->sdio.tx_kthread))
-		return PTR_ERR(mdev->sdio.tx_kthread);
-
 	ret = mt76s_init(mdev, func, &mt7663s_ops);
 	if (ret < 0)
 		goto err_free;
 
+	INIT_WORK(&mdev->sdio.tx_work, mt7663s_tx_work);
+
 	ret = mt7663s_hw_init(dev, func);
 	if (ret)
-		goto err_free;
+		goto err_deinit;
 
 	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
 		    (mt76_rr(dev, MT_HW_REV) & 0xff);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
index 443a4ecdad3a..9340d1570a78 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
@@ -116,12 +116,12 @@ static int mt7663s_rx_run_queue(struct mt7615_dev *dev, enum mt76_rxq_id qid,
 	return err;
 }
 
-static int mt7663s_tx_update_sched(struct mt7615_dev *dev,
+static int mt7663s_tx_update_sched(struct mt76_dev *dev,
 				   struct mt76_queue_entry *e,
 				   bool mcu)
 {
-	struct mt76_sdio *sdio = &dev->mt76.sdio;
-	struct mt76_phy *mphy = &dev->mt76.phy;
+	struct mt76_sdio *sdio = &dev->sdio;
+	struct mt76_phy *mphy = &dev->phy;
 	struct ieee80211_hdr *hdr;
 	int size, ret = -EBUSY;
 
@@ -157,10 +157,10 @@ static int mt7663s_tx_update_sched(struct mt7615_dev *dev,
 	return ret;
 }
 
-static int mt7663s_tx_run_queue(struct mt7615_dev *dev, struct mt76_queue *q)
+static int mt7663s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q)
 {
-	bool mcu = q == dev->mt76.q_tx[MT_TXQ_MCU].q;
-	struct mt76_sdio *sdio = &dev->mt76.sdio;
+	bool mcu = q == dev->q_tx[MT_TXQ_MCU].q;
+	struct mt76_sdio *sdio = &dev->sdio;
 	int nframes = 0;
 
 	while (q->first != q->tail) {
@@ -174,9 +174,12 @@ static int mt7663s_tx_run_queue(struct mt7615_dev *dev, struct mt76_queue *q)
 			len = roundup(len, sdio->func->cur_blksize);
 
 		/* TODO: skb_walk_frags and then write to SDIO port */
+		sdio_claim_host(sdio->func);
 		err = sdio_writesb(sdio->func, MCR_WTDR1, e->skb->data, len);
+		sdio_release_host(sdio->func);
+
 		if (err) {
-			dev_err(dev->mt76.dev, "sdio write failed: %d\n", err);
+			dev_err(dev->dev, "sdio write failed: %d\n", err);
 			return -EIO;
 		}
 
@@ -188,46 +191,25 @@ static int mt7663s_tx_run_queue(struct mt7615_dev *dev, struct mt76_queue *q)
 	return nframes;
 }
 
-static int mt7663s_tx_run_queues(struct mt7615_dev *dev)
+void mt7663s_tx_work(struct work_struct *work)
 {
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, tx_work);
+	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
 	int i, nframes = 0;
 
 	for (i = 0; i < MT_TXQ_MCU_WA; i++) {
 		int ret;
 
-		ret = mt7663s_tx_run_queue(dev, dev->mt76.q_tx[i].q);
+		ret = mt7663s_tx_run_queue(dev, dev->q_tx[i].q);
 		if (ret < 0)
-			return ret;
+			break;
 
 		nframes += ret;
 	}
+	if (nframes)
+		queue_work(sdio->txrx_wq, &sdio->tx_work);
 
-	return nframes;
-}
-
-int mt7663s_kthread_run(void *data)
-{
-	struct mt7615_dev *dev = data;
-	struct mt76_phy *mphy = &dev->mt76.phy;
-
-	while (!kthread_should_stop()) {
-		int ret;
-
-		cond_resched();
-
-		sdio_claim_host(dev->mt76.sdio.func);
-		ret = mt7663s_tx_run_queues(dev);
-		sdio_release_host(dev->mt76.sdio.func);
-
-		if (ret <= 0 || !test_bit(MT76_STATE_RUNNING, &mphy->state)) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule();
-		} else {
-			wake_up_process(dev->mt76.sdio.kthread);
-		}
-	}
-
-	return 0;
+	wake_up_process(sdio->kthread);
 }
 
 void mt7663s_sdio_irq(struct sdio_func *func)
@@ -258,7 +240,7 @@ void mt7663s_sdio_irq(struct sdio_func *func)
 
 		if (intr.isr & WHIER_TX_DONE_INT_EN) {
 			mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
-			mt7663s_tx_run_queues(dev);
+			queue_work(sdio->txrx_wq, &sdio->tx_work);
 			wake_up_process(sdio->kthread);
 		}
 	} while (intr.isr);
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index 5d8353026aaf..4a233e0e9d25 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -68,6 +68,7 @@ void mt76s_stop_txrx(struct mt76_dev *dev)
 {
 	struct mt76_sdio *sdio = &dev->sdio;
 
+	cancel_work_sync(&sdio->tx_work);
 	cancel_work_sync(&sdio->stat_work);
 	clear_bit(MT76_READING_STATS, &dev->phy.state);
 
@@ -179,7 +180,6 @@ static int mt76s_process_tx_queue(struct mt76_dev *dev, enum mt76_txq_id qid)
 	if (wake)
 		ieee80211_wake_queue(dev->hw, qid);
 
-	wake_up_process(dev->sdio.tx_kthread);
 out:
 	return n_dequeued;
 }
@@ -272,7 +272,7 @@ static void mt76s_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 {
 	struct mt76_sdio *sdio = &dev->sdio;
 
-	wake_up_process(sdio->tx_kthread);
+	queue_work(sdio->txrx_wq, &sdio->tx_work);
 }
 
 static const struct mt76_queue_ops sdio_queue_ops = {
@@ -324,9 +324,13 @@ void mt76s_deinit(struct mt76_dev *dev)
 	int i;
 
 	kthread_stop(sdio->kthread);
-	kthread_stop(sdio->tx_kthread);
 	mt76s_stop_txrx(dev);
 
+	if (sdio->txrx_wq) {
+		destroy_workqueue(sdio->txrx_wq);
+		sdio->txrx_wq = NULL;
+	}
+
 	sdio_claim_host(sdio->func);
 	sdio_release_irq(sdio->func);
 	sdio_release_host(sdio->func);
@@ -353,6 +357,12 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
 {
 	struct mt76_sdio *sdio = &dev->sdio;
 
+	sdio->txrx_wq = alloc_workqueue("mt76s_txrx_wq",
+					WQ_UNBOUND | WQ_HIGHPRI,
+					WQ_UNBOUND_MAX_ACTIVE);
+	if (!sdio->txrx_wq)
+		return -ENOMEM;
+
 	sdio->kthread = kthread_create(mt76s_kthread_run, dev, "mt76s");
 	if (IS_ERR(sdio->kthread))
 		return PTR_ERR(sdio->kthread);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] mt76: mt7663s: move rx processing in txrx wq
  2020-07-30 14:09 [PATCH 0/4] mt7663s: move tx/rx processing in a dedicated wq Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 1/4] mt76: mt76s: move tx " Lorenzo Bianconi
@ 2020-07-30 14:09 ` Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 3/4] mt76: mt76s: move status " Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 4/4] mt76: mt76s: move tx/rx processing in 2 separate works Lorenzo Bianconi
  3 siblings, 0 replies; 5+ messages in thread
From: Lorenzo Bianconi @ 2020-07-30 14:09 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, sean.wang, linux-wireless

Move rx processing to mt76s_txrx_wq in order to minimize the interval when
the sdio bus is locked during rx

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt76.h     |  1 +
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  1 +
 .../net/wireless/mediatek/mt76/mt7615/sdio.c  |  1 +
 .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 82 ++++++++++++-------
 drivers/net/wireless/mediatek/mt76/sdio.c     |  1 +
 5 files changed, 57 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 4570770e9b1d..6079f44287ea 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -452,6 +452,7 @@ struct mt76_sdio {
 
 	struct workqueue_struct *txrx_wq;
 	struct work_struct tx_work;
+	struct work_struct rx_work;
 
 	unsigned long state;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index 18b0b7b614ef..4892a3d6d6c3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -679,6 +679,7 @@ int mt7663s_mcu_init(struct mt7615_dev *dev);
 int mt7663s_driver_own(struct mt7615_dev *dev);
 int mt7663s_firmware_own(struct mt7615_dev *dev);
 void mt7663s_tx_work(struct work_struct *work);
+void mt7663s_rx_work(struct work_struct *work);
 void mt7663s_sdio_irq(struct sdio_func *func);
 
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index 3ab033e0f440..0cc3f0aca70b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -369,6 +369,7 @@ static int mt7663s_probe(struct sdio_func *func,
 		goto err_free;
 
 	INIT_WORK(&mdev->sdio.tx_work, mt7663s_tx_work);
+	INIT_WORK(&mdev->sdio.rx_work, mt7663s_rx_work);
 
 	ret = mt7663s_hw_init(dev, func);
 	if (ret)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
index 9340d1570a78..c214960504bf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
@@ -19,9 +19,9 @@
 #include "sdio.h"
 #include "mac.h"
 
-static void mt7663s_refill_sched_quota(struct mt7615_dev *dev, u32 *data)
+static void mt7663s_refill_sched_quota(struct mt76_dev *dev, u32 *data)
 {
-	struct mt76_sdio *sdio = &dev->mt76.sdio;
+	struct mt76_sdio *sdio = &dev->sdio;
 
 	mutex_lock(&sdio->sched.lock);
 	sdio->sched.pse_data_quota += FIELD_GET(TXQ_CNT_L, data[0]) + /* BK */
@@ -61,11 +61,11 @@ static struct sk_buff *mt7663s_build_rx_skb(void *data, int data_len,
 	return skb;
 }
 
-static int mt7663s_rx_run_queue(struct mt7615_dev *dev, enum mt76_rxq_id qid,
+static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
 				struct mt76s_intr *intr)
 {
-	struct mt76_queue *q = &dev->mt76.q_rx[qid];
-	struct mt76_sdio *sdio = &dev->mt76.sdio;
+	struct mt76_queue *q = &dev->q_rx[qid];
+	struct mt76_sdio *sdio = &dev->sdio;
 	int len = 0, err, i, order;
 	struct page *page;
 	u8 *buf;
@@ -86,9 +86,12 @@ static int mt7663s_rx_run_queue(struct mt7615_dev *dev, enum mt76_rxq_id qid,
 
 	buf = page_address(page);
 
+	sdio_claim_host(sdio->func);
 	err = sdio_readsb(sdio->func, buf, MCR_WRDR(qid), len);
+	sdio_release_host(sdio->func);
+
 	if (err < 0) {
-		dev_err(dev->mt76.dev, "sdio read data failed:%d\n", err);
+		dev_err(dev->dev, "sdio read data failed:%d\n", err);
 		__free_pages(page, order);
 		return err;
 	}
@@ -113,7 +116,7 @@ static int mt7663s_rx_run_queue(struct mt7615_dev *dev, enum mt76_rxq_id qid,
 	q->queued += i;
 	spin_unlock_bh(&q->lock);
 
-	return err;
+	return i;
 }
 
 static int mt7663s_tx_update_sched(struct mt76_dev *dev,
@@ -212,39 +215,60 @@ void mt7663s_tx_work(struct work_struct *work)
 	wake_up_process(sdio->kthread);
 }
 
-void mt7663s_sdio_irq(struct sdio_func *func)
+void mt7663s_rx_work(struct work_struct *work)
 {
-	struct mt7615_dev *dev = sdio_get_drvdata(func);
-	struct mt76_sdio *sdio = &dev->mt76.sdio;
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, rx_work);
+	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
 	struct mt76s_intr intr;
+	int nframes = 0, ret;
 
 	/* disable interrupt */
-	sdio_writel(func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, 0);
+	sdio_claim_host(sdio->func);
+	sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, 0);
+	sdio_readsb(sdio->func, &intr, MCR_WHISR, sizeof(struct mt76s_intr));
+	sdio_release_host(sdio->func);
 
-	do {
-		sdio_readsb(func, &intr, MCR_WHISR, sizeof(struct mt76s_intr));
-		trace_dev_irq(&dev->mt76, intr.isr, 0);
+	trace_dev_irq(dev, intr.isr, 0);
 
-		if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.phy.state))
-			goto out;
-
-		if (intr.isr & WHIER_RX0_DONE_INT_EN) {
-			mt7663s_rx_run_queue(dev, 0, &intr);
+	if (intr.isr & WHIER_RX0_DONE_INT_EN) {
+		ret = mt7663s_rx_run_queue(dev, 0, &intr);
+		if (ret > 0) {
 			wake_up_process(sdio->kthread);
+			nframes += ret;
 		}
+	}
 
-		if (intr.isr & WHIER_RX1_DONE_INT_EN) {
-			mt7663s_rx_run_queue(dev, 1, &intr);
+	if (intr.isr & WHIER_RX1_DONE_INT_EN) {
+		ret = mt7663s_rx_run_queue(dev, 1, &intr);
+		if (ret > 0) {
 			wake_up_process(sdio->kthread);
+			nframes += ret;
 		}
+	}
+
+	if (intr.isr & WHIER_TX_DONE_INT_EN) {
+		mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
+		queue_work(sdio->txrx_wq, &sdio->tx_work);
+	}
+
+	if (nframes) {
+		queue_work(sdio->txrx_wq, &sdio->rx_work);
+		return;
+	}
 
-		if (intr.isr & WHIER_TX_DONE_INT_EN) {
-			mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
-			queue_work(sdio->txrx_wq, &sdio->tx_work);
-			wake_up_process(sdio->kthread);
-		}
-	} while (intr.isr);
-out:
 	/* enable interrupt */
-	sdio_writel(func, WHLPCR_INT_EN_SET, MCR_WHLPCR, 0);
+	sdio_claim_host(sdio->func);
+	sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, 0);
+	sdio_release_host(sdio->func);
+}
+
+void mt7663s_sdio_irq(struct sdio_func *func)
+{
+	struct mt7615_dev *dev = sdio_get_drvdata(func);
+	struct mt76_sdio *sdio = &dev->mt76.sdio;
+
+	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.phy.state))
+		return;
+
+	queue_work(sdio->txrx_wq, &sdio->rx_work);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index 4a233e0e9d25..e9fa0ca8f9cd 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -69,6 +69,7 @@ void mt76s_stop_txrx(struct mt76_dev *dev)
 	struct mt76_sdio *sdio = &dev->sdio;
 
 	cancel_work_sync(&sdio->tx_work);
+	cancel_work_sync(&sdio->rx_work);
 	cancel_work_sync(&sdio->stat_work);
 	clear_bit(MT76_READING_STATS, &dev->phy.state);
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] mt76: mt76s: move status processing in txrx wq
  2020-07-30 14:09 [PATCH 0/4] mt7663s: move tx/rx processing in a dedicated wq Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 1/4] mt76: mt76s: move tx " Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 2/4] mt76: mt7663s: move rx processing in txrx wq Lorenzo Bianconi
@ 2020-07-30 14:09 ` Lorenzo Bianconi
  2020-07-30 14:09 ` [PATCH 4/4] mt76: mt76s: move tx/rx processing in 2 separate works Lorenzo Bianconi
  3 siblings, 0 replies; 5+ messages in thread
From: Lorenzo Bianconi @ 2020-07-30 14:09 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, sean.wang, linux-wireless

As it has been done for tx and rx processing, move tx/rx status
processing into mt76s_txrx_wq workqueue

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt76.h     |  6 +--
 .../wireless/mediatek/mt76/mt7615/sdio_txrx.c |  6 +--
 drivers/net/wireless/mediatek/mt76/sdio.c     | 54 +++++++------------
 3 files changed, 25 insertions(+), 41 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 6079f44287ea..17f424d78c2c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -447,12 +447,12 @@ struct mt76_usb {
 };
 
 struct mt76_sdio {
-	struct task_struct *kthread;
-	struct work_struct stat_work;
-
 	struct workqueue_struct *txrx_wq;
 	struct work_struct tx_work;
 	struct work_struct rx_work;
+	struct work_struct work;
+
+	struct work_struct stat_work;
 
 	unsigned long state;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
index c214960504bf..8872b145df64 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
@@ -212,7 +212,7 @@ void mt7663s_tx_work(struct work_struct *work)
 	if (nframes)
 		queue_work(sdio->txrx_wq, &sdio->tx_work);
 
-	wake_up_process(sdio->kthread);
+	queue_work(sdio->txrx_wq, &sdio->work);
 }
 
 void mt7663s_rx_work(struct work_struct *work)
@@ -233,7 +233,7 @@ void mt7663s_rx_work(struct work_struct *work)
 	if (intr.isr & WHIER_RX0_DONE_INT_EN) {
 		ret = mt7663s_rx_run_queue(dev, 0, &intr);
 		if (ret > 0) {
-			wake_up_process(sdio->kthread);
+			queue_work(sdio->txrx_wq, &sdio->work);
 			nframes += ret;
 		}
 	}
@@ -241,7 +241,7 @@ void mt7663s_rx_work(struct work_struct *work)
 	if (intr.isr & WHIER_RX1_DONE_INT_EN) {
 		ret = mt7663s_rx_run_queue(dev, 1, &intr);
 		if (ret > 0) {
-			wake_up_process(sdio->kthread);
+			queue_work(sdio->txrx_wq, &sdio->work);
 			nframes += ret;
 		}
 	}
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index e9fa0ca8f9cd..5432b388ceab 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -70,6 +70,7 @@ void mt76s_stop_txrx(struct mt76_dev *dev)
 
 	cancel_work_sync(&sdio->tx_work);
 	cancel_work_sync(&sdio->rx_work);
+	cancel_work_sync(&sdio->work);
 	cancel_work_sync(&sdio->stat_work);
 	clear_bit(MT76_READING_STATS, &dev->phy.state);
 
@@ -282,41 +283,29 @@ static const struct mt76_queue_ops sdio_queue_ops = {
 	.tx_queue_skb_raw = mt76s_tx_queue_skb_raw,
 };
 
-static int mt76s_kthread_run(void *data)
+static void mt76s_txrx_work(struct work_struct *work)
 {
-	struct mt76_dev *dev = data;
-	struct mt76_phy *mphy = &dev->phy;
-
-	while (!kthread_should_stop()) {
-		int i, nframes = 0;
-
-		cond_resched();
-
-		/* rx processing */
-		local_bh_disable();
-		rcu_read_lock();
-
-		mt76_for_each_q_rx(dev, i)
-			nframes += mt76s_process_rx_queue(dev, &dev->q_rx[i]);
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, work);
+	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
+	int i;
 
-		rcu_read_unlock();
-		local_bh_enable();
+	/* rx processing */
+	local_bh_disable();
+	rcu_read_lock();
 
-		/* tx processing */
-		for (i = 0; i < MT_TXQ_MCU_WA; i++)
-			nframes += mt76s_process_tx_queue(dev, i);
+	mt76_for_each_q_rx(dev, i)
+		mt76s_process_rx_queue(dev, &dev->q_rx[i]);
 
-		if (dev->drv->tx_status_data &&
-		    !test_and_set_bit(MT76_READING_STATS, &mphy->state))
-			queue_work(dev->wq, &dev->sdio.stat_work);
+	rcu_read_unlock();
+	local_bh_enable();
 
-		if (!nframes || !test_bit(MT76_STATE_RUNNING, &mphy->state)) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule();
-		}
-	}
+	/* tx processing */
+	for (i = 0; i < MT_TXQ_MCU_WA; i++)
+		mt76s_process_tx_queue(dev, i);
 
-	return 0;
+	if (dev->drv->tx_status_data &&
+	    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
+		queue_work(dev->wq, &dev->sdio.stat_work);
 }
 
 void mt76s_deinit(struct mt76_dev *dev)
@@ -324,9 +313,7 @@ void mt76s_deinit(struct mt76_dev *dev)
 	struct mt76_sdio *sdio = &dev->sdio;
 	int i;
 
-	kthread_stop(sdio->kthread);
 	mt76s_stop_txrx(dev);
-
 	if (sdio->txrx_wq) {
 		destroy_workqueue(sdio->txrx_wq);
 		sdio->txrx_wq = NULL;
@@ -364,11 +351,8 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
 	if (!sdio->txrx_wq)
 		return -ENOMEM;
 
-	sdio->kthread = kthread_create(mt76s_kthread_run, dev, "mt76s");
-	if (IS_ERR(sdio->kthread))
-		return PTR_ERR(sdio->kthread);
-
 	INIT_WORK(&sdio->stat_work, mt76s_tx_status_data);
+	INIT_WORK(&sdio->work, mt76s_txrx_work);
 
 	mutex_init(&sdio->sched.lock);
 	dev->queue_ops = &sdio_queue_ops;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] mt76: mt76s: move tx/rx processing in 2 separate works
  2020-07-30 14:09 [PATCH 0/4] mt7663s: move tx/rx processing in a dedicated wq Lorenzo Bianconi
                   ` (2 preceding siblings ...)
  2020-07-30 14:09 ` [PATCH 3/4] mt76: mt76s: move status " Lorenzo Bianconi
@ 2020-07-30 14:09 ` Lorenzo Bianconi
  3 siblings, 0 replies; 5+ messages in thread
From: Lorenzo Bianconi @ 2020-07-30 14:09 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, sean.wang, linux-wireless

In order to maximize parallelism, split status work in tx status work
and rx net work

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt76.h     | 11 +++--
 .../net/wireless/mediatek/mt76/mt7615/sdio.c  |  4 +-
 .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 20 +++++-----
 drivers/net/wireless/mediatek/mt76/sdio.c     | 40 ++++++++++++-------
 4 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 17f424d78c2c..d44a35463197 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -448,9 +448,14 @@ struct mt76_usb {
 
 struct mt76_sdio {
 	struct workqueue_struct *txrx_wq;
-	struct work_struct tx_work;
-	struct work_struct rx_work;
-	struct work_struct work;
+	struct {
+		struct work_struct xmit_work;
+		struct work_struct status_work;
+	} tx;
+	struct {
+		struct work_struct recv_work;
+		struct work_struct net_work;
+	} rx;
 
 	struct work_struct stat_work;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index 0cc3f0aca70b..ddf62dc05c00 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -368,8 +368,8 @@ static int mt7663s_probe(struct sdio_func *func,
 	if (ret < 0)
 		goto err_free;
 
-	INIT_WORK(&mdev->sdio.tx_work, mt7663s_tx_work);
-	INIT_WORK(&mdev->sdio.rx_work, mt7663s_rx_work);
+	INIT_WORK(&mdev->sdio.tx.xmit_work, mt7663s_tx_work);
+	INIT_WORK(&mdev->sdio.rx.recv_work, mt7663s_rx_work);
 
 	ret = mt7663s_hw_init(dev, func);
 	if (ret)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
index 8872b145df64..c945b4e0320d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
@@ -196,7 +196,8 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q)
 
 void mt7663s_tx_work(struct work_struct *work)
 {
-	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, tx_work);
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio,
+					      tx.xmit_work);
 	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
 	int i, nframes = 0;
 
@@ -210,14 +211,15 @@ void mt7663s_tx_work(struct work_struct *work)
 		nframes += ret;
 	}
 	if (nframes)
-		queue_work(sdio->txrx_wq, &sdio->tx_work);
+		queue_work(sdio->txrx_wq, &sdio->tx.xmit_work);
 
-	queue_work(sdio->txrx_wq, &sdio->work);
+	queue_work(sdio->txrx_wq, &sdio->tx.status_work);
 }
 
 void mt7663s_rx_work(struct work_struct *work)
 {
-	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, rx_work);
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio,
+					      rx.recv_work);
 	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
 	struct mt76s_intr intr;
 	int nframes = 0, ret;
@@ -233,7 +235,7 @@ void mt7663s_rx_work(struct work_struct *work)
 	if (intr.isr & WHIER_RX0_DONE_INT_EN) {
 		ret = mt7663s_rx_run_queue(dev, 0, &intr);
 		if (ret > 0) {
-			queue_work(sdio->txrx_wq, &sdio->work);
+			queue_work(sdio->txrx_wq, &sdio->rx.net_work);
 			nframes += ret;
 		}
 	}
@@ -241,18 +243,18 @@ void mt7663s_rx_work(struct work_struct *work)
 	if (intr.isr & WHIER_RX1_DONE_INT_EN) {
 		ret = mt7663s_rx_run_queue(dev, 1, &intr);
 		if (ret > 0) {
-			queue_work(sdio->txrx_wq, &sdio->work);
+			queue_work(sdio->txrx_wq, &sdio->rx.net_work);
 			nframes += ret;
 		}
 	}
 
 	if (intr.isr & WHIER_TX_DONE_INT_EN) {
 		mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
-		queue_work(sdio->txrx_wq, &sdio->tx_work);
+		queue_work(sdio->txrx_wq, &sdio->tx.xmit_work);
 	}
 
 	if (nframes) {
-		queue_work(sdio->txrx_wq, &sdio->rx_work);
+		queue_work(sdio->txrx_wq, &sdio->rx.recv_work);
 		return;
 	}
 
@@ -270,5 +272,5 @@ void mt7663s_sdio_irq(struct sdio_func *func)
 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.phy.state))
 		return;
 
-	queue_work(sdio->txrx_wq, &sdio->rx_work);
+	queue_work(sdio->txrx_wq, &sdio->rx.recv_work);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index 5432b388ceab..40fd752d1234 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -68,9 +68,10 @@ void mt76s_stop_txrx(struct mt76_dev *dev)
 {
 	struct mt76_sdio *sdio = &dev->sdio;
 
-	cancel_work_sync(&sdio->tx_work);
-	cancel_work_sync(&sdio->rx_work);
-	cancel_work_sync(&sdio->work);
+	cancel_work_sync(&sdio->tx.xmit_work);
+	cancel_work_sync(&sdio->tx.status_work);
+	cancel_work_sync(&sdio->rx.recv_work);
+	cancel_work_sync(&sdio->rx.net_work);
 	cancel_work_sync(&sdio->stat_work);
 	clear_bit(MT76_READING_STATS, &dev->phy.state);
 
@@ -274,7 +275,7 @@ static void mt76s_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 {
 	struct mt76_sdio *sdio = &dev->sdio;
 
-	queue_work(sdio->txrx_wq, &sdio->tx_work);
+	queue_work(sdio->txrx_wq, &sdio->tx.xmit_work);
 }
 
 static const struct mt76_queue_ops sdio_queue_ops = {
@@ -283,9 +284,25 @@ static const struct mt76_queue_ops sdio_queue_ops = {
 	.tx_queue_skb_raw = mt76s_tx_queue_skb_raw,
 };
 
-static void mt76s_txrx_work(struct work_struct *work)
+static void mt76s_tx_work(struct work_struct *work)
 {
-	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, work);
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio,
+					      tx.status_work);
+	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
+	int i;
+
+	for (i = 0; i < MT_TXQ_MCU_WA; i++)
+		mt76s_process_tx_queue(dev, i);
+
+	if (dev->drv->tx_status_data &&
+	    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
+		queue_work(dev->wq, &dev->sdio.stat_work);
+}
+
+static void mt76s_rx_work(struct work_struct *work)
+{
+	struct mt76_sdio *sdio = container_of(work, struct mt76_sdio,
+					      rx.net_work);
 	struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);
 	int i;
 
@@ -298,14 +315,6 @@ static void mt76s_txrx_work(struct work_struct *work)
 
 	rcu_read_unlock();
 	local_bh_enable();
-
-	/* tx processing */
-	for (i = 0; i < MT_TXQ_MCU_WA; i++)
-		mt76s_process_tx_queue(dev, i);
-
-	if (dev->drv->tx_status_data &&
-	    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
-		queue_work(dev->wq, &dev->sdio.stat_work);
 }
 
 void mt76s_deinit(struct mt76_dev *dev)
@@ -352,7 +361,8 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
 		return -ENOMEM;
 
 	INIT_WORK(&sdio->stat_work, mt76s_tx_status_data);
-	INIT_WORK(&sdio->work, mt76s_txrx_work);
+	INIT_WORK(&sdio->tx.status_work, mt76s_tx_work);
+	INIT_WORK(&sdio->rx.net_work, mt76s_rx_work);
 
 	mutex_init(&sdio->sched.lock);
 	dev->queue_ops = &sdio_queue_ops;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-07-30 14:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-30 14:09 [PATCH 0/4] mt7663s: move tx/rx processing in a dedicated wq Lorenzo Bianconi
2020-07-30 14:09 ` [PATCH 1/4] mt76: mt76s: move tx " Lorenzo Bianconi
2020-07-30 14:09 ` [PATCH 2/4] mt76: mt7663s: move rx processing in txrx wq Lorenzo Bianconi
2020-07-30 14:09 ` [PATCH 3/4] mt76: mt76s: move status " Lorenzo Bianconi
2020-07-30 14:09 ` [PATCH 4/4] mt76: mt76s: move tx/rx processing in 2 separate works Lorenzo Bianconi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.