2019-03-21 15:25:50

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 00/12] mt76usb: some cleanups and optimizations

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.

RFC -> v1:
- introduce mt76u_tx_setup_buffers
- calculate data_len differently
- fix *usb->sg bug on intermediate patches
- use (struct scatterlist *)(e->urb + 1) trick

Rebased on latest tree and
[PATCH v2 00/12] mt76x02: AP support for USB with PS
https://lore.kernel.org/linux-wireless/[email protected]/

Not rebased on
[PATCH 1/6] mt76: use mac80211 txq scheduling
https://lore.kernel.org/linux-wireless/[email protected]/
It easer to rebase '[PATCH 5/6] mt76: move tx tasklet to struct mt76_dev'
from that set of top of my 2 pending sets.

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 +-
.../net/wireless/mediatek/mt76/mt76x0/usb.c | 2 +-
.../net/wireless/mediatek/mt76/mt76x2/usb.c | 4 +-
drivers/net/wireless/mediatek/mt76/usb.c | 243 ++++++++----------
4 files changed, 118 insertions(+), 146 deletions(-)

--
2.20.1



2019-03-21 15:25:54

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 01/12] mt76usb: change mt76u_submit_buf

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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 7b62bd63d395..ac4608f1422d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -394,18 +394,6 @@ mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
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;
}
--
2.20.1


2019-03-21 15:25:57

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 02/12] mt76: remove rx_page_lock

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 <[email protected]>
---
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 c163ba68647e..67ff9bce94c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -138,7 +138,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 ac4608f1422d..3f21599d52de 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -292,7 +292,6 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
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 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
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)
--
2.20.1


2019-03-21 15:25:59

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 03/12] mt76usb: change mt76u_fill_rx_sg arguments

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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 3f21599d52de..56e7a2ca8930 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -285,11 +285,13 @@ mt76u_set_endpoints(struct usb_interface *intf,
}

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 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
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 @@ mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
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;
--
2.20.1


2019-03-21 15:26:10

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 04/12] mt76usb: use usb_dev private data

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 <[email protected]>
---
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 67ff9bce94c0..ab93d7e94b36 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -90,7 +90,6 @@ struct mt76_tx_info {
};

struct mt76u_buf {
- struct mt76_dev *dev;
struct urb *urb;
size_t len;
void *buf;
@@ -763,8 +762,7 @@ static inline int
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 cf97bbd89485..c27769f062af 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 asic_rev, 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 1f0b1bebed79..b112b2f8342a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -49,7 +49,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;
@@ -59,6 +59,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 56e7a2ca8930..28552c622fee 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 @@ mt76u_rd_rp(struct mt76_dev *dev, u32 base,

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 @@ mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
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 @@ mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
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)
--
2.20.1


2019-03-21 15:26:18

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 05/12] mt76usb: remove mt76u_buf redundant fileds

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 -
drivers/net/wireless/mediatek/mt76/usb.c | 56 +++++++++++++----------
2 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index ab93d7e94b36..4cb01502f5b1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -91,8 +91,6 @@ struct mt76_tx_info {

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 28552c622fee..8bb660e0d65a 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -315,7 +315,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
}

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 @@ mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
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 @@ mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
{
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 @@ mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
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 @@ mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
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,8 +428,9 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct mt76u_buf *buf)
{
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;
- int data_len, len, nsgs = 1;
+ u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
+ int data_len = urb->num_sgs ? urb->sg[0].length : urb->actual_length;
+ int len, nsgs = 1;
struct sk_buff *skb;

if (!test_bit(MT76_STATE_INITIALIZED, &dev->state))
@@ -437,7 +440,6 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct mt76u_buf *buf)
if (len < 0)
return 0;

- data_len = urb->num_sgs ? urb->sg[0].length : buf->len;
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;
@@ -701,15 +703,21 @@ static void mt76u_complete_tx(struct urb *urb)
}

static int
-mt76u_tx_build_sg(struct mt76_dev *dev, struct sk_buff *skb,
- struct urb *urb)
+mt76u_tx_setup_buffers(struct mt76_dev *dev, struct sk_buff *skb,
+ struct urb *urb)
{
- if (!dev->usb.sg_en)
- return 0;
+ urb->transfer_buffer_length = skb->len;

- sg_init_table(urb->sg, MT_SG_MAX_SIZE);
- urb->num_sgs = skb_to_sgvec(skb, urb->sg, 0, skb->len);
- return urb->num_sgs;
+ if (!dev->usb.sg_en) {
+ urb->transfer_buffer = skb->data;
+ return 0;
+ } else {
+ sg_init_table(urb->sg, MT_SG_MAX_SIZE);
+ urb->num_sgs = skb_to_sgvec(skb, urb->sg, 0, skb->len);
+ if (urb->num_sgs == 0)
+ return -ENOMEM;
+ return urb->num_sgs;
+ }
}

static int
@@ -731,14 +739,12 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
return err;

buf = &q->entry[idx].ubuf;
- buf->buf = skb->data;
- buf->len = skb->len;
- buf->done = false;
-
- err = mt76u_tx_build_sg(dev, skb, buf->urb);
+ err = mt76u_tx_setup_buffers(dev, skb, buf->urb);
if (err < 0)
return err;

+ buf->done = false;
+
mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
buf, mt76u_complete_tx, buf);

--
2.20.1


2019-03-21 15:26:23

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 06/12] mt76usb: move mt76u_buf->done to queue entry

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 <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
drivers/net/wireless/mediatek/mt76/usb.c | 13 +++++--------
2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 4cb01502f5b1..508f21926025 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -91,7 +91,6 @@ struct mt76_tx_info {

struct mt76u_buf {
struct urb *urb;
- bool done;
};

struct mt76_queue_entry {
@@ -105,6 +104,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 8bb660e0d65a..bea7379d572b 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);
}
@@ -738,15 +736,14 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
if (err < 0)
return err;

+ q->entry[idx].done = false;
buf = &q->entry[idx].ubuf;
err = mt76u_tx_setup_buffers(dev, skb, buf->urb);
if (err < 0)
return err;

- 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;
--
2.20.1


2019-03-21 15:26:25

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 07/12] mt76usb: remove mt76u_buf and use urb directly

Put urb pointer in mt76_queue_entry directly instead of mt76u_buf
structure.

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 6 +-
drivers/net/wireless/mediatek/mt76/usb.c | 130 +++++++++++-----------
2 files changed, 64 insertions(+), 72 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 508f21926025..efe338cc9829 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -89,10 +89,6 @@ struct mt76_tx_info {
u32 info;
};

-struct mt76u_buf {
- struct urb *urb;
-};
-
struct mt76_queue_entry {
union {
void *buf;
@@ -100,7 +96,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 bea7379d572b..48bbb4e3db2f 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -283,12 +283,11 @@ mt76u_set_endpoints(struct usb_interface *intf,
}

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 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,

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 @@ mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
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 = urb->num_sgs ? urb->sg[0].length : urb->actual_length;
int len, nsgs = 1;
@@ -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)
@@ -724,7 +721,7 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
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;

@@ -737,13 +734,13 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
return err;

q->entry[idx].done = false;
- buf = &q->entry[idx].ubuf;
- err = mt76u_tx_setup_buffers(dev, skb, buf->urb);
+ urb = q->entry[idx].urb;
+ err = mt76u_tx_setup_buffers(dev, skb, urb);
if (err < 0)
return err;

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;
@@ -754,14 +751,14 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,

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);
@@ -776,7 +773,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;

@@ -804,19 +801,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)
continue;

- buf->urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
- sizeof(struct scatterlist),
- GFP_KERNEL);
- if (!buf->urb->sg)
+ urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
+ sizeof(struct scatterlist),
+ 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);
}
}

--
2.20.1


2019-03-21 15:26:28

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 08/12] mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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 48bbb4e3db2f..10507a26d598 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -283,12 +283,10 @@ mt76u_set_endpoints(struct usb_interface *intf,
}

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 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
}

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 @@ mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
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 @@ mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
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;
}
--
2.20.1


2019-03-21 15:26:31

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 09/12] mt76usb: resue mt76u_urb_alloc for tx

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
drivers/net/wireless/mediatek/mt76/usb.c | 35 ++++++++++++------------
1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 10507a26d598..7cefa4fe8251 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -352,7 +352,19 @@ mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
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;
}
@@ -770,9 +782,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);
@@ -798,19 +809,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)
- continue;
-
- urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
- sizeof(struct scatterlist),
- GFP_KERNEL);
- if (!urb->sg)
- return -ENOMEM;
+ err = mt76u_urb_alloc(dev, &q->entry[j]);
+ if (err < 0)
+ return err;
}
}
return 0;
--
2.20.1


2019-03-21 15:26:35

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 10/12] mt76usb: remove unneded sg_init_table

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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 7cefa4fe8251..0ae69c2fedaf 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -348,8 +348,6 @@ mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
sizeof(*urb->sg), GFP_KERNEL);
if (!urb->sg)
return -ENOMEM;
-
- sg_init_table(urb->sg, MT_SG_MAX_SIZE);
}

return 0;
--
2.20.1


2019-03-21 15:26:37

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 11/12] mt76usb: allocate urb and sg as linear data

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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 0ae69c2fedaf..a80d6abee748 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -336,19 +336,19 @@ mt76u_refill_rx(struct mt76_dev *dev, struct urb *urb, int nsgs, gfp_t gfp)
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 *)(e->urb + 1);

return 0;
}
--
2.20.1


2019-03-21 15:26:41

by Stanislaw Gruszka

[permalink] [raw]
Subject: [PATCH 12/12] mt76usb: remove queue variable from rx_tasklet

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

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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 a80d6abee748..a3acc070063a 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -398,8 +398,9 @@ mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
}

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 @@ mt76u_submit_rx_buf(struct mt76_dev *dev, 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;

--
2.20.1


2019-03-22 10:10:47

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 03/12] mt76usb: change mt76u_fill_rx_sg arguments

> We do not need to pass len and sglen to the function.
> Additionally pass gfp to control allocation context.
>
> Signed-off-by: Stanislaw Gruszka <[email protected]>
> ---
> 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 3f21599d52de..56e7a2ca8930 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -285,11 +285,13 @@ mt76u_set_endpoints(struct usb_interface *intf,
> }
>
> 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;
> +

please drop newline here

> int i;
>
> for (i = 0; i < nsgs; i++) {
> @@ -297,7 +299,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
> 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 @@ mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
> 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;
> --
> 2.20.1
>


Attachments:
(No filename) (1.71 kB)
signature.asc (228.00 B)
Download all attachments

2019-03-22 11:02:32

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 00/12] mt76usb: some cleanups and optimizations

> 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.
>
> RFC -> v1:
> - introduce mt76u_tx_setup_buffers
> - calculate data_len differently
> - fix *usb->sg bug on intermediate patches
> - use (struct scatterlist *)(e->urb + 1) trick
>
> Rebased on latest tree and
> [PATCH v2 00/12] mt76x02: AP support for USB with PS
> https://lore.kernel.org/linux-wireless/[email protected]/
>
> Not rebased on
> [PATCH 1/6] mt76: use mac80211 txq scheduling
> https://lore.kernel.org/linux-wireless/[email protected]/
> It easer to rebase '[PATCH 5/6] mt76: move tx tasklet to struct mt76_dev'
> from that set of top of my 2 pending sets.

LGTM

Acked-by: Lorenzo Bianconi <[email protected]>

>
> 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 +-
> .../net/wireless/mediatek/mt76/mt76x0/usb.c | 2 +-
> .../net/wireless/mediatek/mt76/mt76x2/usb.c | 4 +-
> drivers/net/wireless/mediatek/mt76/usb.c | 243 ++++++++----------
> 4 files changed, 118 insertions(+), 146 deletions(-)
>
> --
> 2.20.1
>


Attachments:
(No filename) (1.73 kB)
signature.asc (228.00 B)
Download all attachments

2019-03-22 12:45:56

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: [PATCH 03/12] mt76usb: change mt76u_fill_rx_sg arguments

On Fri, Mar 22, 2019 at 11:10:40AM +0100, Lorenzo Bianconi wrote:
> > We do not need to pass len and sglen to the function.
> > Additionally pass gfp to control allocation context.
> >
> > Signed-off-by: Stanislaw Gruszka <[email protected]>
> > ---
> > 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 3f21599d52de..56e7a2ca8930 100644
> > --- a/drivers/net/wireless/mediatek/mt76/usb.c
> > +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> > @@ -285,11 +285,13 @@ mt76u_set_endpoints(struct usb_interface *intf,
> > }
> >
> > 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;
> > +
>
> please drop newline here

Not sure where it came from, but is already removed on patch 8.

Stanislaw

2019-03-24 07:25:55

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 00/12] mt76usb: some cleanups and optimizations

On 2019-03-21 16:25, Stanislaw Gruszka wrote:
> 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.
>
> RFC -> v1:
> - introduce mt76u_tx_setup_buffers
> - calculate data_len differently
> - fix *usb->sg bug on intermediate patches
> - use (struct scatterlist *)(e->urb + 1) trick
>
> Rebased on latest tree and
> [PATCH v2 00/12] mt76x02: AP support for USB with PS
> https://lore.kernel.org/linux-wireless/[email protected]/
>
> Not rebased on
> [PATCH 1/6] mt76: use mac80211 txq scheduling
> https://lore.kernel.org/linux-wireless/[email protected]/
> It easer to rebase '[PATCH 5/6] mt76: move tx tasklet to struct mt76_dev'
> from that set of top of my 2 pending sets.
Applied, thanks.

- Felix