* [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
@ 2026-07-16 20:10 tresonic
2026-07-16 21:47 ` Andrew Lunn
0 siblings, 1 reply; 12+ messages in thread
From: tresonic @ 2026-07-16 20:10 UTC (permalink / raw)
To: netdev; +Cc: regressions, rmk+kernel, kuba
Hello,
Please bear with me, this is my first time writing to a mailing list...
Since commit 1b9707e6f1a9, suspend (systemctl suspend) causes a full system freeze on my laptop. Fans and keyboard backlight stay powered; the machine is completely unresponsive and requires a hard power-off (holding the power button) to recover. I could not get any kernel output from the hang.
- Reproduces on current master
- git revert 1b9707e6f1a9... on top of master fixes the issue
- Workaround: sudo ip link set eno1 down before suspend avoids the hang entirely; with the interface down, suspend/resume works normally even on the bad commit
Hardware:
64:00.0 Ethernet controller: Motorcomm Microelectronics. YT6801 Gigabit Ethernet Controller (rev 01)
Kernel driver in use: dwmac-motorcomm
[ 5.672548] YT8531S Gigabit Ethernet stmmac-6400:00: attached PHY driver (mii_bus:phy_addr=stmmac-6400:00, irq=POLL)
[ 5.890940] dwmac-motorcomm 0000:64:00.0 eno1: PHY [stmmac-6400:00] driver [YT8531S Gigabit Ethernet] (irq=POLL)
Thank you,
tresonic
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-16 20:10 [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts") tresonic
@ 2026-07-16 21:47 ` Andrew Lunn
2026-07-17 7:18 ` tresonic
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2026-07-16 21:47 UTC (permalink / raw)
To: tresonic; +Cc: netdev, regressions, rmk+kernel, kuba
On Thu, Jul 16, 2026 at 10:10:25PM +0200, tresonic wrote:
> Hello,
> Please bear with me, this is my first time writing to a mailing list...
Thanks for the report. Nice description for a first post. Lots of
useful details.
> Since commit 1b9707e6f1a9, suspend (systemctl suspend) causes a full system freeze on my laptop. Fans and keyboard backlight stay powered; the machine is completely unresponsive and requires a hard power-off (holding the power button) to recover. I could not get any kernel output from the hang.
1b9707e6f1a9 makes in effect 4 changes.
Can you do some testing to see if the changes to
DMA_CHAN_INTR_ABNORMAL or the changes to DMA_CHAN_INTR_ABNORMAL_4_10
break it. Or both, but i think that is unlikely.
Once you know which of those is responsible, can you test to see which
of DMA_CHAN_INTR_ENA_RPS or DMA_CHAN_INTR_ENA_RBU broke it.
It kind of sounds like an interrupt storm, but that is just a
guess. If it is an interrupt storm, it suggests an interrupt is not
being disabled during suspend.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-16 21:47 ` Andrew Lunn
@ 2026-07-17 7:18 ` tresonic
2026-07-17 15:40 ` Andrew Lunn
0 siblings, 1 reply; 12+ messages in thread
From: tresonic @ 2026-07-17 7:18 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, regressions, rmk+kernel, kuba
On 7/16/26 11:47 PM, Andrew Lunn wrote:
> On Thu, Jul 16, 2026 at 10:10:25PM +0200, tresonic wrote:
>> Hello,
>> Please bear with me, this is my first time writing to a mailing list...
>
> Thanks for the report. Nice description for a first post. Lots of
> useful details.
>
>> Since commit 1b9707e6f1a9, suspend (systemctl suspend) causes a full system freeze on my laptop. Fans and keyboard backlight stay powered; the machine is completely unresponsive and requires a hard power-off (holding the power button) to recover. I could not get any kernel output from the hang.
>
> 1b9707e6f1a9 makes in effect 4 changes.
>
> Can you do some testing to see if the changes to
> DMA_CHAN_INTR_ABNORMAL or the changes to DMA_CHAN_INTR_ABNORMAL_4_10
> break it. Or both, but i think that is unlikely.
>
> Once you know which of those is responsible, can you test to see which
> of DMA_CHAN_INTR_ENA_RPS or DMA_CHAN_INTR_ENA_RBU broke it.
>
> It kind of sounds like an interrupt storm, but that is just a
> guess. If it is an interrupt storm, it suggests an interrupt is not
> being disabled during suspend.
>
> Andrew
I tested the changes as you suggested and it seems DMA_CHAN_INTR_ENA_RPS in DMA_CHAN_INTR_ABNORMAL_4_10 broke it.
With this change on master suspend is working:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 43b036d4e95b..e907142c9ee2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -121,7 +121,6 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
DMA_CHAN_INTR_ENA_TIE)
#define DMA_CHAN_INTR_ABNORMAL_4_10 (DMA_CHAN_INTR_ENA_AIE_4_10 | \
- DMA_CHAN_INTR_ENA_RPS | \
DMA_CHAN_INTR_ENA_RBU | \
DMA_CHAN_INTR_ENA_FBE)
/* DMA default interrupt mask for 4.10a */
tresonic
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-17 7:18 ` tresonic
@ 2026-07-17 15:40 ` Andrew Lunn
2026-07-17 22:23 ` tresonic
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2026-07-17 15:40 UTC (permalink / raw)
To: tresonic; +Cc: netdev, regressions, rmk+kernel, kuba, Maxime Chevallier
> I tested the changes as you suggested and it seems DMA_CHAN_INTR_ENA_RPS in DMA_CHAN_INTR_ABNORMAL_4_10 broke it.
> With this change on master suspend is working:
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> index 43b036d4e95b..e907142c9ee2 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> @@ -121,7 +121,6 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
> DMA_CHAN_INTR_ENA_TIE)
>
> #define DMA_CHAN_INTR_ABNORMAL_4_10 (DMA_CHAN_INTR_ENA_AIE_4_10 | \
> - DMA_CHAN_INTR_ENA_RPS | \
> DMA_CHAN_INTR_ENA_RBU | \
> DMA_CHAN_INTR_ENA_FBE)
> /* DMA default interrupt mask for 4.10a */
OK, that narrows it down a bit.
I made the guess it is an interrupt storm during suspend, because
interrupts are not disabled. DMA_CHAN_INTR_ABNORMAL_4_10 is written to
hardware in dwmac410_dma_init_channel(). However, i don't see anywhere
these interrupts are clear? struct stmmac_dma_ops has an init_chan
operation, but there is no opposite operation to reset a channel?
There is however disable_dma_irq. Maybe DMA_CHAN_INTR_ENA_RPS can be
cleared there?
But i'm also having trouble finding where dwmac4_disable_dma_irq() is
actually called. It is called from stmmac_disable_rx_queue() and
stmmac_disable_tx_queue() but they only seem to be used in the XDP
code.
Are the DMAs being stopped during suspend? I don't know this driver
well enough to answer that.
Can you scatter some printk() around and see what actually happens on
suspend. See if you can find somewhere to disable that one interrupt?
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-17 15:40 ` Andrew Lunn
@ 2026-07-17 22:23 ` tresonic
2026-07-17 22:34 ` tresonic
2026-07-18 0:16 ` Andrew Lunn
0 siblings, 2 replies; 12+ messages in thread
From: tresonic @ 2026-07-17 22:23 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, regressions, rmk+kernel, kuba, Maxime Chevallier
On 7/17/26 5:40 PM, Andrew Lunn wrote:
>> I tested the changes as you suggested and it seems DMA_CHAN_INTR_ENA_RPS in DMA_CHAN_INTR_ABNORMAL_4_10 broke it.
>> With this change on master suspend is working:
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
>> index 43b036d4e95b..e907142c9ee2 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
>> @@ -121,7 +121,6 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
>> DMA_CHAN_INTR_ENA_TIE)
>>
>> #define DMA_CHAN_INTR_ABNORMAL_4_10 (DMA_CHAN_INTR_ENA_AIE_4_10 | \
>> - DMA_CHAN_INTR_ENA_RPS | \
>> DMA_CHAN_INTR_ENA_RBU | \
>> DMA_CHAN_INTR_ENA_FBE)
>> /* DMA default interrupt mask for 4.10a */
>
> OK, that narrows it down a bit.
>
> I made the guess it is an interrupt storm during suspend, because
> interrupts are not disabled. DMA_CHAN_INTR_ABNORMAL_4_10 is written to
> hardware in dwmac410_dma_init_channel(). However, i don't see anywhere
> these interrupts are clear? struct stmmac_dma_ops has an init_chan
> operation, but there is no opposite operation to reset a channel?
> There is however disable_dma_irq. Maybe DMA_CHAN_INTR_ENA_RPS can be
> cleared there?
>
> But i'm also having trouble finding where dwmac4_disable_dma_irq() is
> actually called. It is called from stmmac_disable_rx_queue() and
> stmmac_disable_tx_queue() but they only seem to be used in the XDP
> code.
>
> Are the DMAs being stopped during suspend? I don't know this driver
> well enough to answer that.
>
> Can you scatter some printk() around and see what actually happens on
> suspend. See if you can find somewhere to disable that one interrupt?
>
> Andrew
It seems your assumptions are correct. If i do
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index a0249715fafa..487efc746b20 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -129,6 +129,8 @@ void dwmac4_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+ value &= ~DMA_CHAN_INTR_ENA_RPS;
+
if (rx)
value &= ~DMA_CHAN_INTR_ENA_RIE;
if (tx)
I can suspend and resume!
Could it be sufficient to just do this and reenable on dwmac4_enable_dma_irq?
tresonic
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-17 22:23 ` tresonic
@ 2026-07-17 22:34 ` tresonic
2026-07-18 0:16 ` Andrew Lunn
1 sibling, 0 replies; 12+ messages in thread
From: tresonic @ 2026-07-17 22:34 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, regressions, rmk+kernel, kuba, Maxime Chevallier
>> But i'm also having trouble finding where dwmac4_disable_dma_irq() is
>> actually called. It is called from stmmac_disable_rx_queue() and
>> stmmac_disable_tx_queue() but they only seem to be used in the XDP
>> code.
Afaict these are called through the stmmac_stop_rx macro which maps to the function pointers in dwmac410_dma_ops.
So this actually gets called from stmmac_suspend via stmmac_stop_all_dma.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-17 22:23 ` tresonic
2026-07-17 22:34 ` tresonic
@ 2026-07-18 0:16 ` Andrew Lunn
2026-07-18 7:35 ` tresonic
1 sibling, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2026-07-18 0:16 UTC (permalink / raw)
To: tresonic; +Cc: netdev, regressions, rmk+kernel, kuba, Maxime Chevallier
> It seems your assumptions are correct. If i do
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> index a0249715fafa..487efc746b20 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> @@ -129,6 +129,8 @@ void dwmac4_disable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
> const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
> u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
>
> + value &= ~DMA_CHAN_INTR_ENA_RPS;
> +
> if (rx)
> value &= ~DMA_CHAN_INTR_ENA_RIE;
> if (tx)
>
> I can suspend and resume!
Cool. So we might be going in the correct direction.
> Could it be sufficient to just do this and reenable on dwmac4_enable_dma_irq?
Unfortunately, it is not as simple as that.
The driver implements NAPI. Interrupts are expensive, so what NAPI
does is after there is an interrupt indicating there are received
packets, and there are more than 64 packets to be received, it
disables interrupts, and goes into polling made. Whenever it polls, if
there are packets available it keeps on polling. Only when polling
indicates there are no more packets, are interrupts re-enabled and
polling stopped.
You can see parts of this logic in stmmac_napi_poll_rx().
This means it cannot be done here. We need a function which is only
called on suspend, and probably release.
The interrupt is being enabled in the init_chan call in
stmmac_dma_ops. Ideally, it should be disabled in a mirror function,
which currently does not exist. So maybe deinit_chan() needs
adding. But where to call it from? init_chan() is called from
stmmac_init_dma_engine(), from stmmac_hw_setup(). stmmac_resume() does
call this. So we need something in stmmac_suspend(). Maybe in
stmmac_stop_all_dma()?
stmmac is messy, there are often not mirror functions. If there is a
stmmac_init_dma_engine() there should be
stmmac_deinit_dma_engine(). If there is stmmac_hw_setup() there should
be stmmac_hw_tairdown(). But none of these seem to exist.
Anyway, do you want to try to implement deinit_chan() and call it from
stmmac_stop_all_dma()?
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-18 0:16 ` Andrew Lunn
@ 2026-07-18 7:35 ` tresonic
2026-07-18 13:11 ` Maxime Chevallier
2026-07-18 14:06 ` Andrew Lunn
0 siblings, 2 replies; 12+ messages in thread
From: tresonic @ 2026-07-18 7:35 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, regressions, rmk+kernel, kuba, Maxime Chevallier
Thank you for you explanations!
> The interrupt is being enabled in the init_chan call in
> stmmac_dma_ops. Ideally, it should be disabled in a mirror function,
> which currently does not exist. So maybe deinit_chan() needs
> adding. But where to call it from? init_chan() is called from
> stmmac_init_dma_engine(), from stmmac_hw_setup(). stmmac_resume() does
> call this. So we need something in stmmac_suspend(). Maybe in
> stmmac_stop_all_dma()?
>
> stmmac is messy, there are often not mirror functions. If there is a
> stmmac_init_dma_engine() there should be
> stmmac_deinit_dma_engine(). If there is stmmac_hw_setup() there should
> be stmmac_hw_tairdown(). But none of these seem to exist.
>
> Anyway, do you want to try to implement deinit_chan() and call it from
> stmmac_stop_all_dma()?
Yes I'd really like to implement a solution here.
This is my try, but I still have some questions:
- is it ok to disable all interrupts on deinit_chan()?
- maybe the interrupt could also just be disabled in stop_rx?
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 829a23bdad01..65c243fb829f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -125,6 +125,17 @@ static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
}
+static void dwmac410_dma_deinit_channel(struct stmmac_priv *priv,
+ void __iomem *ioaddr, u32 chan)
+{
+ const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
+ u32 value;
+
+ value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+ value &= ~DMA_CHAN_INTR_DEFAULT_MASK_4_10;
+ writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+}
+
static void dwmac4_dma_init(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg)
{
@@ -577,6 +588,7 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
.init_chan = dwmac410_dma_init_channel,
+ .deinit_chan = dwmac410_dma_deinit_channel,
.init_rx_chan = dwmac4_dma_init_rx_chan,
.init_tx_chan = dwmac4_dma_init_tx_chan,
.axi = dwmac4_dma_axi,
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index e6317b94fff7..04dafec021b4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -170,6 +170,8 @@ struct stmmac_dma_ops {
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg);
void (*init_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan);
+ void (*deinit_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
+ u32 chan);
void (*init_rx_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t phy, u32 chan);
@@ -235,6 +237,8 @@ struct stmmac_dma_ops {
stmmac_do_void_callback(__priv, dma, init, __args)
#define stmmac_init_chan(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, init_chan, __priv, __args)
+#define stmmac_deinit_chan(__priv, __args...) \
+ stmmac_do_void_callback(__priv, dma, deinit_chan, __priv, __args)
#define stmmac_init_rx_chan(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, init_rx_chan, __priv, __args)
#define stmmac_init_tx_chan(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 2a0d7eff88d3..8504ecc3dbeb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2560,13 +2560,16 @@ static void stmmac_stop_all_dma(struct stmmac_priv *priv)
{
u8 rx_channels_count = priv->plat->rx_queues_to_use;
u8 tx_channels_count = priv->plat->tx_queues_to_use;
+ u8 max_chan = max(rx_channels_count, tx_channels_count);
u8 chan;
- for (chan = 0; chan < rx_channels_count; chan++)
- stmmac_stop_rx_dma(priv, chan);
-
- for (chan = 0; chan < tx_channels_count; chan++)
- stmmac_stop_tx_dma(priv, chan);
+ for (chan = 0; chan < max_chan; chan++) {
+ if (chan < rx_channels_count)
+ stmmac_stop_rx_dma(priv, chan);
+ if (chan < tx_channels_count)
+ stmmac_stop_tx_dma(priv, chan);
+ stmmac_deinit_chan(priv, priv->ioaddr, chan);
+ }
}
/**
tresonic
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-18 7:35 ` tresonic
@ 2026-07-18 13:11 ` Maxime Chevallier
2026-07-18 13:32 ` tresonic
2026-07-18 14:06 ` Andrew Lunn
1 sibling, 1 reply; 12+ messages in thread
From: Maxime Chevallier @ 2026-07-18 13:11 UTC (permalink / raw)
To: tresonic, Andrew Lunn; +Cc: netdev, regressions, rmk+kernel, kuba
Hi,
On 7/18/26 09:35, tresonic wrote:
> Thank you for you explanations!
>
>> The interrupt is being enabled in the init_chan call in
>> stmmac_dma_ops. Ideally, it should be disabled in a mirror function,
>> which currently does not exist. So maybe deinit_chan() needs
>> adding. But where to call it from? init_chan() is called from
>> stmmac_init_dma_engine(), from stmmac_hw_setup(). stmmac_resume() does
>> call this. So we need something in stmmac_suspend(). Maybe in
>> stmmac_stop_all_dma()?
>>
>> stmmac is messy, there are often not mirror functions. If there is a
>> stmmac_init_dma_engine() there should be
>> stmmac_deinit_dma_engine(). If there is stmmac_hw_setup() there should
>> be stmmac_hw_tairdown(). But none of these seem to exist.
>>
(sorry I missed that thread, I was on my way back from netdev)
>> Anyway, do you want to try to implement deinit_chan() and call it from
>> stmmac_stop_all_dma()?
> Yes I'd really like to implement a solution here.
> This is my try, but I still have some questions:
> - is it ok to disable all interrupts on deinit_chan()?
It mirrors the init, so it should be fine. Now I'm not sure how that
will interfere with things like WoL though, I've yet to test this.
> - maybe the interrupt could also just be disabled in stop_rx?
I don't think so, if something is missing w.r.t the interrupts being
enabled when they shouldn't, that would need to be addressed in the
xdp part, as this seems to be the only place where stop_rx is called
without the dma_chan interrupts being masked.
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> index 829a23bdad01..65c243fb829f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
[...]
I've given this patch a test on imx8mp (that has a dwmac4.10), no regressions found
from running basic tests :) I think this is a good fix, if you submit it can you
address both dwmac410 and dwmac4 ? They both should be impacted by that problem.
Maxime
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-18 13:11 ` Maxime Chevallier
@ 2026-07-18 13:32 ` tresonic
2026-07-18 14:11 ` Andrew Lunn
0 siblings, 1 reply; 12+ messages in thread
From: tresonic @ 2026-07-18 13:32 UTC (permalink / raw)
To: Maxime Chevallier, Andrew Lunn; +Cc: netdev, regressions, rmk+kernel, kuba
Hi, thanks for testing and feedback!
> I've given this patch a test on imx8mp (that has a dwmac4.10), no regressions found
> from running basic tests :) I think this is a good fix, if you submit it can you
> address both dwmac410 and dwmac4 ? They both should be impacted by that problem.
I've added the deinit_chan for dwmac4.
Sorry for the noob question, how would I submit this fix?
Just commit and separately git send-email to netdev@vger.kernel.org?
These are my currernt changes:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 829a23bdad01..23ffe1adcd0d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -106,6 +106,17 @@ static void dwmac4_dma_init_channel(struct stmmac_priv *priv,
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
}
+static void dwmac4_dma_deinit_channel(struct stmmac_priv *priv,
+ void __iomem *ioaddr, u32 chan)
+{
+ const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
+ u32 value;
+
+ value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+ value &= ~DMA_CHAN_INTR_DEFAULT_MASK;
+ writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+}
+
static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan)
@@ -125,6 +136,17 @@ static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
}
+static void dwmac410_dma_deinit_channel(struct stmmac_priv *priv,
+ void __iomem *ioaddr, u32 chan)
+{
+ const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
+ u32 value;
+
+ value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+ value &= ~DMA_CHAN_INTR_DEFAULT_MASK_4_10;
+ writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+}
+
static void dwmac4_dma_init(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg)
{
@@ -548,6 +570,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
.init_chan = dwmac4_dma_init_channel,
+ .deinit_chan = dwmac4_dma_deinit_channel,
.init_rx_chan = dwmac4_dma_init_rx_chan,
.init_tx_chan = dwmac4_dma_init_tx_chan,
.axi = dwmac4_dma_axi,
@@ -577,6 +600,7 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
.init_chan = dwmac410_dma_init_channel,
+ .deinit_chan = dwmac410_dma_deinit_channel,
.init_rx_chan = dwmac4_dma_init_rx_chan,
.init_tx_chan = dwmac4_dma_init_tx_chan,
.axi = dwmac4_dma_axi,
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index e6317b94fff7..04dafec021b4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -170,6 +170,8 @@ struct stmmac_dma_ops {
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg);
void (*init_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan);
+ void (*deinit_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
+ u32 chan);
void (*init_rx_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t phy, u32 chan);
@@ -235,6 +237,8 @@ struct stmmac_dma_ops {
stmmac_do_void_callback(__priv, dma, init, __args)
#define stmmac_init_chan(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, init_chan, __priv, __args)
+#define stmmac_deinit_chan(__priv, __args...) \
+ stmmac_do_void_callback(__priv, dma, deinit_chan, __priv, __args)
#define stmmac_init_rx_chan(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, init_rx_chan, __priv, __args)
#define stmmac_init_tx_chan(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 2a0d7eff88d3..8504ecc3dbeb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2560,13 +2560,16 @@ static void stmmac_stop_all_dma(struct stmmac_priv *priv)
{
u8 rx_channels_count = priv->plat->rx_queues_to_use;
u8 tx_channels_count = priv->plat->tx_queues_to_use;
+ u8 max_chan = max(rx_channels_count, tx_channels_count);
u8 chan;
- for (chan = 0; chan < rx_channels_count; chan++)
- stmmac_stop_rx_dma(priv, chan);
-
- for (chan = 0; chan < tx_channels_count; chan++)
- stmmac_stop_tx_dma(priv, chan);
+ for (chan = 0; chan < max_chan; chan++) {
+ if (chan < rx_channels_count)
+ stmmac_stop_rx_dma(priv, chan);
+ if (chan < tx_channels_count)
+ stmmac_stop_tx_dma(priv, chan);
+ stmmac_deinit_chan(priv, priv->ioaddr, chan);
+ }
}
/**
tresonic
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-18 7:35 ` tresonic
2026-07-18 13:11 ` Maxime Chevallier
@ 2026-07-18 14:06 ` Andrew Lunn
1 sibling, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2026-07-18 14:06 UTC (permalink / raw)
To: tresonic; +Cc: netdev, regressions, rmk+kernel, kuba, Maxime Chevallier
> {
> u8 rx_channels_count = priv->plat->rx_queues_to_use;
> u8 tx_channels_count = priv->plat->tx_queues_to_use;
> + u8 max_chan = max(rx_channels_count, tx_channels_count);
> u8 chan;
>
> - for (chan = 0; chan < rx_channels_count; chan++)
> - stmmac_stop_rx_dma(priv, chan);
> -
> - for (chan = 0; chan < tx_channels_count; chan++)
> - stmmac_stop_tx_dma(priv, chan);
> + for (chan = 0; chan < max_chan; chan++) {
> + if (chan < rx_channels_count)
> + stmmac_stop_rx_dma(priv, chan);
> + if (chan < tx_channels_count)
> + stmmac_stop_tx_dma(priv, chan);
> + stmmac_deinit_chan(priv, priv->ioaddr, chan);
> + }
It is a personal preference, but i would keep the code simple, stupid,
KISS.
Keep the two loops as they are. And add a third loop calling
stmmac_deinit_chan(). That then mirrors the code in
stmmac_init_dma_engine() which also has three loops.
I would also rename max_chan to dma_csr_ch so it has the same name as
in stmmac_init_dma_engine(). As i said, stmmac has pretty bad naming,
mirror functions are not obvious, but when adding new code, we should
try to do better.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
2026-07-18 13:32 ` tresonic
@ 2026-07-18 14:11 ` Andrew Lunn
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2026-07-18 14:11 UTC (permalink / raw)
To: tresonic; +Cc: Maxime Chevallier, netdev, regressions, rmk+kernel, kuba
> Sorry for the noob question, how would I submit this fix?
There are two documents for you to read:
https://docs.kernel.org/process/submitting-patches.html
https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html
Since this is a fix, please use the net tree. And include a Fixes: tag
indicating the patch which broke it.
> Just commit and separately git send-email to netdev@vger.kernel.org?
./scripts/get_maintainer.pl will give you a list of email addresses.
Or take a look at
https://b4.docs.kernel.org/en/latest/contributor/prep.html
b4 automates some of the steps in producing patches, keeping track of
versions, working out who to send to etc.
Often with the kernel, the code is easy. Getting the processes correct
is harder. But we are here to help.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-07-18 14:11 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 20:10 [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts") tresonic
2026-07-16 21:47 ` Andrew Lunn
2026-07-17 7:18 ` tresonic
2026-07-17 15:40 ` Andrew Lunn
2026-07-17 22:23 ` tresonic
2026-07-17 22:34 ` tresonic
2026-07-18 0:16 ` Andrew Lunn
2026-07-18 7:35 ` tresonic
2026-07-18 13:11 ` Maxime Chevallier
2026-07-18 13:32 ` tresonic
2026-07-18 14:11 ` Andrew Lunn
2026-07-18 14:06 ` Andrew Lunn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox