aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2013-07-22 19:20:45 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-22 20:53:42 -0400
commit375fe02c91792917aa26d68a87ab110d1937f44e (patch)
tree2a6c1205f6b136f7ac55f191912b386a0f3b2491
parentc3f51d5f387b552b9d9fd7f41e19b84929712f82 (diff)
tcp: consolidate SYNACK RTT sampling
The first patch consolidates SYNACK and other RTT measurement to use a central function tcp_ack_update_rtt(). A (small) bonus is now SYNACK RTT measurement happens after PAWS check, potentially reducing the impact of RTO seeding on bad TCP timestamps values. Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/tcp.h9
-rw-r--r--net/ipv4/tcp_input.c14
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_minisocks.c8
-rw-r--r--net/ipv6/tcp_ipv6.c2
5 files changed, 14 insertions, 21 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index d1980054ec75..f9777dbede75 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1094,15 +1094,6 @@ static inline void tcp_openreq_init(struct request_sock *req,
1094 ireq->loc_port = tcp_hdr(skb)->dest; 1094 ireq->loc_port = tcp_hdr(skb)->dest;
1095} 1095}
1096 1096
1097/* Compute time elapsed between SYNACK and the ACK completing 3WHS */
1098static inline void tcp_synack_rtt_meas(struct sock *sk,
1099 struct request_sock *req)
1100{
1101 if (tcp_rsk(req)->snt_synack)
1102 tcp_valid_rtt_meas(sk,
1103 tcp_time_stamp - tcp_rsk(req)->snt_synack);
1104}
1105
1106extern void tcp_enter_memory_pressure(struct sock *sk); 1097extern void tcp_enter_memory_pressure(struct sock *sk);
1107 1098
1108static inline int keepalive_intvl_when(const struct tcp_sock *tp) 1099static inline int keepalive_intvl_when(const struct tcp_sock *tp)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 28af45abe062..b531710596ec 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2853,6 +2853,17 @@ static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
2853 tcp_ack_no_tstamp(sk, seq_rtt, flag); 2853 tcp_ack_no_tstamp(sk, seq_rtt, flag);
2854} 2854}
2855 2855
2856/* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */
2857static void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req)
2858{
2859 struct tcp_sock *tp = tcp_sk(sk);
2860 s32 seq_rtt = -1;
2861
2862 if (tp->lsndtime && !tp->total_retrans)
2863 seq_rtt = tcp_time_stamp - tp->lsndtime;
2864 tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt);
2865}
2866
2856static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) 2867static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
2857{ 2868{
2858 const struct inet_connection_sock *icsk = inet_csk(sk); 2869 const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -5624,9 +5635,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5624 * so release it. 5635 * so release it.
5625 */ 5636 */
5626 if (req) { 5637 if (req) {
5627 tcp_synack_rtt_meas(sk, req);
5628 tp->total_retrans = req->num_retrans; 5638 tp->total_retrans = req->num_retrans;
5629
5630 reqsk_fastopen_remove(sk, req, false); 5639 reqsk_fastopen_remove(sk, req, false);
5631 } else { 5640 } else {
5632 /* Make sure socket is routed, for correct metrics. */ 5641 /* Make sure socket is routed, for correct metrics. */
@@ -5651,6 +5660,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5651 tp->snd_una = TCP_SKB_CB(skb)->ack_seq; 5660 tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
5652 tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale; 5661 tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale;
5653 tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); 5662 tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
5663 tcp_synack_rtt_meas(sk, req);
5654 5664
5655 if (tp->rx_opt.tstamp_ok) 5665 if (tp->rx_opt.tstamp_ok)
5656 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; 5666 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index b299da5ff499..2e3f129df0eb 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1671,8 +1671,6 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1671 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; 1671 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
1672 1672
1673 tcp_initialize_rcv_mss(newsk); 1673 tcp_initialize_rcv_mss(newsk);
1674 tcp_synack_rtt_meas(newsk, req);
1675 newtp->total_retrans = req->num_retrans;
1676 1674
1677#ifdef CONFIG_TCP_MD5SIG 1675#ifdef CONFIG_TCP_MD5SIG
1678 /* Copy over the MD5 key from the original socket */ 1676 /* Copy over the MD5 key from the original socket */
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index ab1c08658528..58a3e69aef64 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -411,6 +411,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
411 newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH; 411 newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
412 tcp_enable_early_retrans(newtp); 412 tcp_enable_early_retrans(newtp);
413 newtp->tlp_high_seq = 0; 413 newtp->tlp_high_seq = 0;
414 newtp->lsndtime = treq->snt_synack;
415 newtp->total_retrans = req->num_retrans;
414 416
415 /* So many TCP implementations out there (incorrectly) count the 417 /* So many TCP implementations out there (incorrectly) count the
416 * initial SYN frame in their delayed-ACK and congestion control 418 * initial SYN frame in their delayed-ACK and congestion control
@@ -666,12 +668,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
666 if (!(flg & TCP_FLAG_ACK)) 668 if (!(flg & TCP_FLAG_ACK))
667 return NULL; 669 return NULL;
668 670
669 /* Got ACK for our SYNACK, so update baseline for SYNACK RTT sample. */
670 if (tmp_opt.saw_tstamp && tmp_opt.rcv_tsecr)
671 tcp_rsk(req)->snt_synack = tmp_opt.rcv_tsecr;
672 else if (req->num_retrans) /* don't take RTT sample if retrans && ~TS */
673 tcp_rsk(req)->snt_synack = 0;
674
675 /* For Fast Open no more processing is needed (sk is the 671 /* For Fast Open no more processing is needed (sk is the
676 * child socket). 672 * child socket).
677 */ 673 */
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 6e1649d58533..80fe69ef2188 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1237,8 +1237,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1237 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; 1237 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
1238 1238
1239 tcp_initialize_rcv_mss(newsk); 1239 tcp_initialize_rcv_mss(newsk);
1240 tcp_synack_rtt_meas(newsk, req);
1241 newtp->total_retrans = req->num_retrans;
1242 1240
1243 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; 1241 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
1244 newinet->inet_rcv_saddr = LOOPBACK4_IPV6; 1242 newinet->inet_rcv_saddr = LOOPBACK4_IPV6;