mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 05:16:57 +00:00
wifi: mt76: mt792x: Fix memory leak in SDIO TX path
When tx_prepare_skb() returns an error in the SDIO TX path, the
skb is not freed, leading to a memory leak. This can occur when
zero-length frames (such as WNM NULL frames) are dropped to prevent
potential hardware TX hangs.
Fix this by properly releasing the skb with ieee80211_tx_status_ext()
when tx_prepare_skb() fails.
Fixes: b747fa343817 ("mt76: mt7915: drop zero-length packet to avoid Tx hang")
Signed-off-by: Eason Lai <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -519,6 +519,10 @@ mt76s_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
|
|||||||
enum mt76_txq_id qid, struct sk_buff *skb,
|
enum mt76_txq_id qid, struct sk_buff *skb,
|
||||||
struct mt76_wcid *wcid, struct ieee80211_sta *sta)
|
struct mt76_wcid *wcid, struct ieee80211_sta *sta)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_tx_status status = {
|
||||||
|
.sta = sta,
|
||||||
|
};
|
||||||
|
|
||||||
struct mt76_tx_info tx_info = {
|
struct mt76_tx_info tx_info = {
|
||||||
.skb = skb,
|
.skb = skb,
|
||||||
};
|
};
|
||||||
@@ -531,8 +535,13 @@ mt76s_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
|
|||||||
|
|
||||||
skb->prev = skb->next = NULL;
|
skb->prev = skb->next = NULL;
|
||||||
err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
|
err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
|
status.skb = tx_info.skb;
|
||||||
|
spin_lock_bh(&dev->rx_lock);
|
||||||
|
ieee80211_tx_status_ext(dev->hw, &status);
|
||||||
|
spin_unlock_bh(&dev->rx_lock);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
q->entry[q->head].skb = tx_info.skb;
|
q->entry[q->head].skb = tx_info.skb;
|
||||||
q->entry[q->head].buf_sz = len;
|
q->entry[q->head].buf_sz = len;
|
||||||
|
|||||||
Reference in New Issue
Block a user