aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2013-10-24 11:44:25 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-27 16:50:06 -0400
commitbc15afa39ecc16f01c3389d15d8f6015a427fe85 (patch)
tree37c5d23049eaa8ec76fd79f4a8afc13a2bdbb3c5 /net/ipv4/tcp_input.c
parente9e2a904ef0a4f46ee5c845f3ae04e62b917bb6d (diff)
tcp: fix SYNACK RTT estimation in Fast Open
tp->lsndtime may not always be the SYNACK timestamp if a passive Fast Open socket sends data before handshake completes. And if the remote acknowledges both the data and the SYNACK, the RTT sample is already taken in tcp_ack(), so no need to call tcp_update_ack_rtt() in tcp_synack_rtt_meas() aagain. Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Neal Cardwell <ncardwell@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a16b01b537ba..305cd0526a78 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2871,14 +2871,19 @@ static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
2871} 2871}
2872 2872
2873/* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */ 2873/* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */
2874static void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req) 2874static void tcp_synack_rtt_meas(struct sock *sk, const u32 synack_stamp)
2875{ 2875{
2876 struct tcp_sock *tp = tcp_sk(sk); 2876 struct tcp_sock *tp = tcp_sk(sk);
2877 s32 seq_rtt = -1; 2877 s32 seq_rtt = -1;
2878 2878
2879 if (tp->lsndtime && !tp->total_retrans) 2879 if (synack_stamp && !tp->total_retrans)
2880 seq_rtt = tcp_time_stamp - tp->lsndtime; 2880 seq_rtt = tcp_time_stamp - synack_stamp;
2881 tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt, -1); 2881
2882 /* If the ACK acks both the SYNACK and the (Fast Open'd) data packets
2883 * sent in SYN_RECV, SYNACK RTT is the smooth RTT computed in tcp_ack()
2884 */
2885 if (!tp->srtt)
2886 tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt, -1);
2882} 2887}
2883 2888
2884static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) 2889static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
@@ -5587,6 +5592,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5587 struct request_sock *req; 5592 struct request_sock *req;
5588 int queued = 0; 5593 int queued = 0;
5589 bool acceptable; 5594 bool acceptable;
5595 u32 synack_stamp;
5590 5596
5591 tp->rx_opt.saw_tstamp = 0; 5597 tp->rx_opt.saw_tstamp = 0;
5592 5598
@@ -5669,9 +5675,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5669 * so release it. 5675 * so release it.
5670 */ 5676 */
5671 if (req) { 5677 if (req) {
5678 synack_stamp = tcp_rsk(req)->snt_synack;
5672 tp->total_retrans = req->num_retrans; 5679 tp->total_retrans = req->num_retrans;
5673 reqsk_fastopen_remove(sk, req, false); 5680 reqsk_fastopen_remove(sk, req, false);
5674 } else { 5681 } else {
5682 synack_stamp = tp->lsndtime;
5675 /* Make sure socket is routed, for correct metrics. */ 5683 /* Make sure socket is routed, for correct metrics. */
5676 icsk->icsk_af_ops->rebuild_header(sk); 5684 icsk->icsk_af_ops->rebuild_header(sk);
5677 tcp_init_congestion_control(sk); 5685 tcp_init_congestion_control(sk);
@@ -5694,7 +5702,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5694 tp->snd_una = TCP_SKB_CB(skb)->ack_seq; 5702 tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
5695 tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale; 5703 tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale;
5696 tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); 5704 tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
5697 tcp_synack_rtt_meas(sk, req); 5705 tcp_synack_rtt_meas(sk, synack_stamp);
5698 5706
5699 if (tp->rx_opt.tstamp_ok) 5707 if (tp->rx_opt.tstamp_ok)
5700 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; 5708 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;