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: Signed-off-by: Shiming Cheng --- 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