aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2019-03-16 18:06:33 +0100
committerJohannes Berg <johannes.berg@intel.com>2019-04-26 13:02:11 +0200
commitded4698b58cb23c22b0dcbd829ced19ce4e6ce02 (patch)
tree9a386c23393fb39600f5ed1a5763e7285143502d /net/mac80211
parentmac80211: calculate hash for fq without holding fq->lock in itxq enqueue (diff)
downloadlinux-dev-ded4698b58cb23c22b0dcbd829ced19ce4e6ce02.tar.xz
linux-dev-ded4698b58cb23c22b0dcbd829ced19ce4e6ce02.zip
mac80211: run late dequeue late tx handlers without holding fq->lock
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>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/tx.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2c0fec888021..a3c6053cdffe 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -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);