aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2017-05-16 17:00:14 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-17 16:06:01 -0400
commit9a568de4818dea9a05af141046bd3e589245ab83 (patch)
tree6f1502edf55ecb7205660d62bd683ebcf912cfea /net/ipv4/tcp_ipv4.c
parentac9517fcf310327fa3e3b0d8366e4b11236b1b4b (diff)
tcp: switch TCP TS option (RFC 7323) to 1ms clock
TCP Timestamps option is defined in RFC 7323 Traditionally on linux, it has been tied to the internal 'jiffies' variable, because it had been a cheap and good enough generator. For TCP flows on the Internet, 1 ms resolution would be much better than 4ms or 10ms (HZ=250 or HZ=100 respectively) For TCP flows in the DC, Google has used usec resolution for more than two years with great success [1] Receive size autotuning (DRS) is indeed more precise and converges faster to optimal window size. This patch converts tp->tcp_mstamp to a plain u64 value storing a 1 usec TCP clock. This choice will allow us to upstream the 1 usec TS option as discussed in IETF 97. [1] https://www.ietf.org/proceedings/97/slides/slides-97-tcpm-tcp-options-for-low-latency-00.pdf Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Soheil Hassas Yeganeh <soheil@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d8fe25db79f2..191b2f78b19d 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -376,8 +376,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
376 struct sock *sk; 376 struct sock *sk;
377 struct sk_buff *skb; 377 struct sk_buff *skb;
378 struct request_sock *fastopen; 378 struct request_sock *fastopen;
379 __u32 seq, snd_una; 379 u32 seq, snd_una;
380 __u32 remaining; 380 s32 remaining;
381 u32 delta_us;
381 int err; 382 int err;
382 struct net *net = dev_net(icmp_skb->dev); 383 struct net *net = dev_net(icmp_skb->dev);
383 384
@@ -483,12 +484,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
483 skb = tcp_write_queue_head(sk); 484 skb = tcp_write_queue_head(sk);
484 BUG_ON(!skb); 485 BUG_ON(!skb);
485 486
486 skb_mstamp_get(&tp->tcp_mstamp); 487 tcp_mstamp_refresh(tp);
488 delta_us = (u32)(tp->tcp_mstamp - skb->skb_mstamp);
487 remaining = icsk->icsk_rto - 489 remaining = icsk->icsk_rto -
488 min(icsk->icsk_rto, 490 usecs_to_jiffies(delta_us);
489 tcp_time_stamp - tcp_skb_timestamp(skb));
490 491
491 if (remaining) { 492 if (remaining > 0) {
492 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 493 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
493 remaining, TCP_RTO_MAX); 494 remaining, TCP_RTO_MAX);
494 } else { 495 } else {
@@ -812,7 +813,7 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
812 tcp_v4_send_ack(sk, skb, 813 tcp_v4_send_ack(sk, skb,
813 tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 814 tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
814 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 815 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
815 tcp_time_stamp + tcptw->tw_ts_offset, 816 tcp_time_stamp_raw() + tcptw->tw_ts_offset,
816 tcptw->tw_ts_recent, 817 tcptw->tw_ts_recent,
817 tw->tw_bound_dev_if, 818 tw->tw_bound_dev_if,
818 tcp_twsk_md5_key(tcptw), 819 tcp_twsk_md5_key(tcptw),
@@ -840,7 +841,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
840 tcp_v4_send_ack(sk, skb, seq, 841 tcp_v4_send_ack(sk, skb, seq,
841 tcp_rsk(req)->rcv_nxt, 842 tcp_rsk(req)->rcv_nxt,
842 req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, 843 req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
843 tcp_time_stamp + tcp_rsk(req)->ts_off, 844 tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
844 req->ts_recent, 845 req->ts_recent,
845 0, 846 0,
846 tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr, 847 tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr,