summaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp/tcp_input.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-07-31 12:32:40 -0700
committerFlorin Coras <florin.coras@gmail.com>2020-08-03 15:36:32 +0000
commiteedc74b804a955de39e013f14c97f2abb4770157 (patch)
tree6c9e640858a6f4b548c67ae8d2f97e9d69fdab47 /src/vnet/tcp/tcp_input.c
parentf3ae9e32664ccc3ce0980fcafee9453a3c0cef9b (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.c43
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);
}