diff options
author | Felix Fietkau <nbd@nbd.name> | 2023-08-29 10:39:53 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2023-09-30 20:03:03 +0200 |
commit | 0335c034e7265d36d956e806f33202c94a8a9860 (patch) | |
tree | 135dabd2b968ab97d046a84aa39df63151fa20b1 /drivers/net/wireless/mediatek/mt76/mt76.h | |
parent | debd133ab2e2e06989c24e1a72be2b7997f30456 (diff) |
wifi: mt76: fix race condition related to checking tx queue fill status
When drv_tx calls race against local tx scheduling, the queue fill status checks
can potentially race, leading to dma queue entries being overwritten.
Fix this by deferring packets from drv_tx calls to the tx worker, in order to
ensure that all regular queue tx comes from the same context.
Reported-by: Ryder Lee <Ryder.Lee@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt76.h')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76.h | 24 |
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index e8757865a3d0..9265e1b84b4f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -334,6 +334,9 @@ struct mt76_wcid { u32 tx_info; bool sw_iv; + struct list_head tx_list; + struct sk_buff_head tx_pending; + struct list_head list; struct idr pktid; @@ -719,6 +722,8 @@ struct mt76_phy { unsigned long state; u8 band_idx; + spinlock_t tx_lock; + struct list_head tx_list; struct mt76_queue *q_tx[__MT_TXQ_MAX]; struct cfg80211_chan_def chandef; @@ -1598,22 +1603,7 @@ mt76_token_put(struct mt76_dev *dev, int token) return txwi; } -static inline void mt76_packet_id_init(struct mt76_wcid *wcid) -{ - INIT_LIST_HEAD(&wcid->list); - idr_init(&wcid->pktid); -} - -static inline void -mt76_packet_id_flush(struct mt76_dev *dev, struct mt76_wcid *wcid) -{ - struct sk_buff_head list; - - mt76_tx_status_lock(dev, &list); - mt76_tx_status_skb_get(dev, wcid, -1, &list); - mt76_tx_status_unlock(dev, &list); - - idr_destroy(&wcid->pktid); -} +void mt76_wcid_init(struct mt76_wcid *wcid); +void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid); #endif |