From: Sagi Maimon <maimon.sagi@gmail.com>
To: netdev@vger.kernel.org
Cc: radhey.shyam.pandey@amd.com, michal.simek@amd.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, linux@armlinux.org.uk,
daniel@iogearbox.net, andybnac@gmail.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Sagi Maimon <maimon.sagi@gmail.com>
Subject: [PATCH net v2 3/4] net: axienet: quiesce the TX queue across a DMA error reset
Date: Thu, 24 Sep 2026 16:51:15 +0300 [thread overview]
Message-ID: <20260924135116.185161-4-maimon.sagi@gmail.com> (raw)
In-Reply-To: <20260924135116.185161-1-maimon.sagi@gmail.com>
axienet_dma_err_handler() resets the DMA engine, frees every TX
descriptor's skb and mapping, and rewinds lp->tx_bd_ci and
lp->tx_bd_tail to 0. It has two problems with the transmit path.
First, nothing excludes axienet_start_xmit() while it does so.
napi_disable() only stops axienet_tx_poll(), and the handler takes no
transmit lock. A transmit running concurrently can publish an skb into
a descriptor that the handler then frees, and dereference it afterwards
in netdev_sent_queue(), or program a descriptor whose mapping the
handler has just released and kick XAXIDMA_TX_TDESC with a tail pointer
the handler is about to rewind.
Second, the handler never restarts the queue. If the ring was full when
the error hit, axienet_start_xmit() had stopped the queue with
netif_stop_queue(), and that __QUEUE_STATE_DRV_XOFF survives the reset:
netdev_reset_queue() clears only __QUEUE_STATE_STACK_XOFF, and nothing
at all without CONFIG_BQL. The wake in axienet_tx_poll() is reached
only when axienet_free_tx_chain() reclaims packets, which cannot happen
once the handler has cleared every status word, so the interface stops
transmitting until it is brought down and up again.
Quiesce the transmit path with netif_tx_disable() once TX NAPI is
disabled, so that no transmit is in progress or can start while the ring
is torn down, and wake the queue once the reset is complete. Because
the handler now owns the queue state for its whole duration, the wake
cannot be lost to a concurrent netif_stop_queue().
Skip the wake if the interface is being stopped or the device has been
detached for suspend, or it would undo the stop that
netif_device_detach() installed; axienet_stop() and axienet_open() own
the queue state then. A detach racing with the check is covered by
axienet_stop() quiescing the queue again before it tears anything down.
Both problems were reported by the Sashiko AI review bot.
Tested on an AXI Ethernet MAC behind a PCIe endpoint: traffic passes,
including across ten down/up cycles made with traffic running, with this
series applied. The DMA error path itself was not exercised.
Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Assisted-by: LLM sparse
Signed-off-by: Sagi Maimon <maimon.sagi@gmail.com>
---
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 6d448d0b523d..f16dbfc7dc93 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -2724,6 +2724,11 @@ static void axienet_dma_err_handler(struct work_struct *work)
napi_disable(&lp->napi_tx);
napi_disable(&lp->napi_rx);
+ /* With TX NAPI disabled nothing else can wake the queue. Stop it and
+ * wait out any transmit in progress, so the ring can be torn down.
+ */
+ netif_tx_disable(ndev);
+
axienet_setoptions(ndev, lp->options &
~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
@@ -2791,6 +2796,13 @@ static void axienet_dma_err_handler(struct work_struct *work)
napi_enable(&lp->napi_rx);
napi_enable(&lp->napi_tx);
axienet_setoptions(ndev, lp->options);
+
+ /* Leave the queue stopped if the interface is going down or the
+ * device was detached for suspend: axienet_stop() and axienet_open()
+ * own the queue state then.
+ */
+ if (!READ_ONCE(lp->stopping) && netif_device_present(ndev))
+ netif_wake_queue(ndev);
}
/**
--
2.47.0
next prev parent reply other threads:[~2026-09-24 13:51 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 13:51 [PATCH net v2 0/4] net: axienet: fix TX queue handling around " Sagi Maimon
2026-09-24 13:51 ` [PATCH net v2 1/4] net: axienet: start the TX queue in axienet_open() Sagi Maimon
2026-09-24 13:51 ` [PATCH net v2 2/4] net: axienet: quiesce the TX path before axienet_stop() tears it down Sagi Maimon
2026-09-24 13:51 ` Sagi Maimon [this message]
2026-09-24 13:51 ` [PATCH net v2 4/4] net: axienet: reprogram the link settings after a DMA error reset Sagi Maimon
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=20260924135116.185161-4-maimon.sagi@gmail.com \
--to=maimon.sagi@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=andybnac@gmail.com \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=michal.simek@amd.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=radhey.shyam.pandey@amd.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
all inboxes | Powered by JetHome®