* [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 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.