2021-12-07 17:05:07

by Deren Wu

[permalink] [raw]
Subject: [PATCH] mt76: mt7921: fix network buffer leak by txs missing

From: Deren Wu <[email protected]>

TXS in mt7921 may be forwared to tx_done event. Should try to catch
TXS information in tx_done event as well.

Signed-off-by: Deren Wu <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7921/mac.c | 2 +-
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 17 ++++++++++++
.../net/wireless/mediatek/mt76/mt7921/mcu.h | 27 +++++++++++++++++++
.../wireless/mediatek/mt76/mt7921/mt7921.h | 1 +
4 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index edf54b192f37..2514708e9ac8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -1150,7 +1150,7 @@ mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid,
return !!skb;
}

-static void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
+void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
{
struct mt7921_sta *msta = NULL;
struct mt76_wcid *wcid;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 1227d626e9d3..8f58af4e29c6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -418,6 +418,20 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
trace_lp_event(dev, event->state);
}

+static void
+mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
+{
+ struct mt7921_mcu_tx_done_event *event;
+
+ skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
+ event = (struct mt7921_mcu_tx_done_event *)skb->data;
+
+ if (event->pid < MT_PACKET_ID_FIRST)
+ return;
+
+ mt7921_mac_add_txs(dev, event->txs);
+}
+
static void
mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
{
@@ -445,6 +459,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
case MCU_EVENT_LP_INFO:
mt7921_mcu_low_power_event(dev, skb);
break;
+ case MCU_EVENT_TX_DONE:
+ mt7921_mcu_tx_done_event(dev, skb);
+ break;
default:
break;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
index edc0c73f8c01..821af6e8d99a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
@@ -91,6 +91,33 @@ enum {
MCU_EVENT_COREDUMP = 0xf0,
};

+struct mt7921_mcu_tx_done_event {
+ u8 pid;
+ u8 status;
+ u16 seq;
+
+ u8 wlan_idx;
+ u8 tx_cnt;
+ u16 tx_rate;
+
+ u8 flag;
+ u8 tid;
+ u8 rsp_rate;
+ u8 mcs;
+
+ u8 bw;
+ u8 tx_pwr;
+ u8 reason;
+ u8 rsv0[1];
+
+ u32 delay;
+ u32 timestamp;
+ u32 applied_flag;
+ u8 txs[28];
+
+ u8 rsv1[32];
+} __packed;
+
/* ext event table */
enum {
MCU_EXT_EVENT_RATE_REPORT = 0x87,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index d6b823713ba3..96647801850a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -464,4 +464,5 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct mt76_tx_info *tx_info);
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
+void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
#endif
--
2.18.0



2021-12-07 20:11:50

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH] mt76: mt7921: fix network buffer leak by txs missing

> From: Deren Wu <[email protected]>
>
> TXS in mt7921 may be forwared to tx_done event. Should try to catch
> TXS information in tx_done event as well.
>
> Signed-off-by: Deren Wu <[email protected]>
> ---
> .../net/wireless/mediatek/mt76/mt7921/mac.c | 2 +-
> .../net/wireless/mediatek/mt76/mt7921/mcu.c | 17 ++++++++++++
> .../net/wireless/mediatek/mt76/mt7921/mcu.h | 27 +++++++++++++++++++
> .../wireless/mediatek/mt76/mt7921/mt7921.h | 1 +
> 4 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> index edf54b192f37..2514708e9ac8 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> @@ -1150,7 +1150,7 @@ mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid,
> return !!skb;
> }
>
> -static void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
> +void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
> {
> struct mt7921_sta *msta = NULL;
> struct mt76_wcid *wcid;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
> index 1227d626e9d3..8f58af4e29c6 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
> @@ -418,6 +418,20 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
> trace_lp_event(dev, event->state);
> }
>
> +static void
> +mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
> +{
> + struct mt7921_mcu_tx_done_event *event;
> +
> + skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
> + event = (struct mt7921_mcu_tx_done_event *)skb->data;
> +
> + if (event->pid < MT_PACKET_ID_FIRST)
> + return;

I guess we do not need it since it is already checked in mt7921_mac_add_txs

> +
> + mt7921_mac_add_txs(dev, event->txs);
> +}
> +
> static void
> mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
> {
> @@ -445,6 +459,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
> case MCU_EVENT_LP_INFO:
> mt7921_mcu_low_power_event(dev, skb);
> break;
> + case MCU_EVENT_TX_DONE:
> + mt7921_mcu_tx_done_event(dev, skb);
> + break;
> default:
> break;
> }
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
> index edc0c73f8c01..821af6e8d99a 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
> @@ -91,6 +91,33 @@ enum {
> MCU_EVENT_COREDUMP = 0xf0,
> };
>
> +struct mt7921_mcu_tx_done_event {
> + u8 pid;
> + u8 status;
> + u16 seq;
> +
> + u8 wlan_idx;
> + u8 tx_cnt;
> + u16 tx_rate;

can you please fix endianness of mt7921_mcu_tx_done_event?

Regards,
Lorenzo

> +
> + u8 flag;
> + u8 tid;
> + u8 rsp_rate;
> + u8 mcs;
> +
> + u8 bw;
> + u8 tx_pwr;
> + u8 reason;
> + u8 rsv0[1];
> +
> + u32 delay;
> + u32 timestamp;
> + u32 applied_flag;
> + u8 txs[28];
> +
> + u8 rsv1[32];
> +} __packed;
> +
> /* ext event table */
> enum {
> MCU_EXT_EVENT_RATE_REPORT = 0x87,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> index d6b823713ba3..96647801850a 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> @@ -464,4 +464,5 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
> struct mt76_tx_info *tx_info);
> void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
> bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
> +void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
> #endif
> --
> 2.18.0
>


Attachments:
(No filename) (3.78 kB)
signature.asc (228.00 B)
Download all attachments