[PATCH net-next v6 3/4] net: stmmac: release descriptor resources through priv->dma_conf on open failure

From: Ding Hui

Date: Sat Oct 24 2026 - 03:16:11 EST


From: Ding Hui <dinghui@xxxxxxxxxxx>

__stmmac_open() copies the temporary dma_conf passed by its callers
into the long-lived priv->dma_conf before setting up the hardware.
When the open fails after this copy, the descriptor resources now
belong to priv->dma_conf, but the error path returns without
releasing them and leaves stale pointers behind. The callers then
free the already-copied resources through the temporary dma_conf,
which aliases priv->dma_conf after the memcpy.

Fix this by making __stmmac_open() release the descriptor resources
through priv->dma_conf on failure. Callers of __stmmac_open() only
need to free the temporary dma_conf container in that case, while
failures before the call (PHY setup, serdes power up) still release
the resources through the temporary dma_conf via the existing
err_dma_resources path in stmmac_open().

stmmac_open() no longer jumps to the serdes label chain after
__stmmac_open() fails, as that chain would double-release the
descriptor resources and double-put the runtime PM reference, so the
cleanup is done inline instead.

The resource release is merged with the error unwinding that stops
the DMA engines and the MAC: failures after the hardware setup
first stop the DMA engines and the MAC, and then fall through to
the common init_error label that releases the descriptor resources,
while a stmmac_hw_setup() failure jumps to init_error directly as
the engines were never started.

Signed-off-by: Ding Hui <dinghui@xxxxxxxxxxx>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a8401b04d79f..b093119e752f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4246,7 +4246,7 @@ static int __stmmac_open(struct net_device *dev,
ret = stmmac_hw_setup(dev);
if (ret < 0) {
netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);
- return ret;
+ goto init_error;
}

ret = stmmac_setup_ptp(priv);
@@ -4282,6 +4282,8 @@ static int __stmmac_open(struct net_device *dev,
stmmac_stop_all_dma(priv);
stmmac_mac_set(priv, priv->ioaddr, false);

+init_error:
+ free_dma_desc_resources(priv, &priv->dma_conf);
return ret;
}

@@ -4314,8 +4316,13 @@ static int stmmac_open(struct net_device *dev)
}

ret = __stmmac_open(dev, dma_conf);
- if (ret)
- goto err_serdes;
+ if (ret) {
+ stmmac_legacy_serdes_power_down(priv);
+ phylink_disconnect_phy(priv->phylink);
+ pm_runtime_put(priv->device);
+ kfree(dma_conf);
+ return ret;
+ }

kfree(dma_conf);

@@ -4324,8 +4331,6 @@ static int stmmac_open(struct net_device *dev)

return ret;

-err_serdes:
- stmmac_legacy_serdes_power_down(priv);
err_disconnect_phy:
phylink_disconnect_phy(priv->phylink);
err_runtime_pm:
@@ -6343,7 +6348,6 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)

ret = __stmmac_open(dev, dma_conf);
if (ret) {
- free_dma_desc_resources(priv, dma_conf);
kfree(dma_conf);
netdev_err(priv->dev, "failed reopening the interface after MTU change\n");
return ret;
--
2.34.1