* [PATCH 0/2] mt76u: convert rx/status path to worker APIs
@ 2020-10-20 9:13 Lorenzo Bianconi
2020-10-20 9:13 ` [PATCH 1/2] mt76: mt76u: rely on woker APIs for rx work Lorenzo Bianconi
2020-10-20 9:13 ` [PATCH 2/2] mt76: mt76u: use dedicated thread for status work Lorenzo Bianconi
0 siblings, 2 replies; 3+ messages in thread
From: Lorenzo Bianconi @ 2020-10-20 9:13 UTC (permalink / raw)
To: nbd; +Cc: lorenzo.bianconi, linux-wireless, sean.wang
In order to improve parallelism and improve performances, convert
rx and status path in mt76-usb module to mt76 worker APIs.
mt7663u upstream codepath:
TCP tx: ~420Mbps
TCP rx: ~360Mbps
mt7663u worker APIs:
TCP tx: ~455Mbps
TCP rx: ~380Mbps
Lorenzo Bianconi (2):
mt76: mt76u: rely on woker APIs for rx work
mt76: mt76u: use dedicated thread for status work
drivers/net/wireless/mediatek/mt76/mt76.h | 4 +-
.../net/wireless/mediatek/mt76/mt7615/usb.c | 9 ++-
.../net/wireless/mediatek/mt76/mt76x0/usb.c | 1 +
.../net/wireless/mediatek/mt76/mt76x2/usb.c | 1 +
drivers/net/wireless/mediatek/mt76/usb.c | 68 +++++++++++++------
5 files changed, 56 insertions(+), 27 deletions(-)
--
2.26.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] mt76: mt76u: rely on woker APIs for rx work
2020-10-20 9:13 [PATCH 0/2] mt76u: convert rx/status path to worker APIs Lorenzo Bianconi
@ 2020-10-20 9:13 ` Lorenzo Bianconi
2020-10-20 9:13 ` [PATCH 2/2] mt76: mt76u: use dedicated thread for status work Lorenzo Bianconi
1 sibling, 0 replies; 3+ messages in thread
From: Lorenzo Bianconi @ 2020-10-20 9:13 UTC (permalink / raw)
To: nbd; +Cc: lorenzo.bianconi, linux-wireless, sean.wang
In order to improve parallelism, convert rx path in mt76-usb module to
mt76 workers APIs
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
.../net/wireless/mediatek/mt76/mt7615/usb.c | 9 ++--
.../net/wireless/mediatek/mt76/mt76x0/usb.c | 1 +
.../net/wireless/mediatek/mt76/mt76x2/usb.c | 1 +
drivers/net/wireless/mediatek/mt76/usb.c | 48 ++++++++++++-------
5 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 64683eff76fa..7b78244057b8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -430,7 +430,7 @@ struct mt76_usb {
u8 *data;
u16 data_len;
- struct tasklet_struct rx_tasklet;
+ struct mt76_worker rx_worker;
struct work_struct stat_work;
u8 out_ep[__MT_EP_OUT_MAX];
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
index f0ad83af9e00..a60cfa345521 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
@@ -126,21 +126,20 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
alloc_queues:
ret = mt76u_alloc_mcu_queue(&dev->mt76);
if (ret)
- goto error_free_q;
+ goto error;
ret = mt76u_alloc_queues(&dev->mt76);
if (ret)
- goto error_free_q;
+ goto error;
ret = mt7663_usb_sdio_register_device(dev);
if (ret)
- goto error_free_q;
+ goto error;
return 0;
-error_free_q:
- mt76u_queues_deinit(&dev->mt76);
error:
+ mt76u_queues_deinit(&dev->mt76);
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index ce6b286a8152..b12cb17cb43d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -277,6 +277,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
err:
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
+ mt76u_queues_deinit(&dev->mt76);
mt76_free_device(&dev->mt76);
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index 4e003c7b62cf..2575369e44e2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -75,6 +75,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
return 0;
err:
+ mt76u_queues_deinit(&dev->mt76);
mt76_free_device(&dev->mt76);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 911fb61dfab4..63f55abede71 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -627,7 +627,7 @@ static void mt76u_complete_rx(struct urb *urb)
q->head = (q->head + 1) % q->ndesc;
q->queued++;
- tasklet_schedule(&dev->usb.rx_tasklet);
+ mt76_worker_schedule(&dev->usb.rx_worker);
out:
spin_unlock_irqrestore(&q->lock, flags);
}
@@ -665,13 +665,17 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
}
mt76u_submit_rx_buf(dev, qid, urb);
}
- if (qid == MT_RXQ_MAIN)
+ if (qid == MT_RXQ_MAIN) {
+ local_bh_disable();
mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
+ local_bh_enable();
+ }
}
-static void mt76u_rx_tasklet(struct tasklet_struct *t)
+static void mt76u_rx_worker(struct mt76_worker *w)
{
- struct mt76_dev *dev = from_tasklet(dev, t, usb.rx_tasklet);
+ struct mt76_usb *usb = container_of(w, struct mt76_usb, rx_worker);
+ struct mt76_dev *dev = container_of(usb, struct mt76_dev, usb);
int i;
rcu_read_lock();
@@ -737,8 +741,13 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
struct page *page;
int i;
- for (i = 0; i < q->ndesc; i++)
+ for (i = 0; i < q->ndesc; i++) {
+ if (!q->entry[i].urb)
+ continue;
+
mt76u_urb_free(q->entry[i].urb);
+ q->entry[i].urb = NULL;
+ }
if (!q->rx_page.va)
return;
@@ -752,6 +761,8 @@ static void mt76u_free_rx(struct mt76_dev *dev)
{
int i;
+ mt76_worker_teardown(&dev->usb.rx_worker);
+
mt76_for_each_q_rx(dev, i)
mt76u_free_rx_queue(dev, &dev->q_rx[i]);
}
@@ -760,6 +771,8 @@ void mt76u_stop_rx(struct mt76_dev *dev)
{
int i;
+ mt76_worker_disable(&dev->usb.rx_worker);
+
mt76_for_each_q_rx(dev, i) {
struct mt76_queue *q = &dev->q_rx[i];
int j;
@@ -767,8 +780,6 @@ void mt76u_stop_rx(struct mt76_dev *dev)
for (j = 0; j < q->ndesc; j++)
usb_poison_urb(q->entry[j].urb);
}
-
- tasklet_kill(&dev->usb.rx_tasklet);
}
EXPORT_SYMBOL_GPL(mt76u_stop_rx);
@@ -788,6 +799,8 @@ int mt76u_resume_rx(struct mt76_dev *dev)
return err;
}
+ mt76_worker_enable(&dev->usb.rx_worker);
+
return 0;
}
EXPORT_SYMBOL_GPL(mt76u_resume_rx);
@@ -1011,8 +1024,10 @@ static void mt76u_free_tx(struct mt76_dev *dev)
if (!q)
continue;
- for (j = 0; j < q->ndesc; j++)
+ for (j = 0; j < q->ndesc; j++) {
usb_free_urb(q->entry[j].urb);
+ q->entry[j].urb = NULL;
+ }
}
}
@@ -1102,7 +1117,7 @@ int mt76u_init(struct mt76_dev *dev,
};
struct usb_device *udev = interface_to_usbdev(intf);
struct mt76_usb *usb = &dev->usb;
- int err = -ENOMEM;
+ int err;
mt76u_ops.rr = ext ? mt76u_rr_ext : mt76u_rr;
mt76u_ops.wr = ext ? mt76u_wr_ext : mt76u_wr;
@@ -1110,7 +1125,6 @@ int mt76u_init(struct mt76_dev *dev,
mt76u_ops.write_copy = ext ? mt76u_copy_ext : mt76u_copy;
dev->tx_worker.fn = mt76u_tx_worker;
- tasklet_setup(&usb->rx_tasklet, mt76u_rx_tasklet);
INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
@@ -1119,7 +1133,7 @@ int mt76u_init(struct mt76_dev *dev,
usb->data = devm_kmalloc(dev->dev, usb->data_len, GFP_KERNEL);
if (!usb->data)
- goto error;
+ return -ENOMEM;
mutex_init(&usb->usb_ctrl_mtx);
dev->bus = &mt76u_ops;
@@ -1131,14 +1145,16 @@ int mt76u_init(struct mt76_dev *dev,
err = mt76u_set_endpoints(intf, usb);
if (err < 0)
- goto error;
+ return err;
- return 0;
+ err = mt76_worker_setup(dev->hw, &usb->rx_worker, mt76u_rx_worker,
+ "usb-rx");
+ if (err)
+ return err;
-error:
- destroy_workqueue(dev->wq);
+ sched_set_fifo_low(usb->rx_worker.task);
- return err;
+ return 0;
}
EXPORT_SYMBOL_GPL(mt76u_init);
--
2.26.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] mt76: mt76u: use dedicated thread for status work
2020-10-20 9:13 [PATCH 0/2] mt76u: convert rx/status path to worker APIs Lorenzo Bianconi
2020-10-20 9:13 ` [PATCH 1/2] mt76: mt76u: rely on woker APIs for rx work Lorenzo Bianconi
@ 2020-10-20 9:13 ` Lorenzo Bianconi
1 sibling, 0 replies; 3+ messages in thread
From: Lorenzo Bianconi @ 2020-10-20 9:13 UTC (permalink / raw)
To: nbd; +Cc: lorenzo.bianconi, linux-wireless, sean.wang
Split tx and status path in mt76-usb module relying on mt76 workers APIs
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++
drivers/net/wireless/mediatek/mt76/usb.c | 20 +++++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 7b78244057b8..cd60b47619f1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -430,7 +430,9 @@ struct mt76_usb {
u8 *data;
u16 data_len;
+ struct mt76_worker status_worker;
struct mt76_worker rx_worker;
+
struct work_struct stat_work;
u8 out_ep[__MT_EP_OUT_MAX];
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 63f55abede71..7396bdae6db0 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -805,9 +805,10 @@ int mt76u_resume_rx(struct mt76_dev *dev)
}
EXPORT_SYMBOL_GPL(mt76u_resume_rx);
-static void mt76u_tx_worker(struct mt76_worker *w)
+static void mt76u_status_worker(struct mt76_worker *w)
{
- struct mt76_dev *dev = container_of(w, struct mt76_dev, tx_worker);
+ struct mt76_usb *usb = container_of(w, struct mt76_usb, status_worker);
+ struct mt76_dev *dev = container_of(usb, struct mt76_dev, usb);
struct mt76_queue_entry entry;
struct mt76_queue *q;
bool wake;
@@ -833,7 +834,7 @@ static void mt76u_tx_worker(struct mt76_worker *w)
if (!q->queued)
wake_up(&dev->tx_wait);
- mt76_txq_schedule(&dev->phy, i);
+ mt76_worker_schedule(&dev->tx_worker);
if (dev->drv->tx_status_data &&
!test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
@@ -877,7 +878,7 @@ static void mt76u_complete_tx(struct urb *urb)
dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
e->done = true;
- mt76_worker_schedule(&dev->tx_worker);
+ mt76_worker_schedule(&dev->usb.status_worker);
}
static int
@@ -1016,6 +1017,8 @@ static void mt76u_free_tx(struct mt76_dev *dev)
{
int i;
+ mt76_worker_teardown(&dev->usb.status_worker);
+
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
struct mt76_queue *q;
int j;
@@ -1036,6 +1039,7 @@ void mt76u_stop_tx(struct mt76_dev *dev)
int ret;
mt76_worker_disable(&dev->tx_worker);
+ mt76_worker_disable(&dev->usb.status_worker);
ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(&dev->phy),
HZ / 5);
@@ -1074,6 +1078,7 @@ void mt76u_stop_tx(struct mt76_dev *dev)
clear_bit(MT76_READING_STATS, &dev->phy.state);
mt76_worker_enable(&dev->tx_worker);
+ mt76_worker_enable(&dev->usb.status_worker);
mt76_tx_status_check(dev, NULL, true);
}
@@ -1124,7 +1129,6 @@ int mt76u_init(struct mt76_dev *dev,
mt76u_ops.rmw = ext ? mt76u_rmw_ext : mt76u_rmw;
mt76u_ops.write_copy = ext ? mt76u_copy_ext : mt76u_copy;
- dev->tx_worker.fn = mt76u_tx_worker;
INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
@@ -1152,7 +1156,13 @@ int mt76u_init(struct mt76_dev *dev,
if (err)
return err;
+ err = mt76_worker_setup(dev->hw, &usb->status_worker,
+ mt76u_status_worker, "usb-status");
+ if (err)
+ return err;
+
sched_set_fifo_low(usb->rx_worker.task);
+ sched_set_fifo_low(usb->status_worker.task);
return 0;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-10-20 9:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-20 9:13 [PATCH 0/2] mt76u: convert rx/status path to worker APIs Lorenzo Bianconi
2020-10-20 9:13 ` [PATCH 1/2] mt76: mt76u: rely on woker APIs for rx work Lorenzo Bianconi
2020-10-20 9:13 ` [PATCH 2/2] mt76: mt76u: use dedicated thread for status work Lorenzo Bianconi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).