Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
q->head is managed just in mt76u_tx_tasklet and q->queued is updated
holding q->lock

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
Changes since RFC:
- reset done to false in mt76u_tx_tasklet instead of in mt76u_tx_queue_skb
---
 drivers/net/wireless/mediatek/mt76/usb.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index 15aeda0582e7..f06112180694 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -624,28 +624,35 @@ static void mt76u_tx_tasklet(unsigned long data)
        int i;
 
        for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+               u32 n_queued = 0, n_sw_queued = 0;
+               int idx;
+
                sq = &dev->q_tx[i];
                q = sq->q;
 
-               spin_lock_bh(&q->lock);
-               while (true) {
-                       if (!q->entry[q->head].done || !q->queued)
+               while (q->queued > n_queued) {
+                       if (!q->entry[q->head].done)
                                break;
 
                        if (q->entry[q->head].schedule) {
                                q->entry[q->head].schedule = false;
-                               sq->swq_queued--;
+                               n_sw_queued++;
                        }
 
+                       idx = q->head;
                        entry = q->entry[q->head];
                        q->head = (q->head + 1) % q->ndesc;
-                       q->queued--;
+                       n_queued++;
 
-                       spin_unlock_bh(&q->lock);
                        dev->drv->tx_complete_skb(dev, i, &entry);
-                       spin_lock_bh(&q->lock);
+                       q->entry[idx].done = false;
                }
 
+               spin_lock_bh(&q->lock);
+
+               sq->swq_queued -= n_sw_queued;
+               q->queued -= n_queued;
+
                wake = q->stopped && q->queued < q->ndesc - 8;
                if (wake)
                        q->stopped = false;
@@ -741,7 +748,6 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id 
qid,
        if (err < 0)
                return err;
 
-       q->entry[idx].done = false;
        urb = q->entry[idx].urb;
        err = mt76u_tx_setup_buffers(dev, skb, urb);
        if (err < 0)
-- 
2.20.1

Reply via email to