mac80211: run late dequeue late tx handlers without holding fq->lock
authorFelix Fietkau <nbd@nbd.name>
Sat, 16 Mar 2019 17:06:33 +0000 (18:06 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 26 Apr 2019 11:02:11 +0000 (13:02 +0200)
Reduces lock contention on enqueue/dequeue of iTXQ packets

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/tx.c

index 2c0fec8..a3c6053 100644 (file)
@@ -3535,6 +3535,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) ||
@@ -3551,11 +3552,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);
 
@@ -3600,8 +3602,11 @@ begin:
 
                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) &&
@@ -3640,6 +3645,7 @@ begin:
        }
 
        IEEE80211_SKB_CB(skb)->control.vif = vif;
+       return skb;
 
 out:
        spin_unlock_bh(&fq->lock);