mt7663s: move tx/rx processing in a dedicated wq
Subsystems (2)
Lorenzo Bianconi
maintainercover mt7663s: move tx/rx processing in a dedicated wq
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(-)
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 1/4 mt76: mt76s: move tx processing in a dedicated wq
Introduce mt76s_txrx_wq workqueue and move tx processing from kthread to a dedicated work. This is preliminary patch to improve mt7663s throughput
--- 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(-)
drivers/net/wireless/mediatek/mt76/mt76.h +3 -1
@@ -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;
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +1 -1
@@ -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
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +3 -6
@@ -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 );
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +19 -37
103 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/sdio.c +13 -3
@@ -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);
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 2/4 mt76: mt7663s: move rx processing in txrx wq
In reply to Lorenzo BianconiMove rx processing to mt76s_txrx_wq in order to minimize the interval when the sdio bus is locked during rx
--- 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(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -0
@@ -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;
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +1 -0
@@ -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
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +1 -0
@@ -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)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +53 -29
128 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/sdio.c +1 -0
@@ -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);
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 3/4 mt76: mt76s: move status processing in txrx wq
In reply to Lorenzo BianconiAs it has been done for tx and rx processing, move tx/rx status processing into mt76s_txrx_wq workqueue
--- 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(-)
drivers/net/wireless/mediatek/mt76/mt76.h +3 -3
@@ -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;
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +3 -3
@@ -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; } }
drivers/net/wireless/mediatek/mt76/sdio.c +19 -35
86 lines not on this page · raw message
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 4/4 mt76: mt76s: move tx/rx processing in 2 separate works
In reply to Lorenzo BianconiIn order to maximize parallelism, split status work in tx status work and rx net work
--- 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(-)
drivers/net/wireless/mediatek/mt76/mt76.h +8 -3
@@ -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;
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +2 -2
@@ -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)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +11 -9
@@ -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); }
drivers/net/wireless/mediatek/mt76/sdio.c +25 -15
@@ -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;
Signature · 1 line
2.26.2