From patchwork Thu Jul 30 14:09:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 11693141 X-Patchwork-Delegate: nbd@nbd.name Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 35A0213B1 for ; Thu, 30 Jul 2020 14:10:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 18C6A21744 for ; Thu, 30 Jul 2020 14:10:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118201; bh=Jvy7R2+W4yzCzOC9owIBC3DZTav3nQBBvQ27uk/HWNM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=pLerbMv2k+yHPxzyPB3rIrj9p/IaHo9TRtQh0LZOVW1eiqmE3xkoC30K2PqqWBs+G O7T1rUmDUkDxMMlNTF77+56ms+GP1R2CQr2C+908vtH1Dhs1roxotrZY0NLWqVRVJU Ua/LRdZ7lUrxX5raYkJg2Pzd1YMUe56Np7AgZm68= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729433AbgG3OKA (ORCPT ); Thu, 30 Jul 2020 10:10:00 -0400 Received: from mail.kernel.org ([198.145.29.99]:41490 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727072AbgG3OJ7 (ORCPT ); Thu, 30 Jul 2020 10:09:59 -0400 Received: from lore-desk.redhat.com (unknown [151.48.137.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E2E4420842; Thu, 30 Jul 2020 14:09:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118198; bh=Jvy7R2+W4yzCzOC9owIBC3DZTav3nQBBvQ27uk/HWNM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sTmxJ/PEcTlMky8jnoB7y3z9hseJ4pDOBlNB9FMoHlzIJcVBA5Y1MBnFbkaGZmzAd rWcPt6HWe62lLuWtwo0uelSNUMpaSdrZta97XYESyIlq5onbigVikiAslVehuWnE7t VqtdzK3MHzg+Kja4ajV0GcolYXBaTvGvTttJFo80= From: Lorenzo Bianconi To: nbd@nbd.name Cc: lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, linux-wireless@vger.kernel.org Subject: [PATCH 1/4] mt76: mt76s: move tx processing in a dedicated wq Date: Thu, 30 Jul 2020 16:09:48 +0200 Message-Id: <8116493da15164a352562ccf0bdbc2a6386d3806.1596115358.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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 --- 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); From patchwork Thu Jul 30 14:09:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 11693143 X-Patchwork-Delegate: nbd@nbd.name Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0279513B1 for ; Thu, 30 Jul 2020 14:10:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D977D21744 for ; Thu, 30 Jul 2020 14:10:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118202; bh=lOsOWZ27Jw3DC1n865K2xRIBOdJLkPsizKOfoAbM6cI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=xJ1qVdlfoHN0vMPfKR7ERzIkWxrR7aaIst1DFN9WQuR5GzOKUtmMObJ/BgsRDNXsS GZX4JsYhDILhyZsXrPwlZtoeeffyvpGszHHMLR3jth8vuRmvegdO7Nnm2S7ET9/+QP PyQJSB+iXHe740Z0yraN4OTEOKVmz22WoAcJ+p0Y= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729513AbgG3OKC (ORCPT ); Thu, 30 Jul 2020 10:10:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:41500 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727072AbgG3OKB (ORCPT ); Thu, 30 Jul 2020 10:10:01 -0400 Received: from lore-desk.redhat.com (unknown [151.48.137.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D3070208A9; Thu, 30 Jul 2020 14:09:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118200; bh=lOsOWZ27Jw3DC1n865K2xRIBOdJLkPsizKOfoAbM6cI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=piwls/7FdNHAJ/L70ZkR2SaNlYHpQVm7m1LXyeGvBTHFLE9UVv5s0G1E6x0oR1nzg OG3IwRBxI+S52IASOy3M1BbdNxh8P06upGcYA6RyiNfhcJnL0SCSKxoYrGqyNjO6kI N5kbPLSTrY38C1YEYTWhhUvqDZnL1jIRA30uUxiY= From: Lorenzo Bianconi To: nbd@nbd.name Cc: lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, linux-wireless@vger.kernel.org Subject: [PATCH 2/4] mt76: mt7663s: move rx processing in txrx wq Date: Thu, 30 Jul 2020 16:09:49 +0200 Message-Id: <3952dcf0afcd74064a65810b4c8e6a5369ebd110.1596115358.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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 --- 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); From patchwork Thu Jul 30 14:09:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 11693145 X-Patchwork-Delegate: nbd@nbd.name Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD3B1913 for ; Thu, 30 Jul 2020 14:10:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C4D6A21D95 for ; Thu, 30 Jul 2020 14:10:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118204; bh=6jGOG/jdCRWMTGeEcPIP4lkoOmahuJYpCi39KFq1cms=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=lznNbkJQTc7x/jkI9f0npx87g7Dd8Pb9v3aTfZFotXTisIqBDnIbamEvxicJgmwIG J2rUK1Jz9oSx9vo5rCIfnay779Z/bB17ikEJtjgZB3dYS7ABJL3OTILtZdVkpOuhQA p292h+dgYmiV1lrjznkUNq91EDtUlx297pzz1twg= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729453AbgG3OKE (ORCPT ); Thu, 30 Jul 2020 10:10:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:41512 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727072AbgG3OKD (ORCPT ); Thu, 30 Jul 2020 10:10:03 -0400 Received: from lore-desk.redhat.com (unknown [151.48.137.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C38AB2074B; Thu, 30 Jul 2020 14:10:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118202; bh=6jGOG/jdCRWMTGeEcPIP4lkoOmahuJYpCi39KFq1cms=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HR/d0hDTzMjIfbksxtrtLzcgdN+BYIfC/2NPCkpYKToVQ1x/uTmZkPDjYGNEQYO0a ErDe2AtD9+dFKS4yUnq5Hg+uOwM2zIfAMn8tCs8gs9LDn92aCt0I3KzeqBeYxcZPMv 17Jd4KeOic7OQYuEgHnfwhDX9woUpv8qkArDRxoo= From: Lorenzo Bianconi To: nbd@nbd.name Cc: lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, linux-wireless@vger.kernel.org Subject: [PATCH 3/4] mt76: mt76s: move status processing in txrx wq Date: Thu, 30 Jul 2020 16:09:50 +0200 Message-Id: <2e909d4651da44b1632d081084873e12af9883e0.1596115358.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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 --- 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; From patchwork Thu Jul 30 14:09:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 11693147 X-Patchwork-Delegate: nbd@nbd.name Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C50FF13B1 for ; Thu, 30 Jul 2020 14:10:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A778821744 for ; Thu, 30 Jul 2020 14:10:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118206; bh=cCwoYxzkKwxTtrfhgsNMyCtFYj9+kQx0he8bMN/HdWI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=bUJJuAQIvxVD8zz/018qJFL26D5EG4m8mY8tJEWl0kFFwws0fkyC/tidO3aRklWYY Ri1DH1SQYYQK0RkvKtX03+PUtjq9AKaipgEP0WdrTO4Tb/uKUTkCo+g7bUQjdoSFDg uA/9kVs9vgpBUBdyU5WDNEpVscbekxvOTKqhX0p0= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729438AbgG3OKG (ORCPT ); Thu, 30 Jul 2020 10:10:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:41530 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729484AbgG3OKF (ORCPT ); Thu, 30 Jul 2020 10:10:05 -0400 Received: from lore-desk.redhat.com (unknown [151.48.137.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A803A20842; Thu, 30 Jul 2020 14:10:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596118204; bh=cCwoYxzkKwxTtrfhgsNMyCtFYj9+kQx0he8bMN/HdWI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YhfdzgADhNLgKGTxAhjc0/pU4IF9rRvNYdOdWkq1UKTlVL9hLDNwTF/uGvBxpOkec JBxmSv7O1j4JaP/Nt9hcfFvaEj/b9by6MWTjOmIbpwlpXYD1aOAr3n1UOnoM6ah5IU pf7hmFz8Co3YpSPpydUWwt87q+yPxzHvdQ5HGRTQ= From: Lorenzo Bianconi To: nbd@nbd.name Cc: lorenzo.bianconi@redhat.com, sean.wang@mediatek.com, linux-wireless@vger.kernel.org Subject: [PATCH 4/4] mt76: mt76s: move tx/rx processing in 2 separate works Date: Thu, 30 Jul 2020 16:09:51 +0200 Message-Id: X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org In order to maximize parallelism, split status work in tx status work and rx net work Signed-off-by: Lorenzo Bianconi --- 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;