Skip to content

Commit 9c25aae

Browse files
edumazetkuba-moo
authored andcommitted
tcp: fix tcp_disordered_ack() vs usec TS resolution
After commit 9394630 ("tcp: change data receiver flowlabel after one dup") we noticed an increase of TCPACKSkippedPAWS events. Neal Cardwell tracked the issue to tcp_disordered_ack() assumption about remote peer TS clock. RFC 1323 & 7323 are suggesting the following: "timestamp clock frequency in the range 1 ms to 1 sec per tick between 1ms and 1sec." This has to be adjusted for 1 MHz clock frequency. This hints at reorders of SACK packets on send side, this might deserve a future patch. (skb->ooo_okay is always set for pure ACK packets) Fixes: 614e831 ("tcp: add support for usec resolution in TCP TS values") Co-developed-by: Neal Cardwell <[email protected]> Signed-off-by: Neal Cardwell <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Cc: David Morley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a45f1e4 commit 9c25aae

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

net/ipv4/tcp_input.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4368,14 +4368,31 @@ EXPORT_SYMBOL(tcp_do_parse_auth_options);
43684368
* up to bandwidth of 18Gigabit/sec. 8) ]
43694369
*/
43704370

4371+
/* Estimates max number of increments of remote peer TSval in
4372+
* a replay window (based on our current RTO estimation).
4373+
*/
4374+
static u32 tcp_tsval_replay(const struct sock *sk)
4375+
{
4376+
/* If we use usec TS resolution,
4377+
* then expect the remote peer to use the same resolution.
4378+
*/
4379+
if (tcp_sk(sk)->tcp_usec_ts)
4380+
return inet_csk(sk)->icsk_rto * (USEC_PER_SEC / HZ);
4381+
4382+
/* RFC 7323 recommends a TSval clock between 1ms and 1sec.
4383+
* We know that some OS (including old linux) can use 1200 Hz.
4384+
*/
4385+
return inet_csk(sk)->icsk_rto * 1200 / HZ;
4386+
}
4387+
43714388
static int tcp_disordered_ack(const struct sock *sk, const struct sk_buff *skb)
43724389
{
43734390
const struct tcp_sock *tp = tcp_sk(sk);
43744391
const struct tcphdr *th = tcp_hdr(skb);
43754392
u32 seq = TCP_SKB_CB(skb)->seq;
43764393
u32 ack = TCP_SKB_CB(skb)->ack_seq;
43774394

4378-
return (/* 1. Pure ACK with correct sequence number. */
4395+
return /* 1. Pure ACK with correct sequence number. */
43794396
(th->ack && seq == TCP_SKB_CB(skb)->end_seq && seq == tp->rcv_nxt) &&
43804397

43814398
/* 2. ... and duplicate ACK. */
@@ -4385,7 +4402,8 @@ static int tcp_disordered_ack(const struct sock *sk, const struct sk_buff *skb)
43854402
!tcp_may_update_window(tp, ack, seq, ntohs(th->window) << tp->rx_opt.snd_wscale) &&
43864403

43874404
/* 4. ... and sits in replay window. */
4388-
(s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) <= (inet_csk(sk)->icsk_rto * 1024) / HZ);
4405+
(s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) <=
4406+
tcp_tsval_replay(sk);
43894407
}
43904408

43914409
static inline bool tcp_paws_discard(const struct sock *sk,

0 commit comments

Comments
 (0)