All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] mt76: add missing locking around ampdu action
@ 2019-10-07 14:10 Felix Fietkau
  2019-10-07 14:10 ` [PATCH 2/4] mt76: drop rcu read lock in mt76_rx_aggr_stop Felix Fietkau
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Felix Fietkau @ 2019-10-07 14:10 UTC (permalink / raw)
  To: linux-wireless

This is needed primarily to avoid races in dealing with rx aggregation
related data structures

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/mt7603/main.c  | 2 ++
 drivers/net/wireless/mediatek/mt76/mt7615/main.c  | 2 ++
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 180eb6bb781a..c4dac556fb2e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -569,6 +569,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	mtxq = (struct mt76_txq *)txq->drv_priv;
 
+	mutex_lock(&dev->mt76.mutex);
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
 		mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
@@ -598,6 +599,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 		break;
 	}
+	mutex_unlock(&dev->mt76.mutex);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 942076b6d1ad..d9f4d425424c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -483,6 +483,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	mtxq = (struct mt76_txq *)txq->drv_priv;
 
+	mutex_lock(&dev->mt76.mutex);
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
 		mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
@@ -513,6 +514,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 		break;
 	}
+	mutex_unlock(&dev->mt76.mutex);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index f5695ebdb225..bb7edf288597 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -372,6 +372,7 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	mtxq = (struct mt76_txq *)txq->drv_priv;
 
+	mutex_lock(&dev->mt76.mutex);
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
 		mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid,
@@ -401,6 +402,7 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 		break;
 	}
+	mutex_unlock(&dev->mt76.mutex);
 
 	return 0;
 }
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/4] mt76: drop rcu read lock in mt76_rx_aggr_stop
  2019-10-07 14:10 [PATCH 1/4] mt76: add missing locking around ampdu action Felix Fietkau
@ 2019-10-07 14:10 ` Felix Fietkau
  2019-10-07 14:10 ` [PATCH 3/4] mt76: fix aggregation stop issue Felix Fietkau
  2019-10-07 14:10 ` [PATCH 4/4] mt76: avoid enabling interrupt if NAPI poll is still pending Felix Fietkau
  2 siblings, 0 replies; 4+ messages in thread
From: Felix Fietkau @ 2019-10-07 14:10 UTC (permalink / raw)
  To: linux-wireless

A rcu read locked section is not allowed to sleep, and the rcu lock here
isn't actually necessary, because we're holding dev->mutex.
Fixes an issue when the tid work item is still running while freeing
a station or stopping the aggregation session

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/agg-rx.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c
index 2276fd4e9ec3..b05d439dca3b 100644
--- a/drivers/net/wireless/mediatek/mt76/agg-rx.c
+++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
@@ -277,17 +277,13 @@ static void mt76_rx_aggr_shutdown(struct mt76_dev *dev, struct mt76_rx_tid *tid)
 
 void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tidno)
 {
-	struct mt76_rx_tid *tid;
-
-	rcu_read_lock();
+	struct mt76_rx_tid *tid = NULL;
 
-	tid = rcu_dereference(wcid->aggr[tidno]);
+	rcu_swap_protected(wcid->aggr[tidno], tid,
+			   lockdep_is_held(&dev->mutex));
 	if (tid) {
-		rcu_assign_pointer(wcid->aggr[tidno], NULL);
 		mt76_rx_aggr_shutdown(dev, tid);
 		kfree_rcu(tid, rcu_head);
 	}
-
-	rcu_read_unlock();
 }
 EXPORT_SYMBOL_GPL(mt76_rx_aggr_stop);
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/4] mt76: fix aggregation stop issue
  2019-10-07 14:10 [PATCH 1/4] mt76: add missing locking around ampdu action Felix Fietkau
  2019-10-07 14:10 ` [PATCH 2/4] mt76: drop rcu read lock in mt76_rx_aggr_stop Felix Fietkau
@ 2019-10-07 14:10 ` Felix Fietkau
  2019-10-07 14:10 ` [PATCH 4/4] mt76: avoid enabling interrupt if NAPI poll is still pending Felix Fietkau
  2 siblings, 0 replies; 4+ messages in thread
From: Felix Fietkau @ 2019-10-07 14:10 UTC (permalink / raw)
  To: linux-wireless

Cancel the workqueue after the tid has been cleaned up, in order to
avoid a possible rescheduling from within the work function.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/agg-rx.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c
index b05d439dca3b..53b5a4b2dcc5 100644
--- a/drivers/net/wireless/mediatek/mt76/agg-rx.c
+++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
@@ -130,8 +130,10 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
 		return;
 
 	spin_lock_bh(&tid->lock);
-	mt76_rx_aggr_release_frames(tid, frames, seqno);
-	mt76_rx_aggr_release_head(tid, frames);
+	if (!tid->stopped) {
+		mt76_rx_aggr_release_frames(tid, frames, seqno);
+		mt76_rx_aggr_release_head(tid, frames);
+	}
 	spin_unlock_bh(&tid->lock);
 }
 
@@ -257,8 +259,6 @@ static void mt76_rx_aggr_shutdown(struct mt76_dev *dev, struct mt76_rx_tid *tid)
 	u8 size = tid->size;
 	int i;
 
-	cancel_delayed_work_sync(&tid->reorder_work);
-
 	spin_lock_bh(&tid->lock);
 
 	tid->stopped = true;
@@ -273,6 +273,8 @@ static void mt76_rx_aggr_shutdown(struct mt76_dev *dev, struct mt76_rx_tid *tid)
 	}
 
 	spin_unlock_bh(&tid->lock);
+
+	cancel_delayed_work_sync(&tid->reorder_work);
 }
 
 void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tidno)
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 4/4] mt76: avoid enabling interrupt if NAPI poll is still pending
  2019-10-07 14:10 [PATCH 1/4] mt76: add missing locking around ampdu action Felix Fietkau
  2019-10-07 14:10 ` [PATCH 2/4] mt76: drop rcu read lock in mt76_rx_aggr_stop Felix Fietkau
  2019-10-07 14:10 ` [PATCH 3/4] mt76: fix aggregation stop issue Felix Fietkau
@ 2019-10-07 14:10 ` Felix Fietkau
  2 siblings, 0 replies; 4+ messages in thread
From: Felix Fietkau @ 2019-10-07 14:10 UTC (permalink / raw)
  To: linux-wireless

if napi_complete() returns false, it means that polling is still pending.
Interrupts should not fire until the polling is no longer scheduled

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 drivers/net/wireless/mediatek/mt76/dma.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index e2ce59b260c1..4da7cffbab29 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -537,10 +537,8 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget)
 
 	rcu_read_unlock();
 
-	if (done < budget) {
-		napi_complete(napi);
+	if (done < budget && napi_complete(napi))
 		dev->drv->rx_poll_complete(dev, qid);
-	}
 
 	return done;
 }
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-07 14:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-07 14:10 [PATCH 1/4] mt76: add missing locking around ampdu action Felix Fietkau
2019-10-07 14:10 ` [PATCH 2/4] mt76: drop rcu read lock in mt76_rx_aggr_stop Felix Fietkau
2019-10-07 14:10 ` [PATCH 3/4] mt76: fix aggregation stop issue Felix Fietkau
2019-10-07 14:10 ` [PATCH 4/4] mt76: avoid enabling interrupt if NAPI poll is still pending Felix Fietkau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.