diff options
author | Florin Coras <fcoras@cisco.com> | 2020-07-31 12:32:40 -0700 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2020-08-03 15:36:32 +0000 |
commit | eedc74b804a955de39e013f14c97f2abb4770157 (patch) | |
tree | 6c9e640858a6f4b548c67ae8d2f97e9d69fdab47 /src/vnet/tcp/tcp_input.c | |
parent | f3ae9e32664ccc3ce0980fcafee9453a3c0cef9b (diff) |
tcp: improve timestamp rtt accuracy
- switch to using vlib_time as reference for timestamps
- use us precision ticks for tcp but keep using ms precision for
timestamps. As a result, srtt, rttvar and rto are now measured in us
instead of ms. MRTT samples from timestamps are converted from ms to
us (not accurate under ms) while high precision samples are used with us
precision, i.e., they're no longer converted to ms precision samples.
Type: improvement
Change-Id: Ibda559575d9b4fdc85b0985264f7c865ff367e34
Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/tcp/tcp_input.c')
-rw-r--r-- | src/vnet/tcp/tcp_input.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 519219e2c74..5fa7bf23c72 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -424,31 +424,26 @@ acceptable: /** * Compute smoothed RTT as per VJ's '88 SIGCOMM and RFC6298 * - * Note that although the original article, srtt and rttvar are scaled + * Note that although in the original article srtt and rttvar are scaled * to minimize round-off errors, here we don't. Instead, we rely on * better precision time measurements. + * + * A known limitation of the algorithm is that a drop in rtt results in a + * rttvar increase and bigger RTO. + * + * mrtt must be provided in @ref TCP_TICK multiples, i.e., in us. Note that + * timestamps are measured as ms ticks so they must be converted before + * calling this function. */ static void tcp_estimate_rtt (tcp_connection_t * tc, u32 mrtt) { int err, diff; - if (tc->srtt != 0) - { - err = mrtt - tc->srtt; - - /* XXX Drop in RTT results in RTTVAR increase and bigger RTO. - * The increase should be bound */ - tc->srtt = clib_max ((int) tc->srtt + (err >> 3), 1); - diff = (clib_abs (err) - (int) tc->rttvar) >> 2; - tc->rttvar = clib_max ((int) tc->rttvar + diff, 1); - } - else - { - /* First measurement. */ - tc->srtt = mrtt; - tc->rttvar = mrtt >> 1; - } + err = mrtt - tc->srtt; + tc->srtt = clib_max ((int) tc->srtt + (err >> 3), 1); + diff = (clib_abs (err) - (int) tc->rttvar) >> 2; + tc->rttvar = clib_max ((int) tc->rttvar + diff, 1); } static inline void @@ -506,8 +501,8 @@ tcp_update_rtt (tcp_connection_t * tc, tcp_rate_sample_t * rs, u32 ack) * seq_lt (tc->snd_una, ack). This is a condition for calling update_rtt */ else if (tcp_opts_tstamp (&tc->rcv_opts) && tc->rcv_opts.tsecr) { - u32 now = tcp_tstamp (tc); - mrtt = clib_max (now - tc->rcv_opts.tsecr, 1); + mrtt = clib_max (tcp_tstamp (tc) - tc->rcv_opts.tsecr, 1); + mrtt *= TCP_TSTP_TO_HZ; } estimate_rtt: @@ -543,8 +538,8 @@ tcp_estimate_initial_rtt (tcp_connection_t * tc) } else { - mrtt = tcp_time_now_w_thread (thread_index) - tc->rcv_opts.tsecr; - mrtt = clib_max (mrtt, 1); + mrtt = tcp_tstamp (tc) - tc->rcv_opts.tsecr; + mrtt = clib_max (mrtt, 1) * TCP_TSTP_TO_HZ; /* Due to retransmits we don't know the initial mrtt */ if (tc->rto_boff && mrtt > 1 * THZ) mrtt = 1 * THZ; @@ -552,7 +547,11 @@ tcp_estimate_initial_rtt (tcp_connection_t * tc) } if (mrtt > 0 && mrtt < TCP_RTT_MAX) - tcp_estimate_rtt (tc, mrtt); + { + /* First measurement as per RFC 6298 */ + tc->srtt = mrtt; + tc->rttvar = mrtt >> 1; + } tcp_update_rto (tc); } |