tcp: fast retransmit improvements
Patch is too large to be ported to 18.10 just days before release.
- handle fast retransmits outside of established node and limit the
retransmit burst size to avoid tx losses and worsening congestion.
- in the absance of a tx pacer, use slow start after fast retransmit
exists
- add fast retransmit heuristic that re-retries sending the first
segment if everything else fails
- fine tuning
Change-Id: I84a2ab8fbba8b97f1d2b26584dc11a1e2c33c8d2
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/tcp/tcp_debug.h b/src/vnet/tcp/tcp_debug.h
index ccf12da..8f626b1 100755
--- a/src/vnet/tcp/tcp_debug.h
+++ b/src/vnet/tcp/tcp_debug.h
@@ -629,6 +629,8 @@
#define TCP_EVT_CC_EVT_HANDLER(_tc, _sub_evt, ...) \
{ \
+ if (_tc->snd_una != _tc->iss) \
+ TCP_EVT_CC_STAT_PRINT (_tc); \
ELOG_TYPE_DECLARE (_e) = \
{ \
.format = "cc: %s snd_space %u snd_una %u out %u flight %u", \
@@ -788,9 +790,11 @@
#define STATS_INTERVAL 1
-#define TCP_EVT_CC_RTO_STAT_HANDLER(_tc, ...) \
-{ \
-if (_tc->c_cc_stat_tstamp + STATS_INTERVAL < tcp_time_now()) \
+#define tcp_cc_time_to_print_stats(_tc) \
+ _tc->c_cc_stat_tstamp + STATS_INTERVAL < tcp_time_now() \
+ || tcp_in_fastrecovery (_tc) \
+
+#define TCP_EVT_CC_RTO_STAT_PRINT(_tc) \
{ \
ELOG_TYPE_DECLARE (_e) = \
{ \
@@ -801,29 +805,40 @@
ed->data[0] = _tc->rto; \
ed->data[1] = _tc->srtt; \
ed->data[2] = _tc->rttvar; \
+}
+
+#define TCP_EVT_CC_RTO_STAT_HANDLER(_tc, ...) \
+{ \
+if (tcp_cc_time_to_print_stats (_tc)) \
+{ \
+ TCP_EVT_CC_RTO_STAT_PRINT (_tc); \
} \
}
-#define TCP_EVT_CC_SND_STAT_HANDLER(_tc, ...) \
-{ \
-if (_tc->c_cc_stat_tstamp + STATS_INTERVAL < tcp_time_now()) \
+
+#define TCP_EVT_CC_SND_STAT_PRINT(_tc) \
{ \
ELOG_TYPE_DECLARE (_e) = \
{ \
- .format = "snd_stat: dack %u sacked %u lost %u out %u rxt %u", \
+ .format = "snd_stat: cc_space %u sacked %u lost %u out %u rxt %u", \
.format_args = "i4i4i4i4i4", \
}; \
DECLARE_ETD(_tc, _e, 5); \
- ed->data[0] = _tc->rcv_dupacks; \
+ ed->data[0] = tcp_available_cc_snd_space (_tc); \
ed->data[1] = _tc->sack_sb.sacked_bytes; \
ed->data[2] = _tc->sack_sb.lost_bytes; \
ed->data[3] = tcp_bytes_out (_tc); \
ed->data[3] = _tc->snd_rxt_bytes; \
+}
+
+#define TCP_EVT_CC_SND_STAT_HANDLER(_tc, ...) \
+{ \
+if (tcp_cc_time_to_print_stats (_tc)) \
+{ \
+ TCP_EVT_CC_SND_STAT_PRINT(_tc); \
} \
}
-#define TCP_EVT_CC_STAT_HANDLER(_tc, ...) \
-{ \
-if (_tc->c_cc_stat_tstamp + STATS_INTERVAL < tcp_time_now()) \
+#define TCP_EVT_CC_STAT_PRINT(_tc) \
{ \
ELOG_TYPE_DECLARE (_e) = \
{ \
@@ -836,7 +851,15 @@
ed->data[2] = tcp_snd_space (_tc); \
ed->data[3] = _tc->ssthresh; \
ed->data[4] = _tc->snd_wnd; \
- TCP_EVT_CC_RTO_STAT_HANDLER (_tc); \
+ TCP_EVT_CC_RTO_STAT_PRINT (_tc); \
+ TCP_EVT_CC_SND_STAT_PRINT (_tc); \
+}
+
+#define TCP_EVT_CC_STAT_HANDLER(_tc, ...) \
+{ \
+if (tcp_cc_time_to_print_stats (_tc)) \
+{ \
+ TCP_EVT_CC_STAT_PRINT (_tc); \
_tc->c_cc_stat_tstamp = tcp_time_now(); \
} \
}