Reduces lock contention on enqueue/dequeue of iTXQ packets

Signed-off-by: Felix Fietkau <[email protected]>
---
 net/mac80211/tx.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8127e43e12b1..f85344c9af62 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3544,6 +3544,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw 
*hw,
        ieee80211_tx_result r;
        struct ieee80211_vif *vif = txq->vif;
 
+begin:
        spin_lock_bh(&fq->lock);
 
        if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
@@ -3560,11 +3561,12 @@ struct sk_buff *ieee80211_tx_dequeue(struct 
ieee80211_hw *hw,
        if (skb)
                goto out;
 
-begin:
        skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
        if (!skb)
                goto out;
 
+       spin_unlock_bh(&fq->lock);
+
        hdr = (struct ieee80211_hdr *)skb->data;
        info = IEEE80211_SKB_CB(skb);
 
@@ -3610,8 +3612,11 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw 
*hw,
 
                skb = __skb_dequeue(&tx.skbs);
 
-               if (!skb_queue_empty(&tx.skbs))
+               if (!skb_queue_empty(&tx.skbs)) {
+                       spin_lock_bh(&fq->lock);
                        skb_queue_splice_tail(&tx.skbs, &txqi->frags);
+                       spin_unlock_bh(&fq->lock);
+               }
        }
 
        if (skb_has_frag_list(skb) &&
@@ -3650,6 +3655,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw 
*hw,
        }
 
        IEEE80211_SKB_CB(skb)->control.vif = vif;
+       return skb;
 
 out:
        spin_unlock_bh(&fq->lock);
-- 
2.17.0

Reply via email to