提交 c3d7c82a 编写于 作者: F Felix Fietkau 提交者: Kalle Valo

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: NFelix Fietkau <nbd@nbd.name>
Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
上级 97389373
...@@ -561,6 +561,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, ...@@ -561,6 +561,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
if (queue >= 0) if (queue >= 0)
napi = &dev->napi[queue]; napi = &dev->napi[queue];
spin_lock(&dev->rx_lock);
while ((skb = __skb_dequeue(frames)) != NULL) { while ((skb = __skb_dequeue(frames)) != NULL) {
if (mt76_check_ccmp_pn(skb)) { if (mt76_check_ccmp_pn(skb)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -570,6 +571,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, ...@@ -570,6 +571,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
sta = mt76_rx_convert(skb); sta = mt76_rx_convert(skb);
ieee80211_rx_napi(dev->hw, sta, skb, napi); 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) void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
......
...@@ -241,6 +241,7 @@ struct mt76_dev { ...@@ -241,6 +241,7 @@ struct mt76_dev {
struct device *dev; struct device *dev;
struct net_device napi_dev; struct net_device napi_dev;
spinlock_t rx_lock;
struct napi_struct napi[__MT_RXQ_MAX]; struct napi_struct napi[__MT_RXQ_MAX];
struct sk_buff_head rx_skb[__MT_RXQ_MAX]; struct sk_buff_head rx_skb[__MT_RXQ_MAX];
......
...@@ -645,6 +645,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) ...@@ -645,6 +645,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
dev->mt76.drv = &drv_ops; dev->mt76.drv = &drv_ops;
mutex_init(&dev->mutex); mutex_init(&dev->mutex);
spin_lock_init(&dev->irq_lock); spin_lock_init(&dev->irq_lock);
spin_lock_init(&dev->mt76.rx_lock);
return dev; return dev;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册