[][MAC80211][wed][fix potential memory leakage]
[Description]
Fix potential memory leakage,
release rx queue pages in mt7915_mmio_wed_release_rx_buf,
recycle rxwi when mt76_dma_add_buf() call fails.
[Release-log]
N/A
Change-Id: Iddf3c8809d6b6ceb91cc50749eb53de988701707
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6931723
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3013-mt76-mt7915-wed-fix-potential-memory-leakage.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3013-mt76-mt7915-wed-fix-potential-memory-leakage.patch
new file mode 100644
index 0000000..ee28783
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3013-mt76-mt7915-wed-fix-potential-memory-leakage.patch
@@ -0,0 +1,86 @@
+From fd959ab8b2d9b7ff275bbd8e90f26905a4920583 Mon Sep 17 00:00:00 2001
+From: Sujuan Chen <sujuan.chen@mediatek.com>
+Date: Fri, 16 Dec 2022 12:16:40 +0800
+Subject: [PATCH] mt76: mt7915: wed: fix potential memory leakage
+
+release rx queue pages in mt7915_mmio_wed_release_rx_buf.
+recycle rxwi when mt76_dma_add_buf() call fails.
+
+Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
+---
+ dma.c | 16 ++++++++++------
+ mt7915/mmio.c | 15 +++++++++++++++
+ 2 files changed, 25 insertions(+), 6 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 8b9fdfc..08169ba 100644
+--- a/dma.c
++++ b/dma.c
+@@ -633,9 +633,11 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ qbuf.len = len - offset;
+ qbuf.skip_unmap = false;
+ if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, NULL, r) < 0) {
++ mt76_put_rxwi(dev, r);
+ dma_unmap_single(dev->dma_dev, addr, len,
+ DMA_FROM_DEVICE);
+- skb_free_frag(buf);
++ if (!skip_alloc)
++ skb_free_frag(buf);
+ break;
+ }
+ frames++;
+@@ -758,12 +760,14 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+ } while (1);
+ spin_unlock_bh(&q->lock);
+
+- if (!q->rx_page.va)
+- return;
++ if (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) != MT76_WED_Q_RX) {
++ if (!q->rx_page.va)
++ return;
+
+- page = virt_to_page(q->rx_page.va);
+- __page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
+- memset(&q->rx_page, 0, sizeof(q->rx_page));
++ page = virt_to_page(q->rx_page.va);
++ __page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
++ memset(&q->rx_page, 0, sizeof(q->rx_page));
++ }
+ }
+
+ static void
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 6f80f07..63388fc 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -621,12 +621,27 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+
+ mt76_free_pending_rxwi(&dev->mt76);
+
++ mt76_for_each_q_rx(&dev->mt76, i) {
++ if (FIELD_GET(MT_QFLAG_WED_TYPE,
++ dev->mt76.q_rx[i].flags) == MT76_WED_Q_RX) {
++ struct mt76_queue *q = &dev->mt76.q_rx[i];
++
++ if (!q->rx_page.va)
++ continue;
++
++ page = virt_to_page(q->rx_page.va);
++ __page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
++ memset(&q->rx_page, 0, sizeof(q->rx_page));
++ }
++ }
++
+ if (!wed->rx_buf_ring.rx_page.va)
+ return;
+
+ page = virt_to_page(wed->rx_buf_ring.rx_page.va);
+ __page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias);
+ memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page));
++
+ }
+
+ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+--
+2.18.0
+