From: Paolo Abeni <pabeni@redhat.com>
To: cohenyang511@gmail.com
Cc: andrew+netdev@lunn.ch, davem@davemloft.net, yangg9@xiaopeng.com,
kuba@kernel.org, netdev@vger.kernel.org
Subject: Re: net: stmmac: Reorder cleanup sequence and disable IRQ earlier in reset path
Date: Thu, 19 Mar 2026 13:46:20 +0100 [thread overview]
Message-ID: <20260319124620.226576-1-pabeni@redhat.com> (raw)
In-Reply-To: <20260317121937.109211-1-yangg9@xiaopeng.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
net: stmmac: Reorder cleanup sequence and disable IRQ earlier in reset path
The recent changes restructure resource cleanup in __stmmac_release() to
free IRQ lines, stop DMA, and release descriptors before stopping the PHY.
Additionally, stmmac_reset_subtask() now disables IRQ earlier to prevent
spurious interrupts during the DOWN transition.
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 124d7a00f9f0..fa06b2eb33f2 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4202,6 +4202,15 @@ static void __stmmac_release(struct net_device *dev)
> struct stmmac_priv *priv = netdev_priv(dev);
> u8 chan;
>
> + /* Free the IRQ lines */
> + stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
> +
> + /* Stop TX/RX DMA and clear the descriptors */
> + stmmac_stop_all_dma(priv);
> +
> + /* Release and free the Rx/Tx resources */
> + free_dma_desc_resources(priv, &priv->dma_conf);
> +
> /* Stop and disconnect the PHY */
> phylink_stop(priv->phylink);
>
> @@ -4212,15 +4221,6 @@ static void __stmmac_release(struct net_device *dev)
>
> netif_tx_disable(dev);
>
> - /* Free the IRQ lines */
> - stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
> -
> - /* Stop TX/RX DMA and clear the descriptors */
> - stmmac_stop_all_dma(priv);
> -
> - /* Release and free the Rx/Tx resources */
> - free_dma_desc_resources(priv, &priv->dma_conf);
> -
^^^^
Moving free_dma_desc_resources() before stmmac_disable_all_queues() looks
problematic. Can a TX coalesce hrtimer fire after the DMA resources are
freed?
The stmmac driver has TX coalesce timers (stmmac_tx_timer) that can call
napi_schedule(). If free_dma_desc_resources() frees tx_q->tx_skbuff_dma
and tx_q->tx_skbuff via __free_dma_tx_desc_resources():
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:__free_dma_tx_desc_resources() {
...
kfree(tx_q->tx_skbuff_dma);
tx_q->tx_skbuff_dma = NULL;
kfree(tx_q->tx_skbuff);
tx_q->tx_skbuff = NULL;
...
}
But the hrtimer hasn't been cancelled yet (hrtimer_cancel is in
stmmac_disable_all_queues), and NAPI hasn't been disabled yet, then:
stmmac_tx_timer() fires
-> napi_schedule_prep()
-> __napi_schedule()
-> NAPI poll eventually runs
-> stmmac_napi_poll_tx()
-> stmmac_tx_clean()
-> accesses freed tx_q->tx_skbuff_dma[entry] and tx_q->tx_skbuff[entry]
The original order disabled NAPI and cancelled hrtimers before freeing DMA
resources. The stmmac_xdp_release() function in this same file shows the
correct pattern:
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:stmmac_xdp_release() {
...
stmmac_disable_all_queues(priv);
for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
...
free_dma_desc_resources(priv, &priv->dma_conf);
...
}
> stmmac_release_ptp(priv);
>
> if (stmmac_fpe_supported(priv))
[ ... ]
> @@ -7331,6 +7331,9 @@ static void stmmac_reset_subtask(struct stmmac_priv *priv)
> while (test_and_set_bit(STMMAC_RESETING, &priv->state))
> usleep_range(1000, 2000);
>
> + /* Close IRQ entry as early as possible before DOWN short-circuit path. */
> + disable_irq_nosync(priv->dev->irq);
> +
^^^^
disable_irq_nosync() increments the IRQ descriptor's depth counter, but
where is the corresponding enable_irq()?
The stmmac driver doesn't call enable_irq() anywhere. After dev_close()
and dev_open() complete:
stmmac_reset_subtask()
-> disable_irq_nosync(dev->irq) // depth++
-> dev_close()
-> __stmmac_release()
-> stmmac_free_irq()
-> free_irq(dev->irq, dev)
-> dev_open()
-> stmmac_request_irq_single()
-> request_irq(dev->irq, ..., IRQF_SHARED, ...)
For non-shared IRQs, this works by coincidence: free_irq's last-handler
removal calls irq_shutdown (depth++), then request_irq's first-handler
registration calls irq_startup which resets depth to 0.
However, when dev->irq is shared with another device (IRQF_SHARED is set
in stmmac_request_irq_single), free_irq does NOT call irq_shutdown because
other handlers remain on desc->action. The depth stays at 1. The
subsequent request_irq takes the shared path in __setup_irq which does NOT
call irq_startup, leaving depth at 1.
The IRQ line remains disabled after the reset completes, breaking
interrupts for all devices on that shared line. Should enable_irq() be
added after dev_open()?
> set_bit(STMMAC_DOWN, &priv->state);
> dev_close(priv->dev);
> dev_open(priv->dev, NULL);
prev parent reply other threads:[~2026-03-19 12:49 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-17 12:19 [PATCH] net: stmmac: Reorder cleanup sequence and disable IRQ earlier in reset path yangg9
2026-03-19 12:46 ` Paolo Abeni [this message]
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=20260319124620.226576-1-pabeni@redhat.com \
--to=pabeni@redhat.com \
--cc=andrew+netdev@lunn.ch \
--cc=cohenyang511@gmail.com \
--cc=davem@davemloft.net \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=yangg9@xiaopeng.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