aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2017-05-31 14:30:53 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-02 14:19:23 -0400
commit775e68a93fe4d33ec93949c8022ed84b97a97096 (patch)
tree70959496b390c3b4854b736bc00b383c2a608538 /net/ipv4/tcp_input.c
parent9ae122c62a26ed3022d0affb5b7fffe0292bae16 (diff)
tcp: use TS opt on RTTs for congestion control
Currently when a data packet is retransmitted, we do not compute an RTT sample for congestion control due to Kern's check. Therefore the congestion control that uses RTT signals may not receive any update during loss recovery which could last many round trips. For example, BBR and Vegas may not be able to update its min RTT estimation if the network path has shortened until it recovers from losses. This patch mitigates that by using TCP timestamp options for RTT measurement for congestion control. Note that we already use timestamps for RTT estimation. Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-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.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9f4380662196..4ea8ec5c7bb4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2921,9 +2921,9 @@ static void tcp_update_rtt_min(struct sock *sk, u32 rtt_us)
2921 rtt_us ? : jiffies_to_usecs(1)); 2921 rtt_us ? : jiffies_to_usecs(1));
2922} 2922}
2923 2923
2924static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag, 2924static bool tcp_ack_update_rtt(struct sock *sk, const int flag,
2925 long seq_rtt_us, long sack_rtt_us, 2925 long seq_rtt_us, long sack_rtt_us,
2926 long ca_rtt_us) 2926 long ca_rtt_us, struct rate_sample *rs)
2927{ 2927{
2928 const struct tcp_sock *tp = tcp_sk(sk); 2928 const struct tcp_sock *tp = tcp_sk(sk);
2929 2929
@@ -2948,6 +2948,7 @@ static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
2948 2948
2949 seq_rtt_us = ca_rtt_us = delta_us; 2949 seq_rtt_us = ca_rtt_us = delta_us;
2950 } 2950 }
2951 rs->rtt_us = ca_rtt_us; /* RTT of last (S)ACKed packet (or -1) */
2951 if (seq_rtt_us < 0) 2952 if (seq_rtt_us < 0)
2952 return false; 2953 return false;
2953 2954
@@ -2967,12 +2968,13 @@ static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
2967/* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */ 2968/* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */
2968void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req) 2969void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req)
2969{ 2970{
2971 struct rate_sample rs;
2970 long rtt_us = -1L; 2972 long rtt_us = -1L;
2971 2973
2972 if (req && !req->num_retrans && tcp_rsk(req)->snt_synack) 2974 if (req && !req->num_retrans && tcp_rsk(req)->snt_synack)
2973 rtt_us = tcp_stamp_us_delta(tcp_clock_us(), tcp_rsk(req)->snt_synack); 2975 rtt_us = tcp_stamp_us_delta(tcp_clock_us(), tcp_rsk(req)->snt_synack);
2974 2976
2975 tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, rtt_us, -1L, rtt_us); 2977 tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, rtt_us, -1L, rtt_us, &rs);
2976} 2978}
2977 2979
2978 2980
@@ -3177,9 +3179,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
3177 sack_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, sack->first_sackt); 3179 sack_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, sack->first_sackt);
3178 ca_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, sack->last_sackt); 3180 ca_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, sack->last_sackt);
3179 } 3181 }
3180 sack->rate->rtt_us = ca_rtt_us; /* RTT of last (S)ACKed packet, or -1 */
3181 rtt_update = tcp_ack_update_rtt(sk, flag, seq_rtt_us, sack_rtt_us, 3182 rtt_update = tcp_ack_update_rtt(sk, flag, seq_rtt_us, sack_rtt_us,
3182 ca_rtt_us); 3183 ca_rtt_us, sack->rate);
3183 3184
3184 if (flag & FLAG_ACKED) { 3185 if (flag & FLAG_ACKED) {
3185 tcp_rearm_rto(sk); 3186 tcp_rearm_rto(sk);
@@ -3215,7 +3216,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
3215 3216
3216 if (icsk->icsk_ca_ops->pkts_acked) { 3217 if (icsk->icsk_ca_ops->pkts_acked) {
3217 struct ack_sample sample = { .pkts_acked = pkts_acked, 3218 struct ack_sample sample = { .pkts_acked = pkts_acked,
3218 .rtt_us = ca_rtt_us, 3219 .rtt_us = sack->rate->rtt_us,
3219 .in_flight = last_in_flight }; 3220 .in_flight = last_in_flight };
3220 3221
3221 icsk->icsk_ca_ops->pkts_acked(sk, &sample); 3222 icsk->icsk_ca_ops->pkts_acked(sk, &sample);