* [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts
@ 2026-11-03 12:54 Maxime Chevallier
2026-11-03 13:21 ` Nicolai Buchwitz
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Maxime Chevallier @ 2026-11-03 12:54 UTC (permalink / raw)
To: Andrew Lunn, Jakub Kicinski, davem, Eric Dumazet, Paolo Abeni,
Simon Horman, Maxime Coquelin, Alexandre Torgue, Russell King,
Lorenzo Bianconi, Nicolai Buchwitz, Magnus Leatti
Cc: Maxime Chevallier, thomas.petazzoni, Alexis Lothoré,
netdev, linux-kernel, linux-arm-kernel
The Multi-MSI interrupt handler doesn't clear the DMA error interrupts,
and this leads to interrupt storms when one of these interrupts starts
firing :
- The RBU (rx buff unav) which triggers under high traffic load
This triggers easily with iperf3 and small udp packets, and shows
when running the netpoll kselftest
- The RPS (rx process stop) which triggers when we stop the DMA RX.
This one shows when restarting the RX logic without doing a down/up
cycle, like when attaching an XDP program. The XSK kselftests
triggers it.
Let's make sure we clear these interrupts for multi-MSI cases, and call
stmmac_global_err() upon tx_hard_error to avoid possible races with
other interrupts/napi.
For that introduce an "ERR" DMA dir, as we don't want to touch the
RI/TI bits when handling these interrupts.
Both of the above storms have been found on dwmac-motorcomm (YT6801),
and are triggered by the xdp.py, xsk_reconfig.py, xdp_features.py,
ring_reconfig.py and netpoll_basic kernel selftests.
This seems to only affect dwmac4, there's no multi-msi mode on
dwmac1000, and on dwxgmac these interrupts are masked as of today.
Fixes: 6ccf12ae111e ("net: stmmac: use interrupt mode INTM=1 for multi-MSI")
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V2:
- Dropped reviews/tested tags as the implementation has substantially
changed, sorry :(
- Discarded the helper, call directly stmmac_dma_interrupt_status on
all chans and use stmmac_global_err() for TX hard errors, following
sashiko's review.
drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
.../net/ethernet/stmicro/stmmac/dwmac4_dma.h | 5 +++++
.../net/ethernet/stmicro/stmmac/dwmac4_lib.c | 2 ++
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 19 +++++++++++++++++++
4 files changed, 27 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index c74bc7c9750e..a972bee66504 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -382,6 +382,7 @@ enum dma_irq_dir {
DMA_DIR_RX = 0x1,
DMA_DIR_TX = 0x2,
DMA_DIR_RXTX = 0x3,
+ DMA_DIR_ERR = 0x4,
};
enum request_irq_err {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 43b036d4e95b..a7caac3c98e6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -173,6 +173,11 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
DMA_CHAN_STATUS_TI | \
DMA_CHAN_STATUS_MSK_COMMON)
+#define DMA_CHAN_STATUS_MSK_ERR (DMA_CHAN_STATUS_AIS | \
+ DMA_CHAN_STATUS_FBE | \
+ DMA_CHAN_STATUS_RPS | \
+ DMA_CHAN_STATUS_RBU)
+
int dwmac4_dma_reset(void __iomem *ioaddr);
void dwmac4_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
u32 chan, bool rx, bool tx);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index a0249715fafa..02aa1a3dd1e2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -150,6 +150,8 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
intr_status &= DMA_CHAN_STATUS_MSK_RX;
else if (dir == DMA_DIR_TX)
intr_status &= DMA_CHAN_STATUS_MSK_TX;
+ else if (dir == DMA_DIR_ERR)
+ intr_status &= DMA_CHAN_STATUS_MSK_ERR;
/* ABNORMAL interrupts */
if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7ffed295eb14..6360605ef5ea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3145,6 +3145,22 @@ static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan, u32 dir)
return status;
}
+static void stmmac_dma_err_interrupt(struct stmmac_priv *priv)
+{
+ u8 channels_to_check = max(priv->plat->rx_queues_to_use,
+ priv->plat->tx_queues_to_use);
+ int status;
+ u8 chan;
+
+ for (chan = 0; chan < channels_to_check; chan++) {
+ status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
+ &priv->xstats, chan,
+ DMA_DIR_ERR);
+ if (unlikely(status & tx_hard_error))
+ stmmac_global_err(priv);
+ }
+}
+
/**
* stmmac_dma_interrupt - DMA ISR
* @priv: driver private structure
@@ -6494,6 +6510,9 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
/* To handle Common interrupts */
stmmac_common_interrupt(priv);
+ if (priv->plat->core_type == DWMAC_CORE_GMAC4)
+ stmmac_dma_err_interrupt(priv);
+
return IRQ_HANDLED;
}
--
2.56.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts
2026-11-03 12:54 [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts Maxime Chevallier
@ 2026-11-03 13:21 ` Nicolai Buchwitz
2026-11-03 13:41 ` Lorenzo Bianconi
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Nicolai Buchwitz @ 2026-11-03 13:21 UTC (permalink / raw)
To: Maxime Chevallier
Cc: Andrew Lunn, Jakub Kicinski, davem, Eric Dumazet, Paolo Abeni,
Simon Horman, Maxime Coquelin, Alexandre Torgue, Russell King,
Lorenzo Bianconi, Magnus Leatti, thomas.petazzoni,
Alexis Lothoré,
netdev, linux-kernel, linux-arm-kernel
Hi Maxime
On 3.11.2026 13:54, Maxime Chevallier wrote:
> The Multi-MSI interrupt handler doesn't clear the DMA error interrupts,
> and this leads to interrupt storms when one of these interrupts starts
> firing :
>
> - The RBU (rx buff unav) which triggers under high traffic load
>
> This triggers easily with iperf3 and small udp packets, and shows
> when running the netpoll kselftest
>
> - The RPS (rx process stop) which triggers when we stop the DMA RX.
>
> This one shows when restarting the RX logic without doing a down/up
> cycle, like when attaching an XDP program. The XSK kselftests
> triggers it.
>
> Let's make sure we clear these interrupts for multi-MSI cases, and call
> stmmac_global_err() upon tx_hard_error to avoid possible races with
> other interrupts/napi.
>
> For that introduce an "ERR" DMA dir, as we don't want to touch the
> RI/TI bits when handling these interrupts.
>
> Both of the above storms have been found on dwmac-motorcomm (YT6801),
> and are triggered by the xdp.py, xsk_reconfig.py, xdp_features.py,
> ring_reconfig.py and netpoll_basic kernel selftests.
>
> This seems to only affect dwmac4, there's no multi-msi mode on
> dwmac1000, and on dwxgmac these interrupts are masked as of today.
>
> Fixes: 6ccf12ae111e ("net: stmmac: use interrupt mode INTM=1 for
> multi-MSI")
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> [...]
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Thanks,
Nicolai
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts
2026-11-03 12:54 [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts Maxime Chevallier
2026-11-03 13:21 ` Nicolai Buchwitz
@ 2026-11-03 13:41 ` Lorenzo Bianconi
2026-11-03 16:58 ` Magnus Leatti
2026-11-04 12:57 ` netdev-bot+sashiko
3 siblings, 0 replies; 5+ messages in thread
From: Lorenzo Bianconi @ 2026-11-03 13:41 UTC (permalink / raw)
To: Maxime Chevallier
Cc: Andrew Lunn, Jakub Kicinski, davem, Eric Dumazet, Paolo Abeni,
Simon Horman, Maxime Coquelin, Alexandre Torgue, Russell King,
Nicolai Buchwitz, Magnus Leatti, thomas.petazzoni,
Alexis Lothoré,
netdev, linux-kernel, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 5256 bytes --]
On Nov 03, Maxime Chevallier wrote:
> The Multi-MSI interrupt handler doesn't clear the DMA error interrupts,
> and this leads to interrupt storms when one of these interrupts starts
> firing :
>
> - The RBU (rx buff unav) which triggers under high traffic load
>
> This triggers easily with iperf3 and small udp packets, and shows
> when running the netpoll kselftest
>
> - The RPS (rx process stop) which triggers when we stop the DMA RX.
>
> This one shows when restarting the RX logic without doing a down/up
> cycle, like when attaching an XDP program. The XSK kselftests
> triggers it.
>
> Let's make sure we clear these interrupts for multi-MSI cases, and call
> stmmac_global_err() upon tx_hard_error to avoid possible races with
> other interrupts/napi.
>
> For that introduce an "ERR" DMA dir, as we don't want to touch the
> RI/TI bits when handling these interrupts.
>
> Both of the above storms have been found on dwmac-motorcomm (YT6801),
> and are triggered by the xdp.py, xsk_reconfig.py, xdp_features.py,
> ring_reconfig.py and netpoll_basic kernel selftests.
>
> This seems to only affect dwmac4, there's no multi-msi mode on
> dwmac1000, and on dwxgmac these interrupts are masked as of today.
>
> Fixes: 6ccf12ae111e ("net: stmmac: use interrupt mode INTM=1 for multi-MSI")
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> ---
> V2:
> - Dropped reviews/tested tags as the implementation has substantially
> changed, sorry :(
> - Discarded the helper, call directly stmmac_dma_interrupt_status on
> all chans and use stmmac_global_err() for TX hard errors, following
> sashiko's review.
>
> drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
> .../net/ethernet/stmicro/stmmac/dwmac4_dma.h | 5 +++++
> .../net/ethernet/stmicro/stmmac/dwmac4_lib.c | 2 ++
> .../net/ethernet/stmicro/stmmac/stmmac_main.c | 19 +++++++++++++++++++
> 4 files changed, 27 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index c74bc7c9750e..a972bee66504 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -382,6 +382,7 @@ enum dma_irq_dir {
> DMA_DIR_RX = 0x1,
> DMA_DIR_TX = 0x2,
> DMA_DIR_RXTX = 0x3,
> + DMA_DIR_ERR = 0x4,
> };
>
> enum request_irq_err {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> index 43b036d4e95b..a7caac3c98e6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> @@ -173,6 +173,11 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
> DMA_CHAN_STATUS_TI | \
> DMA_CHAN_STATUS_MSK_COMMON)
>
> +#define DMA_CHAN_STATUS_MSK_ERR (DMA_CHAN_STATUS_AIS | \
> + DMA_CHAN_STATUS_FBE | \
> + DMA_CHAN_STATUS_RPS | \
> + DMA_CHAN_STATUS_RBU)
> +
> int dwmac4_dma_reset(void __iomem *ioaddr);
> void dwmac4_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> u32 chan, bool rx, bool tx);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> index a0249715fafa..02aa1a3dd1e2 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> @@ -150,6 +150,8 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
> intr_status &= DMA_CHAN_STATUS_MSK_RX;
> else if (dir == DMA_DIR_TX)
> intr_status &= DMA_CHAN_STATUS_MSK_TX;
> + else if (dir == DMA_DIR_ERR)
> + intr_status &= DMA_CHAN_STATUS_MSK_ERR;
>
> /* ABNORMAL interrupts */
> if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 7ffed295eb14..6360605ef5ea 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3145,6 +3145,22 @@ static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan, u32 dir)
> return status;
> }
>
> +static void stmmac_dma_err_interrupt(struct stmmac_priv *priv)
> +{
> + u8 channels_to_check = max(priv->plat->rx_queues_to_use,
> + priv->plat->tx_queues_to_use);
> + int status;
> + u8 chan;
> +
> + for (chan = 0; chan < channels_to_check; chan++) {
> + status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
> + &priv->xstats, chan,
> + DMA_DIR_ERR);
> + if (unlikely(status & tx_hard_error))
> + stmmac_global_err(priv);
> + }
> +}
> +
> /**
> * stmmac_dma_interrupt - DMA ISR
> * @priv: driver private structure
> @@ -6494,6 +6510,9 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
> /* To handle Common interrupts */
> stmmac_common_interrupt(priv);
>
> + if (priv->plat->core_type == DWMAC_CORE_GMAC4)
> + stmmac_dma_err_interrupt(priv);
> +
> return IRQ_HANDLED;
> }
Reviewed-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
>
> --
> 2.56.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts
2026-11-03 12:54 [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts Maxime Chevallier
2026-11-03 13:21 ` Nicolai Buchwitz
2026-11-03 13:41 ` Lorenzo Bianconi
@ 2026-11-03 16:58 ` Magnus Leatti
2026-11-04 12:57 ` netdev-bot+sashiko
3 siblings, 0 replies; 5+ messages in thread
From: Magnus Leatti @ 2026-11-03 16:58 UTC (permalink / raw)
To: Maxime Chevallier
Cc: Andrew Lunn, Jakub Kicinski, davem, Eric Dumazet, Paolo Abeni,
Simon Horman, Maxime Coquelin, Alexandre Torgue, Russell King,
Lorenzo Bianconi, Nicolai Buchwitz, thomas.petazzoni,
Alexis Lothoré,
netdev, linux-kernel, linux-arm-kernel
On 11/3/26 13:54, Maxime Chevallier wrote:
> The Multi-MSI interrupt handler doesn't clear the DMA error interrupts,
> and this leads to interrupt storms when one of these interrupts starts
> firing :
Retested v2 on the YT6801, same setup as v1: net at cb284914e749, glue
unmodified, so the MISC interrupt stays unmasked.
4x 64-byte UDP RX flood for 10 s, same kernel:
without the patch: the MAC interrupt hits about 93k/s within 4 s,
stays at about 122k/s after the flood stops, and the machine stops
responding.
with v2: about 300/s during the flood, 0 after.
8x 64-byte UDP RX plus TCP TX for 30 s: about 25/s during, 0 after,
with TX at 744 Mbit/s alongside.
The 4x flood also runs clean after link down/up, ring resize, an MTU
change, a 100/1000 speed change and a module reload. Throughput is the
same as with v1 (TCP RX 941, TCP TX 825 Mbit/s).
Tested-by: Magnus Leatti <magnusleatti@kernelriot.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts
2026-11-03 12:54 [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts Maxime Chevallier
` (2 preceding siblings ...)
2026-11-03 16:58 ` Magnus Leatti
@ 2026-11-04 12:57 ` netdev-bot+sashiko
3 siblings, 0 replies; 5+ messages in thread
From: netdev-bot+sashiko @ 2026-11-04 12:57 UTC (permalink / raw)
To: maxime.chevallier
Cc: andrew+netdev, kuba, davem, edumazet, pabeni, horms,
mcoquelin.stm32, alexandre.torgue, linux, lorenzo.bianconi, nb,
magnusleatti, thomas.petazzoni, alexis.lothore, netdev,
linux-kernel, linux-arm-kernel
Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 2 · Low: 1
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).
- [Medium] The Fixes: tag points at the wrong commit for the storms the
message describes.
- [Medium] The new DMA_DIR_ERR path does not own the abnormal bits it
relies on.
- [Low] The commit message says "there's no multi-msi mode on dwmac1000".
--
net: stmmac: Clear DMA errors for multi-channel interrupts
This patch adds a DMA_DIR_ERR direction and a DMA_CHAN_STATUS_MSK_ERR mask
for dwmac4. In multi-MSI mode, stmmac_mac_interrupt() now walks every DMA
channel and clears the AIS/FBE/RPS/RBU status bits. A tx_hard_error seen on
that path calls stmmac_global_err().
> Fixes: 6ccf12ae111e ("net: stmmac: use interrupt mode INTM=1 for multi-MSI")
[Severity: Medium]
Is this the right commit for the storms described above?
Before 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts"), dwmac4
never set RBU or RPS in DMA_CHAN_INTR_ENA. DMA_CHAN_INTR_ABNORMAL and
DMA_CHAN_INTR_ABNORMAL_4_10 were only:
(DMA_CHAN_INTR_ENA_AIE | DMA_CHAN_INTR_ENA_FBE)
With only 6ccf12ae111e applied, RBU and RPS could not raise AIS on the
INTM=1 MAC vector. FBE was the only abnormal source left unhandled there.
The RBU and RPS storms, and the selftests listed in the message, only seem
reachable after 1b9707e6f1a9. That commit enabled these bits so that the
statistic counters could be updated.
Should the Fixes: tag point at 1b9707e6f1a9 instead, or also include it?
As written, stable may backport this to 5.13+ trees that cannot hit these
storms.
Since RBU and RPS were enabled only for statistics, was masking them in
multi-MSI mode considered as an alternative?
> This seems to only affect dwmac4, there's no multi-msi mode on
> dwmac1000, and on dwxgmac these interrupts are masked as of today.
[Severity: Low]
Is the dwmac1000 part of this accurate? dwmac-loongson uses a
dwmac1000-family core and it does enable multi-MSI:
drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:
plat->core_type = DWMAC_CORE_GMAC;
...
*dma = dwmac1000_dma_ops;
dma->init_chan = loongson_dwmac_dma_init_channel;
dma->dma_interrupt = loongson_dwmac_dma_interrupt;
...
loongson_dwmac_msi_config() {
...
plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
...
}
On multichan Loongson parts, stmmac_mac_interrupt() is installed on
dev->irq. Loongson is only kept out of the new path by the
core_type == DWMAC_CORE_GMAC4 check in stmmac_mac_interrupt(). That check
also keeps DMA_DIR_ERR away from loongson_dwmac_dma_interrupt(), which only
handles DMA_DIR_RX and DMA_DIR_TX.
Could the message give the real reason for excluding this core? For
example, Loongson reports abnormal status per direction (AIS_RX/AIS_TX,
FBI_RX/FBI_TX), and its per-channel RX/TX handlers clear it.
[ ... ]
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 7ffed295eb14a..6360605ef5ead 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3145,6 +3145,22 @@ static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan, u32 dir)
> return status;
> }
>
> +static void stmmac_dma_err_interrupt(struct stmmac_priv *priv)
> +{
> + u8 channels_to_check = max(priv->plat->rx_queues_to_use,
> + priv->plat->tx_queues_to_use);
> + int status;
> + u8 chan;
> +
> + for (chan = 0; chan < channels_to_check; chan++) {
> + status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
> + &priv->xstats, chan,
> + DMA_DIR_ERR);
> + if (unlikely(status & tx_hard_error))
> + stmmac_global_err(priv);
[Severity: Medium]
Can the per-channel RX/TX MSI handlers clear FBE before this loop sees it?
DMA_CHAN_STATUS_MSK_ERR (AIS | FBE | RPS | RBU) is a subset of
DMA_CHAN_STATUS_MSK_RX. DMA_CHAN_STATUS_MSK_TX also includes AIS | FBE
through DMA_CHAN_STATUS_MSK_COMMON.
Every direction goes through dwmac4_dma_interrupt(). It reads
DMA_CHAN_STATUS and then acks what it read, with no lock in between:
u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan));
...
writel(intr_status & intr_en,
ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan));
Suppose FBE latches while RI or TI is pending on the same channel. The
per-channel vector can then consume FBE first and drop the error:
stmmac_msi_intr_rx()
stmmac_napi_check(priv, chan, DMA_DIR_RX);
dwmac4_dma_interrupt() /* clears FBE | AIS, returns tx_hard_error */
/* return value is ignored */
stmmac_msi_intr_tx()
status = stmmac_napi_check(priv, chan, DMA_DIR_TX);
/* status is tx_hard_error | handle_tx when TI is also set */
if (unlikely(status & tx_hard_error_bump_tc)) {
...
} else if (unlikely(status == tx_hard_error)) {
stmmac_tx_err(priv, chan);
}
When stmmac_mac_interrupt() then runs for that event,
stmmac_dma_err_interrupt() finds FBE already cleared and does not call
stmmac_global_err(). The error is counted, but nothing resets the DMA
unless the TX watchdog happens to fire.
The commit message says stmmac_global_err() is called upon tx_hard_error
"to avoid possible races with other interrupts/napi". Does that only hold
when the MAC vector reads FBE first?
The overlap also means one RBU or RPS event can be counted twice in
rx_buf_unav_irq or rx_process_stopped_irq. This happens if the DMA_DIR_ERR
and DMA_DIR_RX paths both read the status before either one acks it.
Would it work to make the masks disjoint in multi-MSI mode? For example,
AIS/FBE/RBU/RPS could be dropped from the RX/TX masks when the ERR path
owns them.
Also, stmmac_request_irq_multi_msi() installs stmmac_mac_interrupt() on
wol_irq as well:
ret = request_irq(priv->wol_irq,
stmmac_mac_interrupt,
0, int_name, dev);
Could two copies of this loop race over the same per-channel status
registers on different CPUs?
> + }
> +}
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261103125430.962715-1-maxime.chevallier%40bootlin.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-04 12:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-03 12:54 [PATCH net v2] net: stmmac: Clear DMA errors for multi-channel interrupts Maxime Chevallier
2026-11-03 13:21 ` Nicolai Buchwitz
2026-11-03 13:41 ` Lorenzo Bianconi
2026-11-03 16:58 ` Magnus Leatti
2026-11-04 12:57 ` 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
all inboxes | Powered by JetHome®