From: netdev-bot+sashiko@kernel.org
To: hujy652@gmail.com
Cc: nbd@nbd.name, lorenzo@kernel.org, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com, matthias.bgg@gmail.com,
angelogioacchino.delregno@collabora.com,
sujuan.chen@mediatek.com, rex.lu@mediatek.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org
Subject: Re: [PATCH net v5 3/5] net: ethernet: mtk_wed: free up rings during detach
Date: Tue, 20 Oct 2026 10:10:42 +0000 [thread overview]
Message-ID: <179249104276.3135.12420565113536395663@kernel.org> (raw)
In-Reply-To: <20261016-wedfix-v5-3-8b02e78fd34f@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider.
Critical: 0 · High: 1 · Medium: 2 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [High] Copy-paste bug in the new rx_ring cleanup loop in
mtk_wed_free_rx_rings()…
- [Medium] The new flag gating in mtk_wed_free_tx_rings() causes a leak
on partial setup failure.
- [Medium] The patch now frees the rx_ring descriptor memory in
__mtk_wed_detach() → mtk_wed_free_rx_rings(), but WED never disables…
--
net: ethernet: mtk_wed: free up rings during detach
This commit adds frees for rx_ring and tx_wdma in mtk_wed_free_rx_rings()
during __mtk_wed_detach(). It also sets MTK_WED_RING_CONFIGURED in the
tx/rx ring and wdma tx/rx ring setup paths, and only frees rings that have
that flag set.
Link: https://github.com/mediatek/mtk-openwrt-feeds/blob/main/25.12/files/target/linux/mediatek/patches-6.12/999-wed-04-Fix-reinsert-wifi-module-cause-memory-leak-issue.patch
> diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
> index 3f0be70c3f145..b8264435acbe5 100644
> --- a/drivers/net/ethernet/mediatek/mtk_wed.c
> +++ b/drivers/net/ethernet/mediatek/mtk_wed.c
> @@ -949,6 +949,16 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
> static void
> mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
> {
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++)
> + if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED))
> + mtk_wed_free_ring(dev, &dev->rx_ring[i]);
[Severity: High]
Should this check dev->rx_ring[i].flags instead of dev->tx_ring[i].flags?
The flag on rx_ring[idx] is set in mtk_wed_rx_ring_setup(), and that
function never touches tx_ring[idx]. The existing reader in
mtk_wed_dma_enable() also tests the flag on the rx ring itself:
for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
struct mtk_wed_ring *ring = &dev->rx_ring[i];
...
if (!(ring->flags & MTK_WED_RING_CONFIGURED))
continue; /* queue is not configured by mt76 */
TX and RX rings are set up separately, so their flags can differ. Take
MT7992 with a second HIF:
- mt7996_dma_init() puts band1 RX on the primary WED's rx_ring[1].
- mt7996_register_phy() sends band1 TX to wed_hif2.
- mt7996_init_tx_queues() then uses MT_WED_Q_TX(0) on wed_hif2.
So the primary WED's tx_ring[1] is never configured.
In that case, is the rx_ring[1] descriptor memory still leaked on every
detach? This loop skips it, and the pointer is then lost to the
memset(dev, 0, sizeof(*dev)) at the end of __mtk_wed_detach(). That looks
like the same leak the commit message says it fixes.
mtk_wed_free_ring() already returns early when ring->desc is NULL. Would
dropping the flag check here be enough?
> +
> + for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
> + if ((dev->tx_wdma[i].flags & MTK_WED_RING_CONFIGURED))
> + mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
> +
> mtk_wed_free_rx_buffer(dev);
> mtk_wed_free_ring(dev, &dev->rro.ring);
> }
[Severity: Medium]
Can rx_ring[i] be freed here while the WLAN chip's WFDMA RX engine still
points at it?
mtk_wed_rx_ring_setup() writes ring->desc_phys into the WLAN chip's PDMA
RX ring registers through wpdma_rx_w32(). mtk_wed_dma_enable() then turns
on the chip's RX DMA:
val = wifi_r32(dev,
dev->wlan.wpdma_rx_glo -
dev->wlan.phy_base) | MTK_WFMDA_RX_DMA_EN;
wifi_w32(dev,
dev->wlan.wpdma_rx_glo - dev->wlan.phy_base,
val);
mtk_wed_dma_disable() never clears MTK_WFMDA_RX_DMA_EN. On normal teardown
mt7915/mt7996 disable DMA before mt76_dma_cleanup() detaches WED. The
mt7915 probe error path does not seem to do that:
mt7915_init_hardware()
mt7915_dma_init()
mt7915_dma_enable()
mt7915_dma_start()
mtk_wed_device_start() <- WFDMA RX enabled
mt7915_mcu_init() <- fails, returns without DMA disable
The probe error label in mt7915/pci.c or mt7915/soc.c then runs:
mtk_wed_device_detach()
__mtk_wed_detach()
mtk_wed_free_rx_rings()
mtk_wed_free_ring(dev, &dev->rx_ring[i])
dma_free_coherent()
If the chip writes back an RX descriptor after this point, would that
corrupt memory that has since been reused? Before this patch the ring
leaked, so such writes landed in memory that was still allocated.
The error path leaving DMA armed predates this patch, and the RX packet
buffers were already freed in this window. Whether the chip really writes
descriptors after MCU init fails depends on hardware behaviour. Freeing
the descriptor ring here is the new part.
> @@ -959,9 +969,11 @@ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
> int i;
>
> for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
> - mtk_wed_free_ring(dev, &dev->tx_ring[i]);
> + if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED))
> + mtk_wed_free_ring(dev, &dev->tx_ring[i]);
[Severity: Medium]
Does this leak the tx_ring[idx] descriptor buffer when
mtk_wed_tx_ring_setup() fails partway?
mtk_wed_tx_ring_setup() allocates the descriptor before it sets the flag:
if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
sizeof(*ring->desc), true))
return -ENOMEM;
if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_TX(idx);
ring->wpdma = regs;
ring->flags |= MTK_WED_RING_CONFIGURED;
If the rx_wdma dma_alloc_coherent() fails, tx_ring[idx].desc stays
allocated but the flag is never set. The -ENOMEM travels up:
mt76_wed_dma_setup()
mt76_dma_alloc_queue()
mt7915/mt7996 dma init
probe error path
mtk_wed_device_detach()
Before this patch, mtk_wed_free_tx_rings() freed the ring because
mtk_wed_free_ring() only checks ring->desc. With the new check the ring
is skipped, and the memset in __mtk_wed_detach() then drops the pointer.
mtk_wed_rx_ring_setup() uses the same order. A failure in
mtk_wed_wdma_tx_ring_setup() returns before rx_ring[idx].flags is set, so
the flag-gated rx_ring free in mtk_wed_free_rx_rings() cannot reclaim
that ring either.
Since mtk_wed_free_ring() already guards on ring->desc, what does the
MTK_WED_RING_CONFIGURED check add in these free loops? The commit message
does not explain why the frees are gated.
> for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
> - mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
> + if ((dev->rx_wdma[i].flags & MTK_WED_RING_CONFIGURED))
> + mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
> }
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261016-wedfix-v5-0-8b02e78fd34f%40gmail.com
next prev parent reply other threads:[~2026-10-20 10:11 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-16 9:12 [PATCH net v5 0/5] net: ethernet: mtk_wed: misc fixes Zhi-Jun You
2026-10-16 9:12 ` [PATCH net v5 1/5] net: ethernet: mtk_wed: skip ring reset in wdma_tx_ring_setup for WED v3 Zhi-Jun You
2026-10-20 10:10 ` netdev-bot+sashiko
2026-10-16 9:12 ` [PATCH net v5 2/5] net: ethernet: mtk_wed: fix reset condition for rx wdma Zhi-Jun You
2026-10-20 10:10 ` netdev-bot+sashiko
2026-10-16 9:12 ` [PATCH net v5 3/5] net: ethernet: mtk_wed: free up rings during detach Zhi-Jun You
2026-10-20 10:10 ` netdev-bot+sashiko [this message]
2026-10-20 12:37 ` Zhi-Jun You
2026-10-16 9:12 ` [PATCH net v5 4/5] net: ethernet: mtk_wed: setup WDMA_RING_TX(0) for non-DBDC MT7986 Zhi-Jun You
2026-10-20 10:10 ` netdev-bot+sashiko
2026-10-20 12:39 ` Zhi-Jun You
2026-10-16 9:12 ` [PATCH net v5 5/5] net: ethernet: mtk_wed: bail out when failed to set up rings in wed_start Zhi-Jun You
2026-10-20 10:10 ` netdev-bot+sashiko
2026-10-20 12:42 ` Zhi-Jun You
2026-10-16 9:19 ` [PATCH net v5 0/5] net: ethernet: mtk_wed: misc fixes netdev-bot+sinfo
2026-10-20 2:42 ` Zhi-Jun You
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=179249104276.3135.12420565113536395663@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=angelogioacchino.delregno@collabora.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=hujy652@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=lorenzo@kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=nbd@nbd.name \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rex.lu@mediatek.com \
--cc=sujuan.chen@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox