tcp: preserve timestamps across receive queue collapse

When tcp_collapse() rebuilds skbs under memory pressure, the copy
process doesn't include the right tstamp and hwtstamp from the
old skb. And memcpy(nskb->cb, skb->cb, ...) copies has_rxtstamp,
but nskb->tstamp and hwtstamps are left at zero, so
tcp_recv_timestamp() ends up emitting no cmsg at all.

In net timestamping case, if such an skb happens to be the last
one consumed in a recvmsg() call, the application receives no RX
timestamp for that call.

Fix this by copying both tstamp and hwtstamp of the last skb to
the new skb, matching tcp_try_coalesce()/tcp_add_backlog().

Note that the has_rxtstamp flag can still be inherited through
the cb memcpy from an skb that contributes no bytes (fully covered
skb left in the ofo tree by the tcp_ooo_try_coalesce() ->
coalesce_done path), so set TCP_SKB_CB(nskb)->has_rxtstamp to false
which makes the new block the only place setting it.

Signed-off-by: Jason Xing <kerneljasonxing@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20260924152529.5689-1-kerneljasonxing@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jason Xing 2026-09-24 23:25:29 +08:00 • committed by Jakub Kicinski
commit 1a924ab28f