* [PATCH net] net: stmmac: do not cache the new TSO MSS before it reaches the DMA
@ 2026-09-17 12:42 Linkui Xiao
2026-09-17 17:37 ` Lorenzo Bianconi
0 siblings, 1 reply; 3+ messages in thread
From: Linkui Xiao @ 2026-09-17 12:42 UTC (permalink / raw)
To: maxime.chevallier, andrew+netdev, davem, edumazet, kuba, pabeni,
mcoquelin.stm32, alexandre.torgue
Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel, Linkui Xiao,
stable
From: Linkui Xiao <xiaolinkui@kylinos.cn>
stmmac_tso_xmit() fills the MSS context descriptor and stores the new
MSS in tx_q->mss right away, but the descriptor only gets its OWN bit
much later, right before the frame is handed to the DMA. Every error
path in between - the dma_map_single() of the linear part and the
skb_frag_dma_map() of each fragment - returns with tx_q->mss already
updated while the MAC is still programmed with the previous MSS; the
abandoned context descriptor is later reclaimed by stmmac_tx_clean().
The next skb carrying the same MSS then compares equal to the cached
value, so no context descriptor is emitted and the hardware segments
the TCP stream with a stale MSS, generating frames whose payload size
does not match what the stack accounted for.
Only update tx_q->mss once the context descriptor has been given to the
DMA so that the cached value always describes what the hardware is
actually programmed with.
Fixes: f748be531d70 ("stmmac: support new GMAC4")
Cc: stable@vger.kernel.org
Signed-off-by: Linkui Xiao <xiaolinkui@kylinos.cn>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index af2d38a2bb3d..a8f94cd6abb4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4563,7 +4563,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
mss_desc = &tx_q->dma_tx[tx_q->cur_tx];
stmmac_set_mss(priv, mss_desc, mss);
- tx_q->mss = mss;
tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx,
priv->dma_conf.dma_tx_size);
WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
@@ -4714,6 +4713,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
*/
dma_wmb();
stmmac_set_tx_owner(priv, mss_desc);
+ tx_q->mss = mss;
}
if (netif_msg_pktdata(priv)) {
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH net] net: stmmac: do not cache the new TSO MSS before it reaches the DMA 2026-09-17 12:42 [PATCH net] net: stmmac: do not cache the new TSO MSS before it reaches the DMA Linkui Xiao @ 2026-09-17 17:37 ` Lorenzo Bianconi 2026-09-18 10:32 ` Linkui Xiao 0 siblings, 1 reply; 3+ messages in thread From: Lorenzo Bianconi @ 2026-09-17 17:37 UTC (permalink / raw) To: Linkui Xiao Cc: maxime.chevallier, andrew+netdev, davem, edumazet, kuba, pabeni, mcoquelin.stm32, alexandre.torgue, netdev, linux-stm32, linux-arm-kernel, linux-kernel, Linkui Xiao, stable [-- Attachment #1: Type: text/plain, Size: 2517 bytes --] > From: Linkui Xiao <xiaolinkui@kylinos.cn> > > stmmac_tso_xmit() fills the MSS context descriptor and stores the new > MSS in tx_q->mss right away, but the descriptor only gets its OWN bit > much later, right before the frame is handed to the DMA. Every error > path in between - the dma_map_single() of the linear part and the > skb_frag_dma_map() of each fragment - returns with tx_q->mss already > updated while the MAC is still programmed with the previous MSS; the > abandoned context descriptor is later reclaimed by stmmac_tx_clean(). > > The next skb carrying the same MSS then compares equal to the cached > value, so no context descriptor is emitted and the hardware segments > the TCP stream with a stale MSS, generating frames whose payload size > does not match what the stack accounted for. > > Only update tx_q->mss once the context descriptor has been given to the > DMA so that the cached value always describes what the hardware is > actually programmed with. > > Fixes: f748be531d70 ("stmmac: support new GMAC4") > Cc: stable@vger.kernel.org > Signed-off-by: Linkui Xiao <xiaolinkui@kylinos.cn> > --- > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > index af2d38a2bb3d..a8f94cd6abb4 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > @@ -4563,7 +4563,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) > mss_desc = &tx_q->dma_tx[tx_q->cur_tx]; > > stmmac_set_mss(priv, mss_desc, mss); > - tx_q->mss = mss; > tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, > priv->dma_conf.dma_tx_size); > WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); > @@ -4714,6 +4713,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) > */ > dma_wmb(); > stmmac_set_tx_owner(priv, mss_desc); > + tx_q->mss = mss; I think the issue is real. A couple of comments: - do you think we should run stmmac_release_tx_desc() on mss descritpr in order to clean it up? - I guess we should use the same approach used for data descriptor and advance tx_q->cur_tx when there are no other possible error condition. What do you think? Regards, Lorenzo > } > > if (netif_msg_pktdata(priv)) { > -- > 2.25.1 > > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] net: stmmac: do not cache the new TSO MSS before it reaches the DMA 2026-09-17 17:37 ` Lorenzo Bianconi @ 2026-09-18 10:32 ` Linkui Xiao 0 siblings, 0 replies; 3+ messages in thread From: Linkui Xiao @ 2026-09-18 10:32 UTC (permalink / raw) To: Lorenzo Bianconi Cc: maxime.chevallier, andrew+netdev, davem, edumazet, kuba, pabeni, mcoquelin.stm32, alexandre.torgue, netdev, linux-stm32, linux-arm-kernel, linux-kernel, Linkui Xiao, stable Hi Lorenzo, thanks for the review. On 2026/9/18 01:37, Lorenzo Bianconi wrote: >> From: Linkui Xiao <xiaolinkui@kylinos.cn> >> >> stmmac_tso_xmit() fills the MSS context descriptor and stores the new >> MSS in tx_q->mss right away, but the descriptor only gets its OWN bit >> much later, right before the frame is handed to the DMA. Every error >> path in between - the dma_map_single() of the linear part and the >> skb_frag_dma_map() of each fragment - returns with tx_q->mss already >> updated while the MAC is still programmed with the previous MSS; the >> abandoned context descriptor is later reclaimed by stmmac_tx_clean(). >> >> The next skb carrying the same MSS then compares equal to the cached >> value, so no context descriptor is emitted and the hardware segments >> the TCP stream with a stale MSS, generating frames whose payload size >> does not match what the stack accounted for. >> >> Only update tx_q->mss once the context descriptor has been given to the >> DMA so that the cached value always describes what the hardware is >> actually programmed with. >> >> Fixes: f748be531d70 ("stmmac: support new GMAC4") >> Cc: stable@vger.kernel.org >> Signed-off-by: Linkui Xiao <xiaolinkui@kylinos.cn> >> --- >> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> index af2d38a2bb3d..a8f94cd6abb4 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> @@ -4563,7 +4563,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) >> mss_desc = &tx_q->dma_tx[tx_q->cur_tx]; >> >> stmmac_set_mss(priv, mss_desc, mss); >> - tx_q->mss = mss; >> tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, >> priv->dma_conf.dma_tx_size); >> WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); >> @@ -4714,6 +4713,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) >> */ >> dma_wmb(); >> stmmac_set_tx_owner(priv, mss_desc); >> + tx_q->mss = mss; > > I think the issue is real. A couple of comments: > - do you think we should run stmmac_release_tx_desc() on mss descritpr in order > to clean it up? > - I guess we should use the same approach used for data descriptor and advance > tx_q->cur_tx when there are no other possible error condition. What do you > think? I started from your second suggestion, because that is the one that makes the error handling consistent: tx_q->cur_tx is no longer advanced while the context descriptor is being filled, it moves past it together with the data descriptors, exactly like stmmac_xmit() does. On failure the ring index is therefore still where it was and there is nothing to unwind. That in turn makes your first suggestion mandatory rather than optional. stmmac_tx_clean() walks the ring until it reaches tx_q->cur_tx, and the context descriptor now sits exactly at the slot cur_tx points to, so the cleaner cannot reach it and a descriptor tagged with CTXT|TCMSSV would stay in the ring until the slot is reused. The error paths release it explicitly instead, using the same helper the cleaner uses for descriptors. OWN is never granted on that descriptor on these paths, so zeroing des0-des3 cannot race with the DMA engine. Concretely, v2: - keeps tx_q->cur_tx untouched while the context descriptor is filled and lets it advance together with the data descriptors; - moves first_entry past the context slot, so the error_dma_unmap unwind loop does not call stmmac_free_tx_buffer() on a slot that has no skb attached, and is_last_segment = CIRC_CNT(tx_q->cur_tx, first_entry, ...) == 1 keeps the correct value for single descriptor frames; - updates tx_q->mss only after stmmac_set_tx_owner(mss_desc); - releases the context descriptor at the common "error:" label, which covers both the dma_map_single() of the linear part and the skb_frag_dma_map() of every fragment. Nothing else changes. first_tx is sampled before the context descriptor is allocated, so the tx_packets accounting used by the coalescing logic is unaffected, and stmmac_tso_get_num_desc() already counts the context descriptor, so the stmmac_tx_avail() check is unchanged as well. The WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]) that followed the old cur_tx update is dropped: it checked the first data slot, which the WARN_ON on tx_q->tx_skbuff[entry] right after the first_entry assignment already covers. v2 follows in a moment. Regards, Linkui > > Regards, > Lorenzo > >> } >> >> if (netif_msg_pktdata(priv)) { >> -- >> 2.25.1 >> >> ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-18 10:34 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-17 12:42 [PATCH net] net: stmmac: do not cache the new TSO MSS before it reaches the DMA Linkui Xiao 2026-09-17 17:37 ` Lorenzo Bianconi 2026-09-18 10:32 ` Linkui Xiao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox