mt76: fix concurrent rx calls on A-MPDU release

Add a spinlock in mt76_rx_complete. Without this, multiple stats updates
could happen in parallel, which can lead to deadlocks. There are
probably more corner cases fixed by this change.

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2018-04-17 14:49:29 +02:00
parent 8c92c91abe
commit ca5cc9a478
2 changed files with 4 additions and 0 deletions
+3
View File
@@ -279,6 +279,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
spin_lock_init(&dev->lock);
spin_lock_init(&dev->cc_lock);
spin_lock_init(&dev->rx_lock);
INIT_LIST_HEAD(&dev->txwi_cache);
SET_IEEE80211_DEV(hw, dev->dev);
@@ -561,6 +562,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
if (queue >= 0)
napi = &dev->napi[queue];
spin_lock(&dev->rx_lock);
while ((skb = __skb_dequeue(frames)) != NULL) {
if (mt76_check_ccmp_pn(skb)) {
dev_kfree_skb(skb);
@@ -570,6 +572,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
sta = mt76_rx_convert(skb);
ieee80211_rx_napi(dev->hw, sta, skb, napi);
}
spin_unlock(&dev->rx_lock);
}
void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
+1
View File
@@ -241,6 +241,7 @@ struct mt76_dev {
struct device *dev;
struct net_device napi_dev;
spinlock_t rx_lock;
struct napi_struct napi[__MT_RXQ_MAX];
struct sk_buff_head rx_skb[__MT_RXQ_MAX];