[PATCH] net: tcp: fix fraglist GRO flushing on alternating TCP PSH flag

From: Shiming Cheng

Date: Fri Oct 09 2026 - 02:09:03 EST


In forwarding and tethering scenarios where fraglist GRO (is_flist) is
enabled, TCP packet aggregation frequently fails when packets arrive
with alternating PSH flags.

Specifically, when a sender alternates between [ACK] and [PSH, ACK]
segments, tcpdump reveals that no aggregation occurs:

Before this patch:
... [ACK] Seq=10835225 Len=1348
... [PSH, ACK] Seq=10836573 Len=1348 <-- Triggers premature flush
... [ACK] Seq=10837921 Len=1348
... [PSH, ACK] Seq=10839269 Len=1348 <-- Triggers premature flush

The general GRO path allows the aggregation of packets with different
PSH/FIN flags by masking them out at the beginning of `tcp_gro_receive`.
However, the fraglist GRO path (is_flist) still enforces an unmasked
flags comparison: `flush |= (__force int)(flags ^ tcp_flag_word(th2))`.
This redundant check causes premature flushing on any incoming PSH packet,
shattering aggregation and increasing softirq overhead.

After this patch, the redundant flags check is removed from the `is_flist`
branch. The [ACK] and [PSH, ACK] packets are successfully aggregated into
a single fraglist, and are safely flushed together upon encountering the
PSH flag at `out_check_final`, preserving the required TCP push semantics.

Fixes: 8d95dc474f85 ("net: add code for TCP fraglist GRO")
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Shiming Cheng <shiming.cheng@xxxxxxxxxxxx>
---
net/ipv4/tcp_offload.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index e74d99ca9fac..54b40ec95a08 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -328,7 +328,6 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
flush |= skb_cmp_decrypted(p, skb);

if (unlikely(NAPI_GRO_CB(p)->is_flist)) {
- flush |= (__force int)(flags ^ tcp_flag_word(th2));
flush |= skb->ip_summed != p->ip_summed;
flush |= skb->csum_level != p->csum_level;
flush |= NAPI_GRO_CB(p)->count >= 64;
--
2.45.2