* [PATCH net v2 0/2] net: stmmac: Fix XSK crashes on stm32mp2
@ 2026-10-05 7:09 Kurt Kanzenbach
2026-10-05 7:09 ` [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() Kurt Kanzenbach
2026-10-05 7:09 ` [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools Kurt Kanzenbach
0 siblings, 2 replies; 12+ messages in thread
From: Kurt Kanzenbach @ 2026-10-05 7:09 UTC (permalink / raw)
To: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski,
Paolo Abeni, Eric Dumazet
Cc: Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov,
Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi,
Mohd Faizal Abdul Rahim, Ong Boon Leong,
Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel,
bpf, Kurt Kanzenbach
Hi,
while looking at the TBS thingy [1], I've noticed kernel crashes. That
happens when opening or closing an AF_XDP/ZC socket while parallel Tx
traffic is going on.
So far, I see two issues:
- Patch #1: stmmac_xdp_release() seems to have the teardown order wrong
- Patch #2: stmmac_xdp_(en|dis)able_pool() does not stop the Tx queue
at all
The kernel crashes can be reproduced instantly on the stm32mp2 like this:
- Run iperf3
- Run application which opens an AF_XDP/ZC socket
[1] - https://lore.kernel.org/all/20260812-stm32mp2_txtime-v1-1-f9e2462cc85d@linutronix.de/
Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
---
Changes in v2:
- Remove RFC. No comments.
- Link to v1: https://patch.msgid.link/20260915-stmmac_xsk_crashes-v1-0-e14553fcf553@linutronix.de
---
Kurt Kanzenbach (2):
net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release()
net: stmmac: Stop Tx queue when (en|dis)abling XSK pools
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++---
drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 14 ++++++++++++++
2 files changed, 17 insertions(+), 3 deletions(-)
---
base-commit: aaaaf87ea99b8766c9a8aa0e71aa42e6bc8a5320
change-id: 20260914-stmmac_xsk_crashes-10a77f614ab5
Best regards,
--
Kurt Kanzenbach <kurt@linutronix.de>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() 2026-10-05 7:09 [PATCH net v2 0/2] net: stmmac: Fix XSK crashes on stm32mp2 Kurt Kanzenbach @ 2026-10-05 7:09 ` Kurt Kanzenbach 2026-10-05 9:15 ` Maxime Chevallier ` (2 more replies) 2026-10-05 7:09 ` [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools Kurt Kanzenbach 1 sibling, 3 replies; 12+ messages in thread From: Kurt Kanzenbach @ 2026-10-05 7:09 UTC (permalink / raw) To: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet Cc: Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf, Kurt Kanzenbach Attaching an XDP program while Tx traffic is running results in kernel crashes in stmmac_xmit() -> dwmac4_set_addr(). Loading an XDP program tears down and reallocates all DMA resources via stmmac_xdp_release() and stmmac_xdp_open(). stmmac_xdp_release() stops the Tx queues before disabling NAPI: stmmac_xdp_release: netif_tx_disable stmmac_disable_all_queues ... free_dma_desc_resources A Tx NAPI poll may still be in flight at that point. stmmac_tx_clean() takes the Tx queue lock, reaps completed descriptors and wakes the queue again when it observes it stopped with enough descriptors available. Nothing stops the queue afterwards, so the Tx path resumes while free_dma_desc_resources() releases the descriptor rings underneath it. On non-coherent platforms dma_free_coherent() tears down the vmalloc mapping of the descriptors, so the subsequent stmmac_xmit() faults on an unmapped address instead of corrupting memory silently. Disable NAPI first and stop the Tx queues afterwards, which is the order already used by __stmmac_release(). The issue can be easily reproduced by: 1. Run iperf 2. Run application which opens an AF_XDP/ZC socket Assisted-by: Claude:claude-opus-5 Fixes: 77711683a504 ("net: stmmac: ensure tx function is not running in stmmac_xdp_release()") Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 9741f97fa37a..796817caf7af 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -7178,15 +7178,15 @@ void stmmac_xdp_release(struct net_device *dev) struct stmmac_priv *priv = netdev_priv(dev); u8 chan; - /* Ensure tx function is not running */ - netif_tx_disable(dev); - /* Disable NAPI process */ 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); + /* Ensure tx function is not running */ + netif_tx_disable(dev); + /* Free the IRQ lines */ stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); -- 2.47.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() 2026-10-05 7:09 ` [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() Kurt Kanzenbach @ 2026-10-05 9:15 ` Maxime Chevallier 2026-10-06 8:24 ` Kurt Kanzenbach 2026-10-08 7:50 ` Nicolai Buchwitz 2026-10-08 19:09 ` netdev-bot+sashiko 2 siblings, 1 reply; 12+ messages in thread From: Maxime Chevallier @ 2026-10-05 9:15 UTC (permalink / raw) To: Kurt Kanzenbach, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet Cc: Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf Hi Kurt, On 10/5/26 09:09, Kurt Kanzenbach wrote: > Attaching an XDP program while Tx traffic is running results in kernel > crashes in stmmac_xmit() -> dwmac4_set_addr(). > > Loading an XDP program tears down and reallocates all DMA resources via > stmmac_xdp_release() and stmmac_xdp_open(). stmmac_xdp_release() stops > the Tx queues before disabling NAPI: > > stmmac_xdp_release: > netif_tx_disable > stmmac_disable_all_queues > ... > free_dma_desc_resources > > A Tx NAPI poll may still be in flight at that point. stmmac_tx_clean() > takes the Tx queue lock, reaps completed descriptors and wakes the queue > again when it observes it stopped with enough descriptors available. > Nothing stops the queue afterwards, so the Tx path resumes while > free_dma_desc_resources() releases the descriptor rings underneath it. > > On non-coherent platforms dma_free_coherent() tears down the vmalloc > mapping of the descriptors, so the subsequent stmmac_xmit() faults on an > unmapped address instead of corrupting memory silently. > > Disable NAPI first and stop the Tx queues afterwards, which is the order > already used by __stmmac_release(). > > The issue can be easily reproduced by: > > 1. Run iperf > 2. Run application which opens an AF_XDP/ZC socket > > Assisted-by: Claude:claude-opus-5 > Fixes: 77711683a504 ("net: stmmac: ensure tx function is not running in stmmac_xdp_release()") > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> This now matches the non-xdp case, great :) Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Maxime > --- > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > index 9741f97fa37a..796817caf7af 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > @@ -7178,15 +7178,15 @@ void stmmac_xdp_release(struct net_device *dev) > struct stmmac_priv *priv = netdev_priv(dev); > u8 chan; > > - /* Ensure tx function is not running */ > - netif_tx_disable(dev); > - > /* Disable NAPI process */ > 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); > > + /* Ensure tx function is not running */ > + netif_tx_disable(dev); > + > /* Free the IRQ lines */ > stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() 2026-10-05 9:15 ` Maxime Chevallier @ 2026-10-06 8:24 ` Kurt Kanzenbach 0 siblings, 0 replies; 12+ messages in thread From: Kurt Kanzenbach @ 2026-10-06 8:24 UTC (permalink / raw) To: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet Cc: Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf [-- Attachment #1: Type: text/plain, Size: 1868 bytes --] Hi Maxime, On Mon Oct 05 2026, Maxime Chevallier wrote: > On 10/5/26 09:09, Kurt Kanzenbach wrote: >> Attaching an XDP program while Tx traffic is running results in kernel >> crashes in stmmac_xmit() -> dwmac4_set_addr(). >> >> Loading an XDP program tears down and reallocates all DMA resources via >> stmmac_xdp_release() and stmmac_xdp_open(). stmmac_xdp_release() stops >> the Tx queues before disabling NAPI: >> >> stmmac_xdp_release: >> netif_tx_disable >> stmmac_disable_all_queues >> ... >> free_dma_desc_resources >> >> A Tx NAPI poll may still be in flight at that point. stmmac_tx_clean() >> takes the Tx queue lock, reaps completed descriptors and wakes the queue >> again when it observes it stopped with enough descriptors available. >> Nothing stops the queue afterwards, so the Tx path resumes while >> free_dma_desc_resources() releases the descriptor rings underneath it. >> >> On non-coherent platforms dma_free_coherent() tears down the vmalloc >> mapping of the descriptors, so the subsequent stmmac_xmit() faults on an >> unmapped address instead of corrupting memory silently. >> >> Disable NAPI first and stop the Tx queues afterwards, which is the order >> already used by __stmmac_release(). >> >> The issue can be easily reproduced by: >> >> 1. Run iperf >> 2. Run application which opens an AF_XDP/ZC socket >> >> Assisted-by: Claude:claude-opus-5 >> Fixes: 77711683a504 ("net: stmmac: ensure tx function is not running in stmmac_xdp_release()") >> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > > This now matches the non-xdp case, great :) Thanks for the review! Yes, it does match now. We could also collapse the common teardown code between __stmmac_release() and stmmac_xdp_release() into a helper function now and reduce code duplication. Thanks, Kurt [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 861 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() 2026-10-05 7:09 ` [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() Kurt Kanzenbach 2026-10-05 9:15 ` Maxime Chevallier @ 2026-10-08 7:50 ` Nicolai Buchwitz 2026-10-08 19:09 ` netdev-bot+sashiko 2 siblings, 0 replies; 12+ messages in thread From: Nicolai Buchwitz @ 2026-10-08 7:50 UTC (permalink / raw) To: Kurt Kanzenbach Cc: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet, Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf Hi Kurt On 5.10.2026 09:09, Kurt Kanzenbach wrote: > Attaching an XDP program while Tx traffic is running results in kernel > crashes in stmmac_xmit() -> dwmac4_set_addr(). > > Loading an XDP program tears down and reallocates all DMA resources via > stmmac_xdp_release() and stmmac_xdp_open(). stmmac_xdp_release() stops > the Tx queues before disabling NAPI: > > stmmac_xdp_release: > netif_tx_disable > stmmac_disable_all_queues > ... > free_dma_desc_resources > > A Tx NAPI poll may still be in flight at that point. stmmac_tx_clean() > takes the Tx queue lock, reaps completed descriptors and wakes the > queue > again when it observes it stopped with enough descriptors available. > Nothing stops the queue afterwards, so the Tx path resumes while > free_dma_desc_resources() releases the descriptor rings underneath it. > > On non-coherent platforms dma_free_coherent() tears down the vmalloc > mapping of the descriptors, so the subsequent stmmac_xmit() faults on > an > unmapped address instead of corrupting memory silently. > > Disable NAPI first and stop the Tx queues afterwards, which is the > order > already used by __stmmac_release(). > > The issue can be easily reproduced by: > > 1. Run iperf > 2. Run application which opens an AF_XDP/ZC socket > > Assisted-by: Claude:claude-opus-5 > Fixes: 77711683a504 ("net: stmmac: ensure tx function is not running in > stmmac_xdp_release()") > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > [...] Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Tested-by: Nicolai Buchwitz <nb@tipi-net.de> # stm32mp215 Thanks, Nicolai ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() 2026-10-05 7:09 ` [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() Kurt Kanzenbach 2026-10-05 9:15 ` Maxime Chevallier 2026-10-08 7:50 ` Nicolai Buchwitz @ 2026-10-08 19:09 ` netdev-bot+sashiko 2 siblings, 0 replies; 12+ messages in thread From: netdev-bot+sashiko @ 2026-10-08 19:09 UTC (permalink / raw) To: kurt Cc: maxime.chevallier, andrew+netdev, davem, kuba, pabeni, edumazet, mcoquelin.stm32, alexandre.torgue, ast, daniel, hawk, john.fastabend, sdf, yoong.siang.song, noor.azura.ahmad.tarmizi, faizal.abdul.rahim, boon.leong.ong, bigeasy, netdev, linux-stm32, linux-arm-kernel, bpf Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider. Critical: 0 · High: 2 (1) · Medium: 0 (1) · 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] Baseline decision: false. - [High] This patch reorders stmmac_xdp_release() so that hrtimer_cancel() on every tx_q->txtimer now runs before… Pre-existing issues: - [High] This problem was not introduced by this patch, but it is a use- after-free in the same teardown sequence, and moving… - [Medium] Baseline decision: false. -- net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() This commit reorders stmmac_xdp_release() so that NAPI is disabled and the Tx coalescing timers are cancelled before netif_tx_disable() is called. The goal is to stop an in-flight Tx NAPI poll from waking the Tx queue again while free_dma_desc_resources() releases the descriptor rings. > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > index 9741f97fa37a2..796817caf7af0 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > @@ -7178,15 +7178,15 @@ void stmmac_xdp_release(struct net_device *dev) > struct stmmac_priv *priv = netdev_priv(dev); > u8 chan; > > - /* Ensure tx function is not running */ > - netif_tx_disable(dev); > - > /* Disable NAPI process */ > 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); > > + /* Ensure tx function is not running */ > + netif_tx_disable(dev); [Severity: High] Now that netif_tx_disable() runs after the hrtimer_cancel() loop, can stmmac_xmit() re-arm tx_q->txtimer after it has been cancelled? Before this change, netif_tx_disable() took every txq lock first. Any running stmmac_xmit() had finished and the queues were stopped before the timers were cancelled. Now stmmac_xmit() can run at the same time as stmmac_disable_all_queues() and the cancel loop. It always ends by calling stmmac_tx_timer_arm(): stmmac_tx_timer_arm() { ... if (unlikely(!napi_is_scheduled(napi))) { if (unlikely(!(hrtimer_active(&tx_q->txtimer)))) hrtimer_start(&tx_q->txtimer, STMMAC_COAL_TIMER(tx_coal_timer), HRTIMER_MODE_REL); ... } One possible interleaving: CPU1 (stmmac_xmit) CPU0 (stmmac_xdp_release) stmmac_tx_timer_arm() napi_is_scheduled() == false stmmac_disable_all_queues() napi_disable() sets SCHED hrtimer_cancel(&tx_q->txtimer) timer not armed, returns 0 hrtimer_start(&tx_q->txtimer) netif_tx_disable(dev) The timer then stays queued while the rings are freed. The timeout is 5ms by default and up to 100ms through ethtool -C tx-usecs. stmmac_xdp_set_prog() then calls stmmac_xdp_open(), which does: hrtimer_setup(&tx_q->txtimer, stmmac_tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); __hrtimer_setup() memsets the timer while it is still linked in the hrtimer base timerqueue. Could that corrupt the timerqueue rbtree when the timer expires or is started again? Would this order avoid the problem: disable NAPI, then netif_tx_disable(), then hrtimer_cancel()? __stmmac_release() is cited in the commit message as the reference order, but it also cancels the timers before netif_tx_disable(). It may have the same window. [Severity: High] The reproducer in the commit message opens an AF_XDP/ZC socket. When an XDP program is already attached, that goes through stmmac_xdp_setup_pool() -> stmmac_xdp_enable_pool() in stmmac_xdp.c, not stmmac_xdp_release(): stmmac_xdp_enable_pool() { ... if (need_update) { napi_disable(&ch->rx_napi); napi_disable(&ch->tx_napi); stmmac_disable_rx_queue(priv, queue); stmmac_disable_tx_queue(priv, queue); } ... } stmmac_disable_tx_queue() frees the ring with stmmac_stop_tx_dma() and __free_dma_tx_desc_resources(). Nothing stops the netdev Tx queue. stmmac_xdp_disable_pool() follows the same pattern with ch->rxtx_napi. At this commit, can stmmac_xmit() keep writing into tx_q->dma_tx while the ring is freed and reallocated on these paths? The next patch in the series, "net: stmmac: Stop Tx queue when (en|dis)abling XSK pools", appears to address this. It adds stmmac_xdp_stop_tx_queue() after napi_disable() and netif_tx_wake_queue() after the queues are re-enabled, which closes the gap by the end of the series. > + > /* Free the IRQ lines */ > stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); [Severity: Medium] This isn't a bug introduced by this patch, but the TX/DMA IRQ handlers stay registered after netif_tx_disable() until stmmac_free_irq() runs. STMMAC_DOWN is not set on this path. If a TX hard error arrives in that window, stmmac_msi_intr_tx() or stmmac_dma_interrupt() calls stmmac_tx_err(), which ends with: stmmac_tx_err() { ... priv->xstats.tx_errors++; netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, chan)); } Can that reopen the queue so that stmmac_xmit() runs on rings that free_dma_desc_resources() is about to release? The window existed before this patch and was larger then. Hitting it needs a hardware DMA TX fatal error during XDP attach or detach. [Severity: High] This is a pre-existing issue, not introduced by this patch. Moving netif_tx_disable() does not change it. When the XDP program is removed, stmmac_xdp_set_prog() does: if (!prog) xdp_features_clear_redirect_target(dev); need_update = !!priv->xdp_prog != !!prog; if (if_running && need_update) stmmac_xdp_release(dev); Nothing like synchronize_rcu() or synchronize_net() runs between clearing the flag and the release. stmmac_disable_all_queues() calls synchronize_rcu() only when an rx_q->xsk_pool exists. Another device's NAPI poll may already have passed the NETDEV_XDP_ACT_NDO_XMIT check in __xdp_enqueue(). It can then flush its bulk queue from xdp_do_flush() into stmmac_xdp_xmit() after free_dma_desc_resources() has run. stmmac_xdp_xmit() only checks: if (unlikely(test_bit(STMMAC_DOWN, &priv->state))) return -ENETDOWN; This path never sets STMMAC_DOWN. Also, __netif_tx_lock() ignores the stopped state set by netif_tx_disable(). Could stmmac_xdp_xmit_xdpf() then write into the freed tx_q->dma_tx and tx_q->tx_skbuff_dma? Would either of these close it: setting STMMAC_DOWN, or adding synchronize_rcu()/synchronize_net() after the redirect target is cleared and before the release? -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261005-stmmac_xsk_crashes-v2-0-46c60cba6421%40linutronix.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools 2026-10-05 7:09 [PATCH net v2 0/2] net: stmmac: Fix XSK crashes on stm32mp2 Kurt Kanzenbach 2026-10-05 7:09 ` [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() Kurt Kanzenbach @ 2026-10-05 7:09 ` Kurt Kanzenbach 2026-10-08 7:54 ` Nicolai Buchwitz ` (2 more replies) 1 sibling, 3 replies; 12+ messages in thread From: Kurt Kanzenbach @ 2026-10-05 7:09 UTC (permalink / raw) To: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet Cc: Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf, Kurt Kanzenbach When enabling or disabling XSK pools in parallel to Tx traffic, kernel crashes occur. For VLAN tagged frames that happens in stmmac_xmit() -> dwmac4_set_vlan_tag() and for normal frames in stmmac_xmit() -> dwmac4_set_addr(). Both of these functions access the Tx DMA descriptors. The XDP pool (en|dis)ablement frees and reallocates the Tx DMA resources: stmmac_disable_tx_queue: __free_dma_tx_desc_resources stmmac_enable_tx_queue: __alloc_dma_tx_desc_resources __init_dma_tx_desc_rings NAPI is disabled during that allocation window, but the Tx queue is not stopped. Therefore, add the stopping of the Tx queue during the enabling and disabling of XSK pools. Update trans_start when stopping the queue to avoid spurious watchdog timeouts. The issue can be easily reproduced by: 1. Run iperf 2. Run application which opens an AF_XDP/ZC socket Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket") Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> --- drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c index d7e4db7224b0..883bd3fe8089 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c @@ -6,6 +6,16 @@ #include "stmmac.h" #include "stmmac_xdp.h" +static void stmmac_xdp_stop_tx_queue(struct stmmac_priv *priv, u16 queue) +{ + struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); + + __netif_tx_lock_bh(nq); + txq_trans_cond_update(nq); + netif_tx_stop_queue(nq); + __netif_tx_unlock_bh(nq); +} + static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, struct xsk_buff_pool *pool, u16 queue) { @@ -36,6 +46,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, if (need_update) { napi_disable(&ch->rx_napi); napi_disable(&ch->tx_napi); + stmmac_xdp_stop_tx_queue(priv, queue); stmmac_disable_rx_queue(priv, queue); stmmac_disable_tx_queue(priv, queue); } @@ -46,6 +57,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, stmmac_enable_rx_queue(priv, queue); stmmac_enable_tx_queue(priv, queue); napi_enable(&ch->rxtx_napi); + netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX); if (err) @@ -73,6 +85,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue) if (need_update) { napi_disable(&ch->rxtx_napi); + stmmac_xdp_stop_tx_queue(priv, queue); stmmac_disable_rx_queue(priv, queue); stmmac_disable_tx_queue(priv, queue); synchronize_rcu(); @@ -87,6 +100,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue) stmmac_enable_tx_queue(priv, queue); napi_enable(&ch->rx_napi); napi_enable(&ch->tx_napi); + netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); } return 0; -- 2.47.3 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools 2026-10-05 7:09 ` [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools Kurt Kanzenbach @ 2026-10-08 7:54 ` Nicolai Buchwitz 2026-10-08 12:47 ` Kurt Kanzenbach 2026-10-08 9:02 ` Maciej Fijalkowski 2026-10-08 19:09 ` netdev-bot+sashiko 2 siblings, 1 reply; 12+ messages in thread From: Nicolai Buchwitz @ 2026-10-08 7:54 UTC (permalink / raw) To: Kurt Kanzenbach Cc: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet, Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf Hi Kurt On 5.10.2026 09:09, Kurt Kanzenbach wrote: > When enabling or disabling XSK pools in parallel to Tx traffic, kernel > crashes occur. For VLAN tagged frames that happens in stmmac_xmit() -> > dwmac4_set_vlan_tag() and for normal frames in stmmac_xmit() -> > dwmac4_set_addr(). Both of these functions access the Tx DMA > descriptors. > > The XDP pool (en|dis)ablement frees and reallocates the Tx DMA > resources: > > stmmac_disable_tx_queue: > __free_dma_tx_desc_resources > > stmmac_enable_tx_queue: > __alloc_dma_tx_desc_resources > __init_dma_tx_desc_rings > > NAPI is disabled during that allocation window, but the Tx queue is not > stopped. Therefore, add the stopping of the Tx queue during the > enabling > and disabling of XSK pools. Update trans_start when stopping the queue > to avoid spurious watchdog timeouts. > > The issue can be easily reproduced by: > > 1. Run iperf > 2. Run application which opens an AF_XDP/ZC socket > > Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket") > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > --- > drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > index d7e4db7224b0..883bd3fe8089 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > @@ -6,6 +6,16 @@ > #include "stmmac.h" > #include "stmmac_xdp.h" > > +static void stmmac_xdp_stop_tx_queue(struct stmmac_priv *priv, u16 > queue) > +{ > + struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); > + > + __netif_tx_lock_bh(nq); > + txq_trans_cond_update(nq); > + netif_tx_stop_queue(nq); > + __netif_tx_unlock_bh(nq); > +} > + > static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, > struct xsk_buff_pool *pool, u16 queue) > { > @@ -36,6 +46,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv > *priv, > if (need_update) { > napi_disable(&ch->rx_napi); > napi_disable(&ch->tx_napi); > + stmmac_xdp_stop_tx_queue(priv, queue); Unfortunately XDP_TX and ndo_xdp_xmit() ignore the stopped queue and still hit the freed ring. I can reproduce this on STM32MP215 with a veth redirect into the port while toggling the pool: pc : dwmac4_set_addr+0x8/0x18 lr : stmmac_xdp_xmit_xdpf+0x1d0/0x3f0 stmmac_xdp_xmit+0xe4/0x1a8 bq_xmit_all+0xa0/0x208 __dev_flush+0x60/0xc0 xdp_do_flush+0x134/0x198 veth_poll+0x258/0x340 Both go through stmmac_xdp_xmit_xdpf() with the queue lock held, so this fixes it for me: --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, dma_addr_t dma_addr; bool set_ic; + /* Ring may be torn down for an XSK pool switch */ + if (netif_tx_queue_stopped(netdev_get_tx_queue(priv->dev, queue))) + return STMMAC_XDP_CONSUMED; + if (stmmac_tx_avail(priv, queue) < STMMAC_TX_THRESH(priv)) return STMMAC_XDP_CONSUMED; This is older than your patch, but could you fold it in / add a oatch? > [...] Thanks, Nicolai ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools 2026-10-08 7:54 ` Nicolai Buchwitz @ 2026-10-08 12:47 ` Kurt Kanzenbach 0 siblings, 0 replies; 12+ messages in thread From: Kurt Kanzenbach @ 2026-10-08 12:47 UTC (permalink / raw) To: Nicolai Buchwitz Cc: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet, Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf [-- Attachment #1: Type: text/plain, Size: 3612 bytes --] Hi Nicolai, On Thu Oct 08 2026, Nicolai Buchwitz wrote: > On 5.10.2026 09:09, Kurt Kanzenbach wrote: >> When enabling or disabling XSK pools in parallel to Tx traffic, kernel >> crashes occur. For VLAN tagged frames that happens in stmmac_xmit() -> >> dwmac4_set_vlan_tag() and for normal frames in stmmac_xmit() -> >> dwmac4_set_addr(). Both of these functions access the Tx DMA >> descriptors. >> >> The XDP pool (en|dis)ablement frees and reallocates the Tx DMA >> resources: >> >> stmmac_disable_tx_queue: >> __free_dma_tx_desc_resources >> >> stmmac_enable_tx_queue: >> __alloc_dma_tx_desc_resources >> __init_dma_tx_desc_rings >> >> NAPI is disabled during that allocation window, but the Tx queue is not >> stopped. Therefore, add the stopping of the Tx queue during the >> enabling >> and disabling of XSK pools. Update trans_start when stopping the queue >> to avoid spurious watchdog timeouts. >> >> The issue can be easily reproduced by: >> >> 1. Run iperf >> 2. Run application which opens an AF_XDP/ZC socket >> >> Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket") >> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> >> --- >> drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 14 ++++++++++++++ >> 1 file changed, 14 insertions(+) >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> index d7e4db7224b0..883bd3fe8089 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> @@ -6,6 +6,16 @@ >> #include "stmmac.h" >> #include "stmmac_xdp.h" >> >> +static void stmmac_xdp_stop_tx_queue(struct stmmac_priv *priv, u16 >> queue) >> +{ >> + struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); >> + >> + __netif_tx_lock_bh(nq); >> + txq_trans_cond_update(nq); >> + netif_tx_stop_queue(nq); >> + __netif_tx_unlock_bh(nq); >> +} >> + >> static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, >> struct xsk_buff_pool *pool, u16 queue) >> { >> @@ -36,6 +46,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv >> *priv, >> if (need_update) { >> napi_disable(&ch->rx_napi); >> napi_disable(&ch->tx_napi); >> + stmmac_xdp_stop_tx_queue(priv, queue); > > Unfortunately XDP_TX and ndo_xdp_xmit() ignore the stopped queue and > still > hit the freed ring. I can reproduce this on STM32MP215 with a veth > redirect > into the port while toggling the pool: > > pc : dwmac4_set_addr+0x8/0x18 > lr : stmmac_xdp_xmit_xdpf+0x1d0/0x3f0 > stmmac_xdp_xmit+0xe4/0x1a8 > bq_xmit_all+0xa0/0x208 > __dev_flush+0x60/0xc0 > xdp_do_flush+0x134/0x198 > veth_poll+0x258/0x340 > > Both go through stmmac_xdp_xmit_xdpf() with the queue lock held, so this > fixes it for me: > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, > dma_addr_t dma_addr; > bool set_ic; > > + /* Ring may be torn down for an XSK pool switch */ > + if (netif_tx_queue_stopped(netdev_get_tx_queue(priv->dev, queue))) > + return STMMAC_XDP_CONSUMED; > + > if (stmmac_tx_avail(priv, queue) < STMMAC_TX_THRESH(priv)) > return STMMAC_XDP_CONSUMED; > > This is older than your patch, but could you fold it in / add a oatch? Thanks a lot for testing! I'll fold it in for next version. Thanks, Kurt [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 861 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools 2026-10-05 7:09 ` [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools Kurt Kanzenbach 2026-10-08 7:54 ` Nicolai Buchwitz @ 2026-10-08 9:02 ` Maciej Fijalkowski 2026-10-08 12:51 ` Kurt Kanzenbach 2026-10-08 19:09 ` netdev-bot+sashiko 2 siblings, 1 reply; 12+ messages in thread From: Maciej Fijalkowski @ 2026-10-08 9:02 UTC (permalink / raw) To: Kurt Kanzenbach Cc: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet, Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf On Mon, Oct 05, 2026 at 09:09:33AM +0200, Kurt Kanzenbach wrote: > When enabling or disabling XSK pools in parallel to Tx traffic, kernel > crashes occur. For VLAN tagged frames that happens in stmmac_xmit() -> > dwmac4_set_vlan_tag() and for normal frames in stmmac_xmit() -> > dwmac4_set_addr(). Both of these functions access the Tx DMA descriptors. > > The XDP pool (en|dis)ablement frees and reallocates the Tx DMA resources: > > stmmac_disable_tx_queue: > __free_dma_tx_desc_resources > > stmmac_enable_tx_queue: > __alloc_dma_tx_desc_resources > __init_dma_tx_desc_rings > > NAPI is disabled during that allocation window, but the Tx queue is not > stopped. Therefore, add the stopping of the Tx queue during the enabling > and disabling of XSK pools. Update trans_start when stopping the queue > to avoid spurious watchdog timeouts. > > The issue can be easily reproduced by: > > 1. Run iperf > 2. Run application which opens an AF_XDP/ZC socket > > Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket") > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > --- > drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > index d7e4db7224b0..883bd3fe8089 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > @@ -6,6 +6,16 @@ > #include "stmmac.h" > #include "stmmac_xdp.h" > > +static void stmmac_xdp_stop_tx_queue(struct stmmac_priv *priv, u16 queue) > +{ > + struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); > + > + __netif_tx_lock_bh(nq); > + txq_trans_cond_update(nq); > + netif_tx_stop_queue(nq); > + __netif_tx_unlock_bh(nq); > +} > + > static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, > struct xsk_buff_pool *pool, u16 queue) > { > @@ -36,6 +46,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, > if (need_update) { > napi_disable(&ch->rx_napi); > napi_disable(&ch->tx_napi); > + stmmac_xdp_stop_tx_queue(priv, queue); FWIW you can look at what I did at ice driver (ice_qp_dis()) where I used a bigger hammer here; I think updating trans_start is kinda a workaround. https://lore.kernel.org/netdev/20240708221416.625850-1-anthony.l.nguyen@intel.com/ > stmmac_disable_rx_queue(priv, queue); > stmmac_disable_tx_queue(priv, queue); > } > @@ -46,6 +57,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, > stmmac_enable_rx_queue(priv, queue); > stmmac_enable_tx_queue(priv, queue); > napi_enable(&ch->rxtx_napi); > + netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); > > err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX); > if (err) > @@ -73,6 +85,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue) > > if (need_update) { > napi_disable(&ch->rxtx_napi); > + stmmac_xdp_stop_tx_queue(priv, queue); > stmmac_disable_rx_queue(priv, queue); > stmmac_disable_tx_queue(priv, queue); > synchronize_rcu(); > @@ -87,6 +100,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue) > stmmac_enable_tx_queue(priv, queue); > napi_enable(&ch->rx_napi); > napi_enable(&ch->tx_napi); > + netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); > } > > return 0; > > -- > 2.47.3 > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools 2026-10-08 9:02 ` Maciej Fijalkowski @ 2026-10-08 12:51 ` Kurt Kanzenbach 0 siblings, 0 replies; 12+ messages in thread From: Kurt Kanzenbach @ 2026-10-08 12:51 UTC (permalink / raw) To: Maciej Fijalkowski Cc: Maxime Chevallier, Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni, Eric Dumazet, Maxime Coquelin, Alexandre Torgue, Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev, Song Yoong Siang, Noor Azura Ahmad Tarmizi, Mohd Faizal Abdul Rahim, Ong Boon Leong, Sebastian Andrzej Siewior, netdev, linux-stm32, linux-arm-kernel, bpf [-- Attachment #1: Type: text/plain, Size: 2744 bytes --] Hi Maciej, On Thu Oct 08 2026, Maciej Fijalkowski wrote: > On Mon, Oct 05, 2026 at 09:09:33AM +0200, Kurt Kanzenbach wrote: >> When enabling or disabling XSK pools in parallel to Tx traffic, kernel >> crashes occur. For VLAN tagged frames that happens in stmmac_xmit() -> >> dwmac4_set_vlan_tag() and for normal frames in stmmac_xmit() -> >> dwmac4_set_addr(). Both of these functions access the Tx DMA descriptors. >> >> The XDP pool (en|dis)ablement frees and reallocates the Tx DMA resources: >> >> stmmac_disable_tx_queue: >> __free_dma_tx_desc_resources >> >> stmmac_enable_tx_queue: >> __alloc_dma_tx_desc_resources >> __init_dma_tx_desc_rings >> >> NAPI is disabled during that allocation window, but the Tx queue is not >> stopped. Therefore, add the stopping of the Tx queue during the enabling >> and disabling of XSK pools. Update trans_start when stopping the queue >> to avoid spurious watchdog timeouts. >> >> The issue can be easily reproduced by: >> >> 1. Run iperf >> 2. Run application which opens an AF_XDP/ZC socket >> >> Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket") >> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> >> --- >> drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 14 ++++++++++++++ >> 1 file changed, 14 insertions(+) >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> index d7e4db7224b0..883bd3fe8089 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c >> @@ -6,6 +6,16 @@ >> #include "stmmac.h" >> #include "stmmac_xdp.h" >> >> +static void stmmac_xdp_stop_tx_queue(struct stmmac_priv *priv, u16 queue) >> +{ >> + struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); >> + >> + __netif_tx_lock_bh(nq); >> + txq_trans_cond_update(nq); >> + netif_tx_stop_queue(nq); >> + __netif_tx_unlock_bh(nq); >> +} >> + >> static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, >> struct xsk_buff_pool *pool, u16 queue) >> { >> @@ -36,6 +46,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, >> if (need_update) { >> napi_disable(&ch->rx_napi); >> napi_disable(&ch->tx_napi); >> + stmmac_xdp_stop_tx_queue(priv, queue); > > FWIW you can look at what I did at ice driver (ice_qp_dis()) where I used > a bigger hammer here; I think updating trans_start is kinda a workaround. > > https://lore.kernel.org/netdev/20240708221416.625850-1-anthony.l.nguyen@intel.com/ > Actually, trans_start is already updated by netif_tx_stop_queue(). I'd just remove txq_trans_cond_update() for next version. Thanks, Kurt [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 861 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools 2026-10-05 7:09 ` [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools Kurt Kanzenbach 2026-10-08 7:54 ` Nicolai Buchwitz 2026-10-08 9:02 ` Maciej Fijalkowski @ 2026-10-08 19:09 ` netdev-bot+sashiko 2 siblings, 0 replies; 12+ messages in thread From: netdev-bot+sashiko @ 2026-10-08 19:09 UTC (permalink / raw) To: kurt Cc: maxime.chevallier, andrew+netdev, davem, kuba, pabeni, edumazet, mcoquelin.stm32, alexandre.torgue, ast, daniel, hawk, john.fastabend, sdf, yoong.siang.song, noor.azura.ahmad.tarmizi, faizal.abdul.rahim, boon.leong.ong, bigeasy, netdev, linux-stm32, linux-arm-kernel, bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider. Critical: 0 · High: 1 (1) · Medium: 0 · 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] The patch only stops the netdev Tx queue, and the driver's own XDP transmit paths ignore that. Pre-existing issues: - [High] This problem wasn't introduced by this patch, but the new wake- up makes it visible: if stmmac_enable_tx_queue() fails, the Tx queue… -- net: stmmac: Stop Tx queue when (en|dis)abling XSK pools This patch stops the netdev Tx queue in stmmac_xdp_enable_pool() and stmmac_xdp_disable_pool() while the Tx DMA descriptor resources are freed and reallocated. The queue is woken once the ring has been rebuilt. The goal is to fix crashes in stmmac_xmit() when XSK pools are toggled while Tx traffic is running. > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > index d7e4db7224b0c..883bd3fe8089d 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c > @@ -6,6 +6,16 @@ > #include "stmmac.h" > #include "stmmac_xdp.h" > > +static void stmmac_xdp_stop_tx_queue(struct stmmac_priv *priv, u16 queue) > +{ > + struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); > + > + __netif_tx_lock_bh(nq); > + txq_trans_cond_update(nq); > + netif_tx_stop_queue(nq); > + __netif_tx_unlock_bh(nq); > +} [Severity: High] Does setting __QUEUE_STATE_DRV_XOFF here keep the driver's own XDP transmit paths away from the ring while it is freed and reallocated? The Tx lock is released before stmmac_disable_tx_queue() calls __free_dma_tx_desc_resources(). DRV_XOFF only stops callers that reach ndo_start_xmit through the stack. Both XDP Tx paths in stmmac_main.c choose the queue by CPU. Neither checks whether that queue is stopped before calling stmmac_xdp_xmit_xdpf(): stmmac_xdp_xmit_back() { ... queue = stmmac_xdp_get_tx_queue(priv, cpu); nq = netdev_get_tx_queue(priv->dev, queue); __netif_tx_lock(nq, cpu); ... res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, zc); ... } stmmac_xdp_xmit() { ... if (unlikely(test_bit(STMMAC_DOWN, &priv->state))) return -ENETDOWN; ... __netif_tx_lock(nq, cpu); ... res = stmmac_xdp_xmit_xdpf(priv, queue, frames[i], true); ... } need_update requires stmmac_xdp_is_enabled(), so an XDP program is always attached while this window is open. Only the NAPI instances of this one channel are disabled. Two producers can still reach this queue during the window: - RX NAPI of another channel, running on a CPU that stmmac_xdp_get_tx_queue() maps to this queue, can hit XDP_TX. - A redirect from another device on such a CPU can enter stmmac_xdp_xmit(). Either path then runs: stmmac_xdp_xmit_xdpf() stmmac_get_tx_desc() stmmac_set_tx_dma_entry() tx_q->xdpf[entry] = ... stmmac_set_desc_addr() These calls can write into the descriptor ring that was released with dma_free_coherent() and into the kfree()'d tx_skbuff_dma array. They can also race with __init_dma_tx_desc_rings() while the ring is being rebuilt. In stmmac_xdp_disable_pool(), synchronize_rcu() only runs after the ring has already been freed: stmmac_disable_tx_queue(priv, queue); synchronize_rcu(); so it cannot drain ndo_xdp_xmit callers that are in flight before the free. Would this need a per-queue gate that the XDP Tx paths check under the Tx lock, or a drain before the free, rather than DRV_XOFF alone? [ ... ] > @@ -46,6 +57,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, > stmmac_enable_rx_queue(priv, queue); > stmmac_enable_tx_queue(priv, queue); > napi_enable(&ch->rxtx_napi); > + netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue)); [Severity: High] This is a pre-existing issue that this patch did not introduce, but the new wake-up makes it more visible. What happens here if stmmac_enable_tx_queue() failed? stmmac_enable_tx_queue() returns void and only logs the failure: ret = __alloc_dma_tx_desc_resources(priv, &priv->dma_conf, queue); if (ret) { netdev_err(priv->dev, "Failed to alloc TX desc.\n"); return; } A failure in __init_dma_tx_desc_rings() is handled the same way. Either way it skips stmmac_init_tx_chan(), stmmac_start_tx_dma() and stmmac_enable_dma_irq(). __free_dma_tx_desc_resources() never clears tx_q->dma_tx/dma_etx/dma_entx, tx_skbuff_dma or tx_skbuff. That leaves three problems: - If dma_alloc_coherent() fails in __alloc_dma_tx_desc_resources(), the descriptor pointer still points at the freed coherent memory. - If the tx_skbuff allocation fails, tx_skbuff is left NULL. - The earlier partial allocations leak. netif_tx_wake_queue() is called unconditionally here and in stmmac_xdp_disable_pool(). The next stmmac_xmit() would then dereference tx_q->tx_skbuff[first_entry]. It would also write descriptors through stmmac_get_tx_desc() into the freed ring. That is the same dwmac4_set_addr()/dwmac4_set_vlan_tag() crash described in the commit message. A later stmmac_release()->free_dma_desc_resources() could also free the stale pointers a second time. Before this patch the queue was never stopped, so traffic hit the broken ring the same way. Should the failure be returned to the callers, the partial allocations unwound, and the queue kept stopped until a valid ring is in place? > > err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX); > if (err) [ ... ] -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261005-stmmac_xsk_crashes-v2-0-46c60cba6421%40linutronix.de ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-10-08 19:10 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-05 7:09 [PATCH net v2 0/2] net: stmmac: Fix XSK crashes on stm32mp2 Kurt Kanzenbach 2026-10-05 7:09 ` [PATCH net v2 1/2] net: stmmac: Disable NAPI before stopping Tx queues in stmmac_xdp_release() Kurt Kanzenbach 2026-10-05 9:15 ` Maxime Chevallier 2026-10-06 8:24 ` Kurt Kanzenbach 2026-10-08 7:50 ` Nicolai Buchwitz 2026-10-08 19:09 ` netdev-bot+sashiko 2026-10-05 7:09 ` [PATCH net v2 2/2] net: stmmac: Stop Tx queue when (en|dis)abling XSK pools Kurt Kanzenbach 2026-10-08 7:54 ` Nicolai Buchwitz 2026-10-08 12:47 ` Kurt Kanzenbach 2026-10-08 9:02 ` Maciej Fijalkowski 2026-10-08 12:51 ` Kurt Kanzenbach 2026-10-08 19:09 ` netdev-bot+sashiko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox