linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/12] mt76usb: some cleanups and optimizations
@ 2019-03-12 15:05 Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 01/12] mt76usb: change mt76u_submit_buf Stanislaw Gruszka
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

This should be rebased on latest patches, for now sent as RFC.

Significant change is remove mt76u_buf and use urb directly
and allocate urb and sg as linear data for better cache usage.
Other that that, set consist only of some minor cleanups.

Stanislaw Gruszka (12):
  mt76usb: change mt76u_submit_buf
  mt76: remove rx_page_lock
  mt76usb: change mt76u_fill_rx_sg arguments
  mt76usb: use usb_dev private data
  mt76usb: remove mt76u_buf redundant fileds
  mt76usb: move mt76u_buf->done to queue entry
  mt76usb: remove mt76u_buf and use urb directly
  mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc
  mt76usb: resue mt76u_urb_alloc for tx
  mt76usb: remove unneded sg_init_table
  mt76usb: allocate urb and sg as linear data
  mt76usb: remove queue variable from rx_tasklet

 drivers/net/wireless/mediatek/mt76/mt76.h       |  15 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/usb.c |   2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2/usb.c |   4 +-
 drivers/net/wireless/mediatek/mt76/usb.c        | 231 +++++++++++-------------
 4 files changed, 111 insertions(+), 141 deletions(-)

-- 
1.9.3


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

* [RFC 01/12] mt76usb: change mt76u_submit_buf
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
@ 2019-03-12 15:05 ` Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 02/12] mt76: remove rx_page_lock Stanislaw Gruszka
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Remove unnecessery arguments and change the function name since is
now used only for RX.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index c5f3b2cdd9b1..661a65cb9c35 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -394,18 +394,6 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 			  complete_fn, context);
 }
 
-static int
-mt76u_submit_buf(struct mt76_dev *dev, int dir, int index,
-		 struct mt76u_buf *buf, gfp_t gfp,
-		 usb_complete_t complete_fn, void *context)
-{
-	mt76u_fill_bulk_urb(dev, dir, index, buf, complete_fn,
-			    context);
-	trace_submit_urb(dev, buf->urb);
-
-	return usb_submit_urb(buf->urb, gfp);
-}
-
 static inline struct mt76u_buf
 *mt76u_get_next_rx_entry(struct mt76_queue *q)
 {
@@ -513,6 +501,16 @@ static void mt76u_complete_rx(struct urb *urb)
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
+static int
+mt76u_submit_rx_buf(struct mt76_dev *dev, struct mt76u_buf *buf)
+{
+	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, buf,
+			    mt76u_complete_rx, dev);
+	trace_submit_urb(dev, buf->urb);
+
+	return usb_submit_urb(buf->urb, GFP_ATOMIC);
+}
+
 static void mt76u_rx_tasklet(unsigned long data)
 {
 	struct mt76_dev *dev = (struct mt76_dev *)data;
@@ -534,9 +532,7 @@ static void mt76u_rx_tasklet(unsigned long data)
 			if (err < 0)
 				break;
 		}
-		mt76u_submit_buf(dev, USB_DIR_IN, MT_EP_IN_PKT_RX,
-				 buf, GFP_ATOMIC,
-				 mt76u_complete_rx, dev);
+		mt76u_submit_rx_buf(dev, buf);
 	}
 	mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
 
@@ -551,9 +547,7 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
 
 	spin_lock_irqsave(&q->lock, flags);
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_submit_buf(dev, USB_DIR_IN, MT_EP_IN_PKT_RX,
-				       &q->entry[i].ubuf, GFP_ATOMIC,
-				       mt76u_complete_rx, dev);
+		err = mt76u_submit_rx_buf(dev, &q->entry[i].ubuf);
 		if (err < 0)
 			break;
 	}
-- 
1.9.3


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

* [RFC 02/12] mt76: remove rx_page_lock
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 01/12] mt76usb: change mt76u_submit_buf Stanislaw Gruszka
@ 2019-03-12 15:05 ` Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 03/12] mt76usb: change mt76u_fill_rx_sg arguments Stanislaw Gruszka
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

We can not run mt76u_alloc_buf() concurently, rx_tasklet is stooped
when mt76u_submit_rx_buffers(). We can remove rx_page_lock.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
 drivers/net/wireless/mediatek/mt76/usb.c  | 8 +-------
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 3d3f0a5fc426..424f9090680d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -132,7 +132,6 @@ struct mt76_queue {
 	dma_addr_t desc_dma;
 	struct sk_buff *rx_head;
 	struct page_frag_cache rx_page;
-	spinlock_t rx_page_lock;
 };
 
 struct mt76_sw_queue {
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 661a65cb9c35..883e8a2b519f 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -292,7 +292,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	struct urb *urb = buf->urb;
 	int i;
 
-	spin_lock_bh(&q->rx_page_lock);
 	for (i = 0; i < nsgs; i++) {
 		struct page *page;
 		void *data;
@@ -306,7 +305,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		offset = data - page_address(page);
 		sg_set_page(&urb->sg[i], page, sglen, offset);
 	}
-	spin_unlock_bh(&q->rx_page_lock);
 
 	if (i < nsgs) {
 		int j;
@@ -569,7 +567,6 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
 	if (!usb->mcu.data)
 		return -ENOMEM;
 
-	spin_lock_init(&q->rx_page_lock);
 	spin_lock_init(&q->lock);
 	q->entry = devm_kcalloc(dev->dev,
 				MT_NUM_RX_ENTRIES, sizeof(*q->entry),
@@ -597,15 +594,12 @@ static void mt76u_free_rx(struct mt76_dev *dev)
 	for (i = 0; i < q->ndesc; i++)
 		mt76u_buf_free(&q->entry[i].ubuf);
 
-	spin_lock_bh(&q->rx_page_lock);
 	if (!q->rx_page.va)
-		goto out;
+		return;
 
 	page = virt_to_page(q->rx_page.va);
 	__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
 	memset(&q->rx_page, 0, sizeof(q->rx_page));
-out:
-	spin_unlock_bh(&q->rx_page_lock);
 }
 
 static void mt76u_stop_rx(struct mt76_dev *dev)
-- 
1.9.3


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

* [RFC 03/12] mt76usb: change mt76u_fill_rx_sg arguments
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 01/12] mt76usb: change mt76u_submit_buf Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 02/12] mt76: remove rx_page_lock Stanislaw Gruszka
@ 2019-03-12 15:05 ` Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 04/12] mt76usb: use usb_dev private data Stanislaw Gruszka
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

We do not need to pass len and sglen to the function.
Additionally pass gfp to control allocation context.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 883e8a2b519f..dbabf7971798 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -285,11 +285,13 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
-		 int nsgs, int len, int sglen)
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
+		 gfp_t gfp)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
 	struct urb *urb = buf->urb;
+
 	int i;
 
 	for (i = 0; i < nsgs; i++) {
@@ -297,7 +299,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		void *data;
 		int offset;
 
-		data = page_frag_alloc(&q->rx_page, len, GFP_ATOMIC);
+		data = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
 		if (!data)
 			break;
 
@@ -326,8 +328,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		struct mt76u_buf *buf, int nsgs, gfp_t gfp)
 {
 	if (dev->usb.sg_en) {
-		return mt76u_fill_rx_sg(dev, buf, nsgs, q->buf_size,
-					SKB_WITH_OVERHEAD(q->buf_size));
+		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
 	} else {
 		buf->buf = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
 		return buf->buf ? 0 : -ENOMEM;
-- 
1.9.3


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

* [RFC 04/12] mt76usb: use usb_dev private data
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (2 preceding siblings ...)
  2019-03-12 15:05 ` [RFC 03/12] mt76usb: change mt76u_fill_rx_sg arguments Stanislaw Gruszka
@ 2019-03-12 15:05 ` Stanislaw Gruszka
  2019-03-12 15:05 ` [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds Stanislaw Gruszka
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Setup usb device private data. This allows to remove mt76u_buf->dev
and simplify some routines as no longer we need to get usb device
through usb interface.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h       |  4 +---
 drivers/net/wireless/mediatek/mt76/mt76x0/usb.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2/usb.c |  4 +++-
 drivers/net/wireless/mediatek/mt76/usb.c        | 13 ++++---------
 4 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 424f9090680d..89cdfe4abf33 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -84,7 +84,6 @@ struct mt76_queue_buf {
 };
 
 struct mt76u_buf {
-	struct mt76_dev *dev;
 	struct urb *urb;
 	size_t len;
 	void *buf;
@@ -744,8 +743,7 @@ static inline u8 q2ep(u8 qid)
 mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
 	       int timeout)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 	struct mt76_usb *usb = &dev->usb;
 	unsigned int pipe;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 69d6328a098d..1ef00e971cfa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -234,7 +234,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
 	u32 mac_rev;
 	int ret;
 
-	mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), &mt76x0u_ops,
+	mdev = mt76_alloc_device(&usb_dev->dev, sizeof(*dev), &mt76x0u_ops,
 				 &drv_ops);
 	if (!mdev)
 		return -ENOMEM;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index 47fe536bf896..0a7df308b2f8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -50,7 +50,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
 	struct mt76_dev *mdev;
 	int err;
 
-	mdev = mt76_alloc_device(&intf->dev, sizeof(*dev), &mt76x2u_ops,
+	mdev = mt76_alloc_device(&udev->dev, sizeof(*dev), &mt76x2u_ops,
 				 &drv_ops);
 	if (!mdev)
 		return -ENOMEM;
@@ -60,6 +60,8 @@ static int mt76x2u_probe(struct usb_interface *intf,
 	udev = usb_get_dev(udev);
 	usb_reset_device(udev);
 
+	usb_set_intfdata(intf, dev);
+
 	mt76x02u_init_mcu(mdev);
 	err = mt76u_init(mdev, intf);
 	if (err < 0)
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index dbabf7971798..954feb311620 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -31,8 +31,7 @@ static int __mt76u_vendor_request(struct mt76_dev *dev, u8 req,
 				  u8 req_type, u16 val, u16 offset,
 				  void *buf, size_t len)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 	unsigned int pipe;
 	int i, ret;
 
@@ -247,8 +246,7 @@ void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
 
 static bool mt76u_check_sg(struct mt76_dev *dev)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 
 	return (!disable_usb_sg && udev->bus->sg_tablesize > 0 &&
 		(udev->bus->no_sg_constraint ||
@@ -341,7 +339,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 
 	buf->len = SKB_WITH_OVERHEAD(q->buf_size);
-	buf->dev = dev;
 
 	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!buf->urb)
@@ -379,8 +376,7 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 		    struct mt76u_buf *buf, usb_complete_t complete_fn,
 		    void *context)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 	u8 *data = buf->urb->num_sgs ? NULL : buf->buf;
 	unsigned int pipe;
 
@@ -694,8 +690,8 @@ static void mt76u_tx_status_data(struct work_struct *work)
 
 static void mt76u_complete_tx(struct urb *urb)
 {
+	struct mt76_dev *dev = dev_get_drvdata(&urb->dev->dev);
 	struct mt76u_buf *buf = urb->context;
-	struct mt76_dev *dev = buf->dev;
 
 	if (mt76u_urb_error(urb))
 		dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
@@ -806,7 +802,6 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
 		q->ndesc = MT_NUM_TX_ENTRIES;
 		for (j = 0; j < q->ndesc; j++) {
 			buf = &q->entry[j].ubuf;
-			buf->dev = dev;
 
 			buf->urb = usb_alloc_urb(0, GFP_KERNEL);
 			if (!buf->urb)
-- 
1.9.3


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

* [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (3 preceding siblings ...)
  2019-03-12 15:05 ` [RFC 04/12] mt76usb: use usb_dev private data Stanislaw Gruszka
@ 2019-03-12 15:05 ` Stanislaw Gruszka
  2019-03-12 16:25   ` Lorenzo Bianconi
  2019-03-12 15:06 ` [RFC 06/12] mt76usb: move mt76u_buf->done to queue entry Stanislaw Gruszka
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Remove mt76u_buf->{len, buf} fields and operate on corresponding
urb fields directly.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 --
 drivers/net/wireless/mediatek/mt76/usb.c  | 40 +++++++++++++++++--------------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 89cdfe4abf33..476cb39c99b7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -85,8 +85,6 @@ struct mt76_queue_buf {
 
 struct mt76u_buf {
 	struct urb *urb;
-	size_t len;
-	void *buf;
 	bool done;
 };
 
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 954feb311620..86bf852c6e3d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -315,7 +315,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	}
 
 	urb->num_sgs = max_t(int, i, urb->num_sgs);
-	buf->len = urb->num_sgs * sglen,
+	urb->transfer_buffer_length = urb->num_sgs * sglen,
 	sg_init_marker(urb->sg, urb->num_sgs);
 
 	return i ? : -ENOMEM;
@@ -328,8 +328,11 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	if (dev->usb.sg_en) {
 		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
 	} else {
-		buf->buf = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
-		return buf->buf ? 0 : -ENOMEM;
+		buf->urb->transfer_buffer_length =
+			SKB_WITH_OVERHEAD(q->buf_size);
+		buf->urb->transfer_buffer =
+			page_frag_alloc(&q->rx_page, q->buf_size, gfp);
+		return buf->urb->transfer_buffer ? 0 : -ENOMEM;
 	}
 }
 
@@ -338,8 +341,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 
-	buf->len = SKB_WITH_OVERHEAD(q->buf_size);
-
 	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!buf->urb)
 		return -ENOMEM;
@@ -365,8 +366,8 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	for (i = 0; i < urb->num_sgs; i++)
 		skb_free_frag(sg_virt(&urb->sg[i]));
 
-	if (buf->buf)
-		skb_free_frag(buf->buf);
+	if (urb->transfer_buffer)
+		skb_free_frag(urb->transfer_buffer);
 
 	usb_free_urb(buf->urb);
 }
@@ -377,7 +378,6 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 		    void *context)
 {
 	struct usb_device *udev = to_usb_device(dev->dev);
-	u8 *data = buf->urb->num_sgs ? NULL : buf->buf;
 	unsigned int pipe;
 
 	if (dir == USB_DIR_IN)
@@ -385,8 +385,10 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	else
 		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
 
-	usb_fill_bulk_urb(buf->urb, udev, pipe, data, buf->len,
-			  complete_fn, context);
+	buf->urb->dev = udev;
+	buf->urb->pipe = pipe;
+	buf->urb->complete = complete_fn;
+	buf->urb->context = context;
 }
 
 static inline struct mt76u_buf
@@ -426,7 +428,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb = buf->urb;
-	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : buf->buf;
+	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
 	int data_len, len, nsgs = 1;
 	struct sk_buff *skb;
 
@@ -437,7 +439,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
 	if (len < 0)
 		return 0;
 
-	data_len = urb->num_sgs ? urb->sg[0].length : buf->len;
+	data_len = urb->num_sgs ? urb->sg[0].length : INT_MAX;
 	data_len = min_t(int, len, data_len - MT_DMA_HDR_LEN);
 	if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size))
 		return 0;
@@ -731,14 +733,16 @@ static void mt76u_complete_tx(struct urb *urb)
 		return err;
 
 	buf = &q->entry[idx].ubuf;
-	buf->buf = skb->data;
-	buf->len = skb->len;
+	if (!dev->usb.sg_en) {
+		buf->urb->transfer_buffer = skb->data;
+	} else {
+		err = mt76u_tx_build_sg(dev, skb, buf->urb);
+		if (err < 0)
+			return err;
+	}
+	buf->urb->transfer_buffer_length = skb->len;
 	buf->done = false;
 
-	err = mt76u_tx_build_sg(dev, skb, buf->urb);
-	if (err < 0)
-		return err;
-
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
 			    buf, mt76u_complete_tx, buf);
 
-- 
1.9.3


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

* [RFC 06/12] mt76usb: move mt76u_buf->done to queue entry
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (4 preceding siblings ...)
  2019-03-12 15:05 ` [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  2019-03-12 15:06 ` [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly Stanislaw Gruszka
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

mt76_queue_entry has alreay one bool variable, adding new one will
not increase it's size. Removing ->done filed from mt76u_buf will
allow to use urb directly in mt76usb code.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 +-
 drivers/net/wireless/mediatek/mt76/usb.c  | 12 +++++-------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 476cb39c99b7..998505064dee 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -85,7 +85,6 @@ struct mt76_queue_buf {
 
 struct mt76u_buf {
 	struct urb *urb;
-	bool done;
 };
 
 struct mt76_queue_entry {
@@ -99,6 +98,7 @@ struct mt76_queue_entry {
 	};
 	enum mt76_txq_id qid;
 	bool schedule;
+	bool done;
 };
 
 struct mt76_queue_regs {
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 86bf852c6e3d..a4ef9bb1603d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -615,7 +615,6 @@ static void mt76u_tx_tasklet(unsigned long data)
 	struct mt76_dev *dev = (struct mt76_dev *)data;
 	struct mt76_queue_entry entry;
 	struct mt76_sw_queue *sq;
-	struct mt76u_buf *buf;
 	struct mt76_queue *q;
 	bool wake;
 	int i;
@@ -626,8 +625,7 @@ static void mt76u_tx_tasklet(unsigned long data)
 
 		spin_lock_bh(&q->lock);
 		while (true) {
-			buf = &q->entry[q->head].ubuf;
-			if (!buf->done || !q->queued)
+			if (!q->entry[q->head].done || !q->queued)
 				break;
 
 			if (q->entry[q->head].schedule) {
@@ -693,11 +691,11 @@ static void mt76u_tx_status_data(struct work_struct *work)
 static void mt76u_complete_tx(struct urb *urb)
 {
 	struct mt76_dev *dev = dev_get_drvdata(&urb->dev->dev);
-	struct mt76u_buf *buf = urb->context;
+	struct mt76_queue_entry *e = urb->context;
 
 	if (mt76u_urb_error(urb))
 		dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
-	buf->done = true;
+	e->done = true;
 
 	tasklet_schedule(&dev->usb.tx_tasklet);
 }
@@ -732,6 +730,7 @@ static void mt76u_complete_tx(struct urb *urb)
 	if (err < 0)
 		return err;
 
+	q->entry[idx].done = false;
 	buf = &q->entry[idx].ubuf;
 	if (!dev->usb.sg_en) {
 		buf->urb->transfer_buffer = skb->data;
@@ -741,10 +740,9 @@ static void mt76u_complete_tx(struct urb *urb)
 			return err;
 	}
 	buf->urb->transfer_buffer_length = skb->len;
-	buf->done = false;
 
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
-			    buf, mt76u_complete_tx, buf);
+			    buf, mt76u_complete_tx, &q->entry[idx]);
 
 	q->tail = (q->tail + 1) % q->ndesc;
 	q->entry[idx].skb = skb;
-- 
1.9.3


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

* [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (5 preceding siblings ...)
  2019-03-12 15:06 ` [RFC 06/12] mt76usb: move mt76u_buf->done to queue entry Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  2019-03-12 16:27   ` Lorenzo Bianconi
  2019-03-12 15:06 ` [RFC 08/12] mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc Stanislaw Gruszka
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Put urb pointer in mt76_queue_entry directly instead of mt76u_buf
structure.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |   6 +-
 drivers/net/wireless/mediatek/mt76/usb.c  | 132 +++++++++++++++---------------
 2 files changed, 65 insertions(+), 73 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 998505064dee..859d0325583b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -83,10 +83,6 @@ struct mt76_queue_buf {
 	int len;
 };
 
-struct mt76u_buf {
-	struct urb *urb;
-};
-
 struct mt76_queue_entry {
 	union {
 		void *buf;
@@ -94,7 +90,7 @@ struct mt76_queue_entry {
 	};
 	union {
 		struct mt76_txwi_cache *txwi;
-		struct mt76u_buf ubuf;
+		struct urb *urb;
 	};
 	enum mt76_txq_id qid;
 	bool schedule;
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index a4ef9bb1603d..2c21f4773a19 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -283,12 +283,11 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
 		 gfp_t gfp)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
-	struct urb *urb = buf->urb;
 
 	int i;
 
@@ -323,44 +322,43 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 
 static int
 mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
-		struct mt76u_buf *buf, int nsgs, gfp_t gfp)
+		struct urb *urb, int nsgs, gfp_t gfp)
 {
 	if (dev->usb.sg_en) {
-		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
+		return mt76u_fill_rx_sg(dev, urb, nsgs, gfp);
 	} else {
-		buf->urb->transfer_buffer_length =
-			SKB_WITH_OVERHEAD(q->buf_size);
-		buf->urb->transfer_buffer =
-			page_frag_alloc(&q->rx_page, q->buf_size, gfp);
-		return buf->urb->transfer_buffer ? 0 : -ENOMEM;
+		urb->transfer_buffer_length = SKB_WITH_OVERHEAD(q->buf_size);
+		urb->transfer_buffer = page_frag_alloc(&q->rx_page,
+						       q->buf_size, gfp);
+		return urb->transfer_buffer ? 0 : -ENOMEM;
 	}
 }
 
 static int
-mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
+mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+	struct urb *urb;
 
-	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!buf->urb)
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
 		return -ENOMEM;
+	e->urb = urb;
 
 	if (dev->usb.sg_en) {
-		buf->urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
-					    sizeof(*buf->urb->sg),
-					    GFP_KERNEL);
-		if (!buf->urb->sg)
+		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
+				       sizeof(urb->sg), GFP_KERNEL);
+		if (!urb->sg)
 			return -ENOMEM;
 
-		sg_init_table(buf->urb->sg, MT_SG_MAX_SIZE);
+		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
-	return mt76u_refill_rx(dev, q, buf, MT_SG_MAX_SIZE, GFP_KERNEL);
+	return mt76u_refill_rx(dev, q, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
 }
 
-static void mt76u_buf_free(struct mt76u_buf *buf)
+static void mt76u_urb_free(struct urb *urb)
 {
-	struct urb *urb = buf->urb;
 	int i;
 
 	for (i = 0; i < urb->num_sgs; i++)
@@ -369,12 +367,12 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	if (urb->transfer_buffer)
 		skb_free_frag(urb->transfer_buffer);
 
-	usb_free_urb(buf->urb);
+	usb_free_urb(urb);
 }
 
 static void
 mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
-		    struct mt76u_buf *buf, usb_complete_t complete_fn,
+		    struct urb *urb, usb_complete_t complete_fn,
 		    void *context)
 {
 	struct usb_device *udev = to_usb_device(dev->dev);
@@ -385,27 +383,27 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	else
 		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
 
-	buf->urb->dev = udev;
-	buf->urb->pipe = pipe;
-	buf->urb->complete = complete_fn;
-	buf->urb->context = context;
+	urb->dev = udev;
+	urb->pipe = pipe;
+	urb->complete = complete_fn;
+	urb->context = context;
 }
 
-static inline struct mt76u_buf
-*mt76u_get_next_rx_entry(struct mt76_queue *q)
+static inline struct urb *
+mt76u_get_next_rx_entry(struct mt76_queue *q)
 {
-	struct mt76u_buf *buf = NULL;
+	struct urb *urb = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&q->lock, flags);
 	if (q->queued > 0) {
-		buf = &q->entry[q->head].ubuf;
+		urb = q->entry[q->head].urb;
 		q->head = (q->head + 1) % q->ndesc;
 		q->queued--;
 	}
 	spin_unlock_irqrestore(&q->lock, flags);
 
-	return buf;
+	return urb;
 }
 
 static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
@@ -424,10 +422,9 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
 }
 
 static int
-mt76u_process_rx_entry(struct mt76_dev *dev, struct mt76u_buf *buf)
+mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
-	struct urb *urb = buf->urb;
 	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
 	int data_len, len, nsgs = 1;
 	struct sk_buff *skb;
@@ -488,7 +485,7 @@ static void mt76u_complete_rx(struct urb *urb)
 	}
 
 	spin_lock_irqsave(&q->lock, flags);
-	if (WARN_ONCE(q->entry[q->tail].ubuf.urb != urb, "rx urb mismatch"))
+	if (WARN_ONCE(q->entry[q->tail].urb != urb, "rx urb mismatch"))
 		goto out;
 
 	q->tail = (q->tail + 1) % q->ndesc;
@@ -499,37 +496,37 @@ static void mt76u_complete_rx(struct urb *urb)
 }
 
 static int
-mt76u_submit_rx_buf(struct mt76_dev *dev, struct mt76u_buf *buf)
+mt76u_submit_rx_buf(struct mt76_dev *dev, struct urb *urb)
 {
-	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, buf,
+	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, urb,
 			    mt76u_complete_rx, dev);
-	trace_submit_urb(dev, buf->urb);
+	trace_submit_urb(dev, urb);
 
-	return usb_submit_urb(buf->urb, GFP_ATOMIC);
+	return usb_submit_urb(urb, GFP_ATOMIC);
 }
 
 static void mt76u_rx_tasklet(unsigned long data)
 {
 	struct mt76_dev *dev = (struct mt76_dev *)data;
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	int err, count;
 
 	rcu_read_lock();
 
 	while (true) {
-		buf = mt76u_get_next_rx_entry(q);
-		if (!buf)
+		urb = mt76u_get_next_rx_entry(q);
+		if (!urb)
 			break;
 
-		count = mt76u_process_rx_entry(dev, buf);
+		count = mt76u_process_rx_entry(dev, urb);
 		if (count > 0) {
-			err = mt76u_refill_rx(dev, q, buf, count,
+			err = mt76u_refill_rx(dev, q, urb, count,
 					      GFP_ATOMIC);
 			if (err < 0)
 				break;
 		}
-		mt76u_submit_rx_buf(dev, buf);
+		mt76u_submit_rx_buf(dev, urb);
 	}
 	mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
 
@@ -544,7 +541,7 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
 
 	spin_lock_irqsave(&q->lock, flags);
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_submit_rx_buf(dev, &q->entry[i].ubuf);
+		err = mt76u_submit_rx_buf(dev, q->entry[i].urb);
 		if (err < 0)
 			break;
 	}
@@ -576,7 +573,7 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
 	q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
 	q->ndesc = MT_NUM_RX_ENTRIES;
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_buf_alloc(dev, &q->entry[i].ubuf);
+		err = mt76u_urb_alloc(dev, &q->entry[i]);
 		if (err < 0)
 			return err;
 	}
@@ -591,7 +588,7 @@ static void mt76u_free_rx(struct mt76_dev *dev)
 	int i;
 
 	for (i = 0; i < q->ndesc; i++)
-		mt76u_buf_free(&q->entry[i].ubuf);
+		mt76u_urb_free(q->entry[i].urb);
 
 	if (!q->rx_page.va)
 		return;
@@ -607,7 +604,7 @@ static void mt76u_stop_rx(struct mt76_dev *dev)
 	int i;
 
 	for (i = 0; i < q->ndesc; i++)
-		usb_kill_urb(q->entry[i].ubuf.urb);
+		usb_kill_urb(q->entry[i].urb);
 }
 
 static void mt76u_tx_tasklet(unsigned long data)
@@ -718,7 +715,7 @@ static void mt76u_complete_tx(struct urb *urb)
 		   struct ieee80211_sta *sta)
 {
 	struct mt76_queue *q = dev->q_tx[qid].q;
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	u16 idx = q->tail;
 	int err;
 
@@ -731,18 +728,18 @@ static void mt76u_complete_tx(struct urb *urb)
 		return err;
 
 	q->entry[idx].done = false;
-	buf = &q->entry[idx].ubuf;
+	urb = q->entry[idx].urb;
 	if (!dev->usb.sg_en) {
-		buf->urb->transfer_buffer = skb->data;
+		urb->transfer_buffer = skb->data;
 	} else {
-		err = mt76u_tx_build_sg(dev, skb, buf->urb);
+		err = mt76u_tx_build_sg(dev, skb, urb);
 		if (err < 0)
 			return err;
 	}
-	buf->urb->transfer_buffer_length = skb->len;
+	urb->transfer_buffer_length = skb->len;
 
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
-			    buf, mt76u_complete_tx, &q->entry[idx]);
+			    urb, mt76u_complete_tx, &q->entry[idx]);
 
 	q->tail = (q->tail + 1) % q->ndesc;
 	q->entry[idx].skb = skb;
@@ -753,14 +750,14 @@ static void mt76u_complete_tx(struct urb *urb)
 
 static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 {
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	int err;
 
 	while (q->first != q->tail) {
-		buf = &q->entry[q->first].ubuf;
+		urb = q->entry[q->first].urb;
 
-		trace_submit_urb(dev, buf->urb);
-		err = usb_submit_urb(buf->urb, GFP_ATOMIC);
+		trace_submit_urb(dev, urb);
+		err = usb_submit_urb(urb, GFP_ATOMIC);
 		if (err < 0) {
 			if (err == -ENODEV)
 				set_bit(MT76_REMOVED, &dev->state);
@@ -775,7 +772,7 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 
 static int mt76u_alloc_tx(struct mt76_dev *dev)
 {
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	struct mt76_queue *q;
 	int i, j;
 
@@ -803,19 +800,18 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
 
 		q->ndesc = MT_NUM_TX_ENTRIES;
 		for (j = 0; j < q->ndesc; j++) {
-			buf = &q->entry[j].ubuf;
-
-			buf->urb = usb_alloc_urb(0, GFP_KERNEL);
-			if (!buf->urb)
+			urb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!urb)
 				return -ENOMEM;
+			q->entry[j].urb = urb;
 
 			if (dev->usb.sg_en) {
 				size_t size = MT_SG_MAX_SIZE *
 					      sizeof(struct scatterlist);
 
-				buf->urb->sg = devm_kzalloc(dev->dev, size,
-							    GFP_KERNEL);
-				if (!buf->urb->sg)
+				urb->sg = devm_kzalloc(dev->dev, size,
+						       GFP_KERNEL);
+				if (!urb->sg)
 					return -ENOMEM;
 			}
 		}
@@ -831,7 +827,7 @@ static void mt76u_free_tx(struct mt76_dev *dev)
 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 		q = dev->q_tx[i].q;
 		for (j = 0; j < q->ndesc; j++)
-			usb_free_urb(q->entry[j].ubuf.urb);
+			usb_free_urb(q->entry[j].urb);
 	}
 }
 
@@ -843,7 +839,7 @@ static void mt76u_stop_tx(struct mt76_dev *dev)
 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 		q = dev->q_tx[i].q;
 		for (j = 0; j < q->ndesc; j++)
-			usb_kill_urb(q->entry[j].ubuf.urb);
+			usb_kill_urb(q->entry[j].urb);
 	}
 }
 
-- 
1.9.3


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

* [RFC 08/12] mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (6 preceding siblings ...)
  2019-03-12 15:06 ` [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  2019-03-12 15:06 ` [RFC 09/12] mt76usb: resue mt76u_urb_alloc for tx Stanislaw Gruszka
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Get the RX queue inside mt76u_refill_rx. This will allow to reuse
mt76u_urb_alloc for TX allocations.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 2c21f4773a19..ca62ddc03be2 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -283,12 +283,10 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
-		 gfp_t gfp)
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb,
+		 int nsgs, gfp_t gfp)
 {
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
-
 	int i;
 
 	for (i = 0; i < nsgs; i++) {
@@ -321,11 +319,12 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
-		struct urb *urb, int nsgs, gfp_t gfp)
+mt76u_refill_rx(struct mt76_dev *dev, struct urb *urb, int nsgs, gfp_t gfp)
 {
+	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+
 	if (dev->usb.sg_en) {
-		return mt76u_fill_rx_sg(dev, urb, nsgs, gfp);
+		return mt76u_fill_rx_sg(dev, q, urb, nsgs, gfp);
 	} else {
 		urb->transfer_buffer_length = SKB_WITH_OVERHEAD(q->buf_size);
 		urb->transfer_buffer = page_frag_alloc(&q->rx_page,
@@ -337,7 +336,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 static int
 mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
 {
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb;
 
 	urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -354,7 +352,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
-	return mt76u_refill_rx(dev, q, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
+	return mt76u_refill_rx(dev, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
 }
 
 static void mt76u_urb_free(struct urb *urb)
@@ -521,8 +519,7 @@ static void mt76u_rx_tasklet(unsigned long data)
 
 		count = mt76u_process_rx_entry(dev, urb);
 		if (count > 0) {
-			err = mt76u_refill_rx(dev, q, urb, count,
-					      GFP_ATOMIC);
+			err = mt76u_refill_rx(dev, urb, count, GFP_ATOMIC);
 			if (err < 0)
 				break;
 		}
-- 
1.9.3


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

* [RFC 09/12] mt76usb: resue mt76u_urb_alloc for tx
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (7 preceding siblings ...)
  2019-03-12 15:06 ` [RFC 08/12] mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  2019-03-12 15:06 ` [RFC 10/12] mt76usb: remove unneded sg_init_table Stanislaw Gruszka
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Add new rx_urb_alloc routine and reuse common urb_alloc for tx
allocations.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 36 ++++++++++++++++----------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index ca62ddc03be2..64fac91f1a72 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -352,7 +352,19 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
-	return mt76u_refill_rx(dev, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
+	return 0;
+}
+
+static int
+mt76u_rx_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
+{
+	int err;
+
+	err = mt76u_urb_alloc(dev, e);
+	if (err)
+		return err;
+
+	return mt76u_refill_rx(dev, e->urb, MT_SG_MAX_SIZE, GFP_KERNEL);
 }
 
 static void mt76u_urb_free(struct urb *urb)
@@ -570,7 +582,7 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
 	q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
 	q->ndesc = MT_NUM_RX_ENTRIES;
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_urb_alloc(dev, &q->entry[i]);
+		err = mt76u_rx_urb_alloc(dev, &q->entry[i]);
 		if (err < 0)
 			return err;
 	}
@@ -769,9 +781,8 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 
 static int mt76u_alloc_tx(struct mt76_dev *dev)
 {
-	struct urb *urb;
 	struct mt76_queue *q;
-	int i, j;
+	int i, j, err;
 
 	for (i = 0; i <= MT_TXQ_PSD; i++) {
 		INIT_LIST_HEAD(&dev->q_tx[i].swq);
@@ -797,20 +808,9 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
 
 		q->ndesc = MT_NUM_TX_ENTRIES;
 		for (j = 0; j < q->ndesc; j++) {
-			urb = usb_alloc_urb(0, GFP_KERNEL);
-			if (!urb)
-				return -ENOMEM;
-			q->entry[j].urb = urb;
-
-			if (dev->usb.sg_en) {
-				size_t size = MT_SG_MAX_SIZE *
-					      sizeof(struct scatterlist);
-
-				urb->sg = devm_kzalloc(dev->dev, size,
-						       GFP_KERNEL);
-				if (!urb->sg)
-					return -ENOMEM;
-			}
+			err = mt76u_urb_alloc(dev, &q->entry[j]);
+			if (err < 0)
+				return err;
 		}
 	}
 	return 0;
-- 
1.9.3


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

* [RFC 10/12] mt76usb: remove unneded sg_init_table
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (8 preceding siblings ...)
  2019-03-12 15:06 ` [RFC 09/12] mt76usb: resue mt76u_urb_alloc for tx Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  2019-03-12 15:06 ` [RFC 11/12] mt76usb: allocate urb and sg as linear data Stanislaw Gruszka
  2019-03-12 15:06 ` [RFC 12/12] mt76usb: remove queue variable from rx_tasklet Stanislaw Gruszka
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

We already allocate with GFP_ZERO and sg marker is set later for
both RX and TX.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 64fac91f1a72..0b9f0b5fd37d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -348,8 +348,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 				       sizeof(urb->sg), GFP_KERNEL);
 		if (!urb->sg)
 			return -ENOMEM;
-
-		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
 	return 0;
-- 
1.9.3


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

* [RFC 11/12] mt76usb: allocate urb and sg as linear data
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (9 preceding siblings ...)
  2019-03-12 15:06 ` [RFC 10/12] mt76usb: remove unneded sg_init_table Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  2019-03-12 16:34   ` Lorenzo Bianconi
  2019-03-12 15:06 ` [RFC 12/12] mt76usb: remove queue variable from rx_tasklet Stanislaw Gruszka
  11 siblings, 1 reply; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Alloc sg table at the end of urb structure. This will increase
cache usage.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 0b9f0b5fd37d..dd487f65f44e 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -336,19 +336,19 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 static int
 mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
 {
-	struct urb *urb;
+	unsigned int size = sizeof(struct urb);
+
+	if (dev->usb.sg_en)
+		size += MT_SG_MAX_SIZE * sizeof(struct scatterlist);
 
-	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!urb)
+	e->urb = kzalloc(size, GFP_KERNEL);
+	if (!e->urb)
 		return -ENOMEM;
-	e->urb = urb;
 
-	if (dev->usb.sg_en) {
-		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
-				       sizeof(urb->sg), GFP_KERNEL);
-		if (!urb->sg)
-			return -ENOMEM;
-	}
+	usb_init_urb(e->urb);
+
+	if (dev->usb.sg_en)
+		e->urb->sg = (struct scatterlist *)((u8 *)e->urb + sizeof(struct urb));
 
 	return 0;
 }
-- 
1.9.3


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

* [RFC 12/12] mt76usb: remove queue variable from rx_tasklet
  2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
                   ` (10 preceding siblings ...)
  2019-03-12 15:06 ` [RFC 11/12] mt76usb: allocate urb and sg as linear data Stanislaw Gruszka
@ 2019-03-12 15:06 ` Stanislaw Gruszka
  11 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka

Since now only mt76u_get_next_rx_entry use queue argument move
it to this function.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index dd487f65f44e..6a23e1852d2a 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -398,8 +398,9 @@ static void mt76u_urb_free(struct urb *urb)
 }
 
 static inline struct urb *
-mt76u_get_next_rx_entry(struct mt76_queue *q)
+mt76u_get_next_rx_entry(struct mt76_dev *dev)
 {
+	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb = NULL;
 	unsigned long flags;
 
@@ -516,14 +517,13 @@ static void mt76u_complete_rx(struct urb *urb)
 static void mt76u_rx_tasklet(unsigned long data)
 {
 	struct mt76_dev *dev = (struct mt76_dev *)data;
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb;
 	int err, count;
 
 	rcu_read_lock();
 
 	while (true) {
-		urb = mt76u_get_next_rx_entry(q);
+		urb = mt76u_get_next_rx_entry(dev);
 		if (!urb)
 			break;
 
-- 
1.9.3


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

* Re: [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds
  2019-03-12 15:05 ` [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds Stanislaw Gruszka
@ 2019-03-12 16:25   ` Lorenzo Bianconi
  2019-03-13 12:53     ` Stanislaw Gruszka
  0 siblings, 1 reply; 19+ messages in thread
From: Lorenzo Bianconi @ 2019-03-12 16:25 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau

[-- Attachment #1: Type: text/plain, Size: 3038 bytes --]

> Remove mt76u_buf->{len, buf} fields and operate on corresponding
> urb fields directly.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/mediatek/mt76/mt76.h |  2 --
>  drivers/net/wireless/mediatek/mt76/usb.c  | 40 +++++++++++++++++--------------
>  2 files changed, 22 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 89cdfe4abf33..476cb39c99b7 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -85,8 +85,6 @@ struct mt76_queue_buf {
>  

[...]

> @@ -377,7 +378,6 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  		    void *context)
>  {
>  	struct usb_device *udev = to_usb_device(dev->dev);
> -	u8 *data = buf->urb->num_sgs ? NULL : buf->buf;
>  	unsigned int pipe;
>  
>  	if (dir == USB_DIR_IN)
> @@ -385,8 +385,10 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  	else
>  		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
>  
> -	usb_fill_bulk_urb(buf->urb, udev, pipe, data, buf->len,
> -			  complete_fn, context);
> +	buf->urb->dev = udev;
> +	buf->urb->pipe = pipe;
> +	buf->urb->complete = complete_fn;
> +	buf->urb->context = context;
>  }
>  
>  static inline struct mt76u_buf
> @@ -426,7 +428,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
>  	struct urb *urb = buf->urb;
> -	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : buf->buf;
> +	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
>  	int data_len, len, nsgs = 1;
>  	struct sk_buff *skb;
>  
> @@ -437,7 +439,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
>  	if (len < 0)
>  		return 0;
>  
> -	data_len = urb->num_sgs ? urb->sg[0].length : buf->len;
> +	data_len = urb->num_sgs ? urb->sg[0].length : INT_MAX;

In this way we only use len, maybe better to do:
	data_len = urb->num_sgs ? urb->sg[0].length :
				  SKB_WITH_OVERHEAD(q->buf_size)

>  	data_len = min_t(int, len, data_len - MT_DMA_HDR_LEN);
>  	if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size))
>  		return 0;
> @@ -731,14 +733,16 @@ static void mt76u_complete_tx(struct urb *urb)
>  		return err;
>  
>  	buf = &q->entry[idx].ubuf;
> -	buf->buf = skb->data;
> -	buf->len = skb->len;
> +	if (!dev->usb.sg_en) {
> +		buf->urb->transfer_buffer = skb->data;

I think you can move this in mt76u_tx_build_sg or remove the if condition in
mt76u_tx_build_sg()

Regards,
Lorenzo

> +	} else {
> +		err = mt76u_tx_build_sg(dev, skb, buf->urb);
> +		if (err < 0)
> +			return err;
> +	}
> +	buf->urb->transfer_buffer_length = skb->len;
>  	buf->done = false;
>  
> -	err = mt76u_tx_build_sg(dev, skb, buf->urb);
> -	if (err < 0)
> -		return err;
> -
>  	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
>  			    buf, mt76u_complete_tx, buf);
>  
> -- 
> 1.9.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly
  2019-03-12 15:06 ` [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly Stanislaw Gruszka
@ 2019-03-12 16:27   ` Lorenzo Bianconi
  2019-03-13 12:53     ` Stanislaw Gruszka
  0 siblings, 1 reply; 19+ messages in thread
From: Lorenzo Bianconi @ 2019-03-12 16:27 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau

[-- Attachment #1: Type: text/plain, Size: 11997 bytes --]

> Put urb pointer in mt76_queue_entry directly instead of mt76u_buf
> structure.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/mediatek/mt76/mt76.h |   6 +-
>  drivers/net/wireless/mediatek/mt76/usb.c  | 132 +++++++++++++++---------------
>  2 files changed, 65 insertions(+), 73 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 998505064dee..859d0325583b 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -83,10 +83,6 @@ struct mt76_queue_buf {
>  	int len;
>  };
>  
> -struct mt76u_buf {
> -	struct urb *urb;
> -};
> -
>  struct mt76_queue_entry {
>  	union {
>  		void *buf;
> @@ -94,7 +90,7 @@ struct mt76_queue_entry {
>  	};
>  	union {
>  		struct mt76_txwi_cache *txwi;
> -		struct mt76u_buf ubuf;
> +		struct urb *urb;
>  	};
>  	enum mt76_txq_id qid;
>  	bool schedule;
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> index a4ef9bb1603d..2c21f4773a19 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -283,12 +283,11 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
>  }
>  
>  static int
> -mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
> +mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
>  		 gfp_t gfp)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
>  	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
> -	struct urb *urb = buf->urb;
>  
>  	int i;
>  
> @@ -323,44 +322,43 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
>  
>  static int
>  mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
> -		struct mt76u_buf *buf, int nsgs, gfp_t gfp)
> +		struct urb *urb, int nsgs, gfp_t gfp)
>  {
>  	if (dev->usb.sg_en) {
> -		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
> +		return mt76u_fill_rx_sg(dev, urb, nsgs, gfp);
>  	} else {
> -		buf->urb->transfer_buffer_length =
> -			SKB_WITH_OVERHEAD(q->buf_size);
> -		buf->urb->transfer_buffer =
> -			page_frag_alloc(&q->rx_page, q->buf_size, gfp);
> -		return buf->urb->transfer_buffer ? 0 : -ENOMEM;
> +		urb->transfer_buffer_length = SKB_WITH_OVERHEAD(q->buf_size);
> +		urb->transfer_buffer = page_frag_alloc(&q->rx_page,
> +						       q->buf_size, gfp);
> +		return urb->transfer_buffer ? 0 : -ENOMEM;
>  	}
>  }
>  
>  static int
> -mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
> +mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
> +	struct urb *urb;
>  
> -	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
> -	if (!buf->urb)
> +	urb = usb_alloc_urb(0, GFP_KERNEL);

I guess here you can do:
	e->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!e->urb)
		return -ENOMEM;

Regards,
Lorenzo

> +	if (!urb)
>  		return -ENOMEM;
> +	e->urb = urb;
>  
>  	if (dev->usb.sg_en) {
> -		buf->urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> -					    sizeof(*buf->urb->sg),
> -					    GFP_KERNEL);
> -		if (!buf->urb->sg)
> +		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> +				       sizeof(urb->sg), GFP_KERNEL);
> +		if (!urb->sg)
>  			return -ENOMEM;
>  
> -		sg_init_table(buf->urb->sg, MT_SG_MAX_SIZE);
> +		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
>  	}
>  
> -	return mt76u_refill_rx(dev, q, buf, MT_SG_MAX_SIZE, GFP_KERNEL);
> +	return mt76u_refill_rx(dev, q, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
>  }
>  
> -static void mt76u_buf_free(struct mt76u_buf *buf)
> +static void mt76u_urb_free(struct urb *urb)
>  {
> -	struct urb *urb = buf->urb;
>  	int i;
>  
>  	for (i = 0; i < urb->num_sgs; i++)
> @@ -369,12 +367,12 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  	if (urb->transfer_buffer)
>  		skb_free_frag(urb->transfer_buffer);
>  
> -	usb_free_urb(buf->urb);
> +	usb_free_urb(urb);
>  }
>  
>  static void
>  mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
> -		    struct mt76u_buf *buf, usb_complete_t complete_fn,
> +		    struct urb *urb, usb_complete_t complete_fn,
>  		    void *context)
>  {
>  	struct usb_device *udev = to_usb_device(dev->dev);
> @@ -385,27 +383,27 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  	else
>  		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
>  
> -	buf->urb->dev = udev;
> -	buf->urb->pipe = pipe;
> -	buf->urb->complete = complete_fn;
> -	buf->urb->context = context;
> +	urb->dev = udev;
> +	urb->pipe = pipe;
> +	urb->complete = complete_fn;
> +	urb->context = context;
>  }
>  
> -static inline struct mt76u_buf
> -*mt76u_get_next_rx_entry(struct mt76_queue *q)
> +static inline struct urb *
> +mt76u_get_next_rx_entry(struct mt76_queue *q)
>  {
> -	struct mt76u_buf *buf = NULL;
> +	struct urb *urb = NULL;
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&q->lock, flags);
>  	if (q->queued > 0) {
> -		buf = &q->entry[q->head].ubuf;
> +		urb = q->entry[q->head].urb;
>  		q->head = (q->head + 1) % q->ndesc;
>  		q->queued--;
>  	}
>  	spin_unlock_irqrestore(&q->lock, flags);
>  
> -	return buf;
> +	return urb;
>  }
>  
>  static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
> @@ -424,10 +422,9 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
>  }
>  
>  static int
> -mt76u_process_rx_entry(struct mt76_dev *dev, struct mt76u_buf *buf)
> +mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
> -	struct urb *urb = buf->urb;
>  	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
>  	int data_len, len, nsgs = 1;
>  	struct sk_buff *skb;
> @@ -488,7 +485,7 @@ static void mt76u_complete_rx(struct urb *urb)
>  	}
>  
>  	spin_lock_irqsave(&q->lock, flags);
> -	if (WARN_ONCE(q->entry[q->tail].ubuf.urb != urb, "rx urb mismatch"))
> +	if (WARN_ONCE(q->entry[q->tail].urb != urb, "rx urb mismatch"))
>  		goto out;
>  
>  	q->tail = (q->tail + 1) % q->ndesc;
> @@ -499,37 +496,37 @@ static void mt76u_complete_rx(struct urb *urb)
>  }
>  
>  static int
> -mt76u_submit_rx_buf(struct mt76_dev *dev, struct mt76u_buf *buf)
> +mt76u_submit_rx_buf(struct mt76_dev *dev, struct urb *urb)
>  {
> -	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, buf,
> +	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, urb,
>  			    mt76u_complete_rx, dev);
> -	trace_submit_urb(dev, buf->urb);
> +	trace_submit_urb(dev, urb);
>  
> -	return usb_submit_urb(buf->urb, GFP_ATOMIC);
> +	return usb_submit_urb(urb, GFP_ATOMIC);
>  }
>  
>  static void mt76u_rx_tasklet(unsigned long data)
>  {
>  	struct mt76_dev *dev = (struct mt76_dev *)data;
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	int err, count;
>  
>  	rcu_read_lock();
>  
>  	while (true) {
> -		buf = mt76u_get_next_rx_entry(q);
> -		if (!buf)
> +		urb = mt76u_get_next_rx_entry(q);
> +		if (!urb)
>  			break;
>  
> -		count = mt76u_process_rx_entry(dev, buf);
> +		count = mt76u_process_rx_entry(dev, urb);
>  		if (count > 0) {
> -			err = mt76u_refill_rx(dev, q, buf, count,
> +			err = mt76u_refill_rx(dev, q, urb, count,
>  					      GFP_ATOMIC);
>  			if (err < 0)
>  				break;
>  		}
> -		mt76u_submit_rx_buf(dev, buf);
> +		mt76u_submit_rx_buf(dev, urb);
>  	}
>  	mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
>  
> @@ -544,7 +541,7 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
>  
>  	spin_lock_irqsave(&q->lock, flags);
>  	for (i = 0; i < q->ndesc; i++) {
> -		err = mt76u_submit_rx_buf(dev, &q->entry[i].ubuf);
> +		err = mt76u_submit_rx_buf(dev, q->entry[i].urb);
>  		if (err < 0)
>  			break;
>  	}
> @@ -576,7 +573,7 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
>  	q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
>  	q->ndesc = MT_NUM_RX_ENTRIES;
>  	for (i = 0; i < q->ndesc; i++) {
> -		err = mt76u_buf_alloc(dev, &q->entry[i].ubuf);
> +		err = mt76u_urb_alloc(dev, &q->entry[i]);
>  		if (err < 0)
>  			return err;
>  	}
> @@ -591,7 +588,7 @@ static void mt76u_free_rx(struct mt76_dev *dev)
>  	int i;
>  
>  	for (i = 0; i < q->ndesc; i++)
> -		mt76u_buf_free(&q->entry[i].ubuf);
> +		mt76u_urb_free(q->entry[i].urb);
>  
>  	if (!q->rx_page.va)
>  		return;
> @@ -607,7 +604,7 @@ static void mt76u_stop_rx(struct mt76_dev *dev)
>  	int i;
>  
>  	for (i = 0; i < q->ndesc; i++)
> -		usb_kill_urb(q->entry[i].ubuf.urb);
> +		usb_kill_urb(q->entry[i].urb);
>  }
>  
>  static void mt76u_tx_tasklet(unsigned long data)
> @@ -718,7 +715,7 @@ static void mt76u_complete_tx(struct urb *urb)
>  		   struct ieee80211_sta *sta)
>  {
>  	struct mt76_queue *q = dev->q_tx[qid].q;
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	u16 idx = q->tail;
>  	int err;
>  
> @@ -731,18 +728,18 @@ static void mt76u_complete_tx(struct urb *urb)
>  		return err;
>  
>  	q->entry[idx].done = false;
> -	buf = &q->entry[idx].ubuf;
> +	urb = q->entry[idx].urb;
>  	if (!dev->usb.sg_en) {
> -		buf->urb->transfer_buffer = skb->data;
> +		urb->transfer_buffer = skb->data;
>  	} else {
> -		err = mt76u_tx_build_sg(dev, skb, buf->urb);
> +		err = mt76u_tx_build_sg(dev, skb, urb);
>  		if (err < 0)
>  			return err;
>  	}
> -	buf->urb->transfer_buffer_length = skb->len;
> +	urb->transfer_buffer_length = skb->len;
>  
>  	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
> -			    buf, mt76u_complete_tx, &q->entry[idx]);
> +			    urb, mt76u_complete_tx, &q->entry[idx]);
>  
>  	q->tail = (q->tail + 1) % q->ndesc;
>  	q->entry[idx].skb = skb;
> @@ -753,14 +750,14 @@ static void mt76u_complete_tx(struct urb *urb)
>  
>  static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
>  {
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	int err;
>  
>  	while (q->first != q->tail) {
> -		buf = &q->entry[q->first].ubuf;
> +		urb = q->entry[q->first].urb;
>  
> -		trace_submit_urb(dev, buf->urb);
> -		err = usb_submit_urb(buf->urb, GFP_ATOMIC);
> +		trace_submit_urb(dev, urb);
> +		err = usb_submit_urb(urb, GFP_ATOMIC);
>  		if (err < 0) {
>  			if (err == -ENODEV)
>  				set_bit(MT76_REMOVED, &dev->state);
> @@ -775,7 +772,7 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
>  
>  static int mt76u_alloc_tx(struct mt76_dev *dev)
>  {
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	struct mt76_queue *q;
>  	int i, j;
>  
> @@ -803,19 +800,18 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
>  
>  		q->ndesc = MT_NUM_TX_ENTRIES;
>  		for (j = 0; j < q->ndesc; j++) {
> -			buf = &q->entry[j].ubuf;
> -
> -			buf->urb = usb_alloc_urb(0, GFP_KERNEL);
> -			if (!buf->urb)
> +			urb = usb_alloc_urb(0, GFP_KERNEL);
> +			if (!urb)
>  				return -ENOMEM;
> +			q->entry[j].urb = urb;
>  
>  			if (dev->usb.sg_en) {
>  				size_t size = MT_SG_MAX_SIZE *
>  					      sizeof(struct scatterlist);
>  
> -				buf->urb->sg = devm_kzalloc(dev->dev, size,
> -							    GFP_KERNEL);
> -				if (!buf->urb->sg)
> +				urb->sg = devm_kzalloc(dev->dev, size,
> +						       GFP_KERNEL);
> +				if (!urb->sg)
>  					return -ENOMEM;
>  			}
>  		}
> @@ -831,7 +827,7 @@ static void mt76u_free_tx(struct mt76_dev *dev)
>  	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
>  		q = dev->q_tx[i].q;
>  		for (j = 0; j < q->ndesc; j++)
> -			usb_free_urb(q->entry[j].ubuf.urb);
> +			usb_free_urb(q->entry[j].urb);
>  	}
>  }
>  
> @@ -843,7 +839,7 @@ static void mt76u_stop_tx(struct mt76_dev *dev)
>  	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
>  		q = dev->q_tx[i].q;
>  		for (j = 0; j < q->ndesc; j++)
> -			usb_kill_urb(q->entry[j].ubuf.urb);
> +			usb_kill_urb(q->entry[j].urb);
>  	}
>  }
>  
> -- 
> 1.9.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [RFC 11/12] mt76usb: allocate urb and sg as linear data
  2019-03-12 15:06 ` [RFC 11/12] mt76usb: allocate urb and sg as linear data Stanislaw Gruszka
@ 2019-03-12 16:34   ` Lorenzo Bianconi
  2019-03-13 12:59     ` Stanislaw Gruszka
  0 siblings, 1 reply; 19+ messages in thread
From: Lorenzo Bianconi @ 2019-03-12 16:34 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau

[-- Attachment #1: Type: text/plain, Size: 1534 bytes --]

> Alloc sg table at the end of urb structure. This will increase
> cache usage.
> 

I am curious, have you observed any performance improvement doing so?

> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/mediatek/mt76/usb.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> index 0b9f0b5fd37d..dd487f65f44e 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -336,19 +336,19 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
>  static int
>  mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
>  {
> -	struct urb *urb;
> +	unsigned int size = sizeof(struct urb);
> +
> +	if (dev->usb.sg_en)
> +		size += MT_SG_MAX_SIZE * sizeof(struct scatterlist);
>  
> -	urb = usb_alloc_urb(0, GFP_KERNEL);
> -	if (!urb)
> +	e->urb = kzalloc(size, GFP_KERNEL);
> +	if (!e->urb)
>  		return -ENOMEM;
> -	e->urb = urb;
>  
> -	if (dev->usb.sg_en) {
> -		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> -				       sizeof(urb->sg), GFP_KERNEL);
> -		if (!urb->sg)
> -			return -ENOMEM;
> -	}
> +	usb_init_urb(e->urb);
> +
> +	if (dev->usb.sg_en)
> +		e->urb->sg = (struct scatterlist *)((u8 *)e->urb + sizeof(struct urb));

You can avoid u8 cast doing:
(struct scatterlist *)(e->urb + 1)

Regards,
Lorenzo

>  
>  	return 0;
>  }
> -- 
> 1.9.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds
  2019-03-12 16:25   ` Lorenzo Bianconi
@ 2019-03-13 12:53     ` Stanislaw Gruszka
  0 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-13 12:53 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, Felix Fietkau

On Tue, Mar 12, 2019 at 05:25:50PM +0100, Lorenzo Bianconi wrote:
> >  	buf = &q->entry[idx].ubuf;
> > -	buf->buf = skb->data;
> > -	buf->len = skb->len;
> > +	if (!dev->usb.sg_en) {
> > +		buf->urb->transfer_buffer = skb->data;
> 
> I think you can move this in mt76u_tx_build_sg or remove the if condition in
> mt76u_tx_build_sg()

I'll rename mt76u_tx_build_sg() to mt76u_tx_setup_bufffers() then,
which will more corresponding the what the function do.

Stanislaw

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

* Re: [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly
  2019-03-12 16:27   ` Lorenzo Bianconi
@ 2019-03-13 12:53     ` Stanislaw Gruszka
  0 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-13 12:53 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, Felix Fietkau

On Tue, Mar 12, 2019 at 05:27:43PM +0100, Lorenzo Bianconi wrote:
> I guess here you can do:
> 	e->urb = usb_alloc_urb(0, GFP_KERNEL);
> 	if (!e->urb)
> 		return -ENOMEM;

Done in later patch.

Stanislaw

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

* Re: [RFC 11/12] mt76usb: allocate urb and sg as linear data
  2019-03-12 16:34   ` Lorenzo Bianconi
@ 2019-03-13 12:59     ` Stanislaw Gruszka
  0 siblings, 0 replies; 19+ messages in thread
From: Stanislaw Gruszka @ 2019-03-13 12:59 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, Felix Fietkau

On Tue, Mar 12, 2019 at 05:34:32PM +0100, Lorenzo Bianconi wrote:
> > Alloc sg table at the end of urb structure. This will increase
> > cache usage.
> > 
> 
> I am curious, have you observed any performance improvement doing so?

It's hard to measure that. Stressing net transfer with about 175 Mbit/s
by netperf (what is max I can get) only took about 15% of CPU for me
and net performance fluctuate so CPU pref stats vary too.

> > -	if (dev->usb.sg_en) {
> > -		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> > -				       sizeof(urb->sg), GFP_KERNEL);
FTR: Here is bug it should be sizeof(*urb->sg).

> > -		if (!urb->sg)
> > -			return -ENOMEM;
> > -	}
> > +	usb_init_urb(e->urb);
> > +
> > +	if (dev->usb.sg_en)
> > +		e->urb->sg = (struct scatterlist *)((u8 *)e->urb + sizeof(struct urb));
> 
> You can avoid u8 cast doing:
> (struct scatterlist *)(e->urb + 1)
Cool trick!

Stanislaw


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

end of thread, other threads:[~2019-03-13 12:59 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-12 15:05 [RFC 00/12] mt76usb: some cleanups and optimizations Stanislaw Gruszka
2019-03-12 15:05 ` [RFC 01/12] mt76usb: change mt76u_submit_buf Stanislaw Gruszka
2019-03-12 15:05 ` [RFC 02/12] mt76: remove rx_page_lock Stanislaw Gruszka
2019-03-12 15:05 ` [RFC 03/12] mt76usb: change mt76u_fill_rx_sg arguments Stanislaw Gruszka
2019-03-12 15:05 ` [RFC 04/12] mt76usb: use usb_dev private data Stanislaw Gruszka
2019-03-12 15:05 ` [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds Stanislaw Gruszka
2019-03-12 16:25   ` Lorenzo Bianconi
2019-03-13 12:53     ` Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 06/12] mt76usb: move mt76u_buf->done to queue entry Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly Stanislaw Gruszka
2019-03-12 16:27   ` Lorenzo Bianconi
2019-03-13 12:53     ` Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 08/12] mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 09/12] mt76usb: resue mt76u_urb_alloc for tx Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 10/12] mt76usb: remove unneded sg_init_table Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 11/12] mt76usb: allocate urb and sg as linear data Stanislaw Gruszka
2019-03-12 16:34   ` Lorenzo Bianconi
2019-03-13 12:59     ` Stanislaw Gruszka
2019-03-12 15:06 ` [RFC 12/12] mt76usb: remove queue variable from rx_tasklet Stanislaw Gruszka

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).