net/ipv4/tcp_offload.c | 1 + 1 file changed, 1 insertion(+)
From: HW He <hw.he@mediatek.com>
On devices that support both NETIF_F_GRO_HW and NETIF_F_GRO_FRAGLIST,
the hardware or driver may deliver packets that have already been
aggregated into a TCP GSO skb with frags[]. GRO may then
aggregate the skb again in skb_gro_receive_list().
This can create a nested GSO skb, which is not handled correctly by the
later GSO segmentation paths. When the skb is segmented by
skb_segment_list(), it not be fully restored to the original packets.
Avoid this by setting NAPI_GRO_CB(skb)->flush for GSO skbs before
aggregation.
Signed-off-by: HW He <hw.he@mediatek.com>
Signed-off-by: Zhaoping Shu <zhaoping.shu@mediatek.com>
---
v2: Take Antoine Tenart's suggestion
v1: https://lore.kernel.org/netdev/amB7wb1A2Oo2dv5d@kwain/
---
net/ipv4/tcp_offload.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index 3b1fdcd3cb29..c363434a5646 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -332,6 +332,7 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
flush |= skb->ip_summed != p->ip_summed;
flush |= skb->csum_level != p->csum_level;
flush |= NAPI_GRO_CB(p)->count >= 64;
+ NAPI_GRO_CB(skb)->flush |= skb_is_gso(skb);
skb_set_network_header(skb, skb_gro_receive_network_offset(skb));
if (flush || skb_gro_receive_list(p, skb))
--
2.17.0
On Thu, 23 Jul 2026 17:16:01 +0800 zhaoping.shu@mediatek.com wrote: > From: HW He <hw.he@mediatek.com> > > On devices that support both NETIF_F_GRO_HW and NETIF_F_GRO_FRAGLIST, "devices that support FRAGLIST"? Isn't it a software feature? > the hardware or driver may deliver packets that have already been If you have a driver in mind please name it. > aggregated into a TCP GSO skb with frags[]. GRO may then > aggregate the skb again in skb_gro_receive_list(). > > This can create a nested GSO skb, which is not handled correctly by the > later GSO segmentation paths. When the skb is segmented by > skb_segment_list(), it not be fully restored to the original packets. > > Avoid this by setting NAPI_GRO_CB(skb)->flush for GSO skbs before > aggregation. I don't think we can do this. For GRO_HW devices re-aggregating in SW is quite helpful, HW often runs out of contexts or times out too soon, generating skbs with 16kB..32kB of data, the SW can help bring it up to full TSO. Also - you're missing a Fixes tag.
On Thu, Jul 23, 2026 at 3:39 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Thu, 23 Jul 2026 17:16:01 +0800 zhaoping.shu@mediatek.com wrote:
> > From: HW He <hw.he@mediatek.com>
> >
> > On devices that support both NETIF_F_GRO_HW and NETIF_F_GRO_FRAGLIST,
>
> "devices that support FRAGLIST"? Isn't it a software feature?
>
> > the hardware or driver may deliver packets that have already been
>
> If you have a driver in mind please name it.
>
> > aggregated into a TCP GSO skb with frags[]. GRO may then
> > aggregate the skb again in skb_gro_receive_list().
> >
> > This can create a nested GSO skb, which is not handled correctly by the
> > later GSO segmentation paths. When the skb is segmented by
> > skb_segment_list(), it not be fully restored to the original packets.
> >
> > Avoid this by setting NAPI_GRO_CB(skb)->flush for GSO skbs before
> > aggregation.
>
> I don't think we can do this. For GRO_HW devices re-aggregating
> in SW is quite helpful, HW often runs out of contexts or times
> out too soon, generating skbs with 16kB..32kB of data, the SW
> can help bring it up to full TSO.
Also, after e751256486d0 ("net: gro: fix double aggregation of
flush-marked skbs"), it's not clear an another bug remains.
If it is: as said "nested GRO" of hw + sw GRO is intentional, e.g., for BIG-TCP.
But it may not be anticipated for skb_gro_receive_list. One option
would be to skip the fraglist GSO optimization for such packets.
First I'd like to understand better what exact bug remains.
© 2016 - 2026 Red Hat, Inc.