summaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-03-13 17:54:42 +0000
committerDave Barach <openvpp@barachs.net>2020-03-19 14:46:01 +0000
commit70f879d2852dfc042ad0911a4a6e4a1714c0eb83 (patch)
treed7ea7d76b8ec034d41ead0b9ada2db18d9676670 /src/vnet/tcp
parent7fd59cc79c9fb0cccd0cb5c0b4579d0f0a004f6b (diff)
session tcp udp: consolidate transport snd apis
Type: improvement Use only one api to retrieve transport send parameters. Additionally, allow transports to request postponing and descheduling of events. With this, tcp now requests descheduling of sessions when the connections are stuck probing for zero snd_wnd Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I722c974f3e68fa15424c519a1fffacda43af050c
Diffstat (limited to 'src/vnet/tcp')
-rw-r--r--src/vnet/tcp/tcp.c65
-rw-r--r--src/vnet/tcp/tcp.h2
-rwxr-xr-xsrc/vnet/tcp/tcp_input.c4
-rw-r--r--src/vnet/tcp/tcp_output.c10
4 files changed, 41 insertions, 40 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 7712ade4416..4a0ffc137e5 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -1195,29 +1195,6 @@ tcp_session_cal_goal_size (tcp_connection_t * tc)
return goal_size > tc->snd_mss ? goal_size : tc->snd_mss;
}
-/**
- * Compute maximum segment size for session layer.
- *
- * Since the result needs to be the actual data length, it first computes
- * the tcp options to be used in the next burst and subtracts their
- * length from the connection's snd_mss.
- */
-static u16
-tcp_session_send_mss (transport_connection_t * trans_conn)
-{
- tcp_connection_t *tc = (tcp_connection_t *) trans_conn;
-
- /* Ensure snd_mss does accurately reflect the amount of data we can push
- * in a segment. This also makes sure that options are updated according to
- * the current state of the connection. */
- tcp_update_burst_snd_vars (tc);
-
- if (PREDICT_FALSE (tc->cfg_flags & TCP_CFG_F_TSO))
- return tcp_session_cal_goal_size (tc);
-
- return tc->snd_mss;
-}
-
always_inline u32
tcp_round_snd_space (tcp_connection_t * tc, u32 snd_space)
{
@@ -1281,23 +1258,39 @@ tcp_snd_space (tcp_connection_t * tc)
return tcp_snd_space_inline (tc);
}
-static u32
-tcp_session_send_space (transport_connection_t * trans_conn)
+static int
+tcp_session_send_params (transport_connection_t * trans_conn,
+ transport_send_params_t * sp)
{
tcp_connection_t *tc = (tcp_connection_t *) trans_conn;
- return clib_min (tcp_snd_space_inline (tc),
- tc->snd_wnd - (tc->snd_nxt - tc->snd_una));
-}
-static u32
-tcp_session_tx_fifo_offset (transport_connection_t * trans_conn)
-{
- tcp_connection_t *tc = (tcp_connection_t *) trans_conn;
+ /* Ensure snd_mss does accurately reflect the amount of data we can push
+ * in a segment. This also makes sure that options are updated according to
+ * the current state of the connection. */
+ tcp_update_burst_snd_vars (tc);
- ASSERT (seq_geq (tc->snd_nxt, tc->snd_una));
+ if (PREDICT_FALSE (tc->cfg_flags & TCP_CFG_F_TSO))
+ sp->snd_mss = tcp_session_cal_goal_size (tc);
+ else
+ sp->snd_mss = tc->snd_mss;
+
+ sp->snd_space = clib_min (tcp_snd_space_inline (tc),
+ tc->snd_wnd - (tc->snd_nxt - tc->snd_una));
+ ASSERT (seq_geq (tc->snd_nxt, tc->snd_una));
/* This still works if fast retransmit is on */
- return (tc->snd_nxt - tc->snd_una);
+ sp->tx_offset = tc->snd_nxt - tc->snd_una;
+
+ sp->flags = 0;
+ if (!tc->snd_wnd)
+ {
+ if (tcp_timer_is_active (tc, TCP_TIMER_PERSIST))
+ sp->flags = TRANSPORT_SND_F_DESCHED;
+ else
+ sp->flags = TRANSPORT_SND_F_POSTPONE;
+ }
+
+ return 0;
}
static void
@@ -1509,10 +1502,8 @@ const static transport_proto_vft_t tcp_proto = {
.close = tcp_session_close,
.cleanup = tcp_session_cleanup,
.reset = tcp_session_reset,
- .send_mss = tcp_session_send_mss,
- .send_space = tcp_session_send_space,
+ .send_params = tcp_session_send_params,
.update_time = tcp_update_time,
- .tx_fifo_offset = tcp_session_tx_fifo_offset,
.flush_data = tcp_session_flush_data,
.custom_tx = tcp_session_custom_tx,
.format_connection = format_tcp_session,
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index 6094ac5110a..8fa9013e31a 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -1244,6 +1244,8 @@ tcp_persist_timer_update (tcp_connection_t * tc)
always_inline void
tcp_persist_timer_reset (tcp_connection_t * tc)
{
+ if (transport_connection_is_descheduled (&tc->connection))
+ transport_connection_reschedule (&tc->connection);
tcp_timer_reset (tc, TCP_TIMER_PERSIST);
}
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index 0e8e68b1339..4f31d21c3c1 100755
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -1312,7 +1312,9 @@ tcp_update_snd_wnd (tcp_connection_t * tc, u32 seq, u32 ack, u32 snd_wnd)
}
else
{
- tcp_persist_timer_reset (tc);
+ if (PREDICT_FALSE (tcp_timer_is_active (tc, TCP_TIMER_PERSIST)))
+ tcp_persist_timer_reset (tc);
+
if (PREDICT_FALSE (!tcp_in_recovery (tc) && tc->rto_boff > 0))
{
tc->rto_boff = 0;
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index 6ed478fd1bc..b77713e1538 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -1637,7 +1637,7 @@ tcp_timer_persist_handler (tcp_connection_t * tc)
/* Problem already solved or worse */
if (tc->state == TCP_STATE_CLOSED || tc->snd_wnd > tc->snd_mss
|| (tc->flags & TCP_CONN_FINSNT))
- return;
+ goto update_scheduler;
available_bytes = transport_max_tx_dequeue (&tc->connection);
offset = tc->snd_nxt - tc->snd_una;
@@ -1651,7 +1651,7 @@ tcp_timer_persist_handler (tcp_connection_t * tc)
}
if (available_bytes <= offset)
- return;
+ goto update_scheduler;
/* Increment RTO backoff */
tc->rto_boff += 1;
@@ -1665,6 +1665,7 @@ tcp_timer_persist_handler (tcp_connection_t * tc)
tcp_persist_timer_set (tc);
return;
}
+
b = vlib_get_buffer (vm, bi);
data = tcp_init_buffer (vm, b);
@@ -1693,6 +1694,11 @@ tcp_timer_persist_handler (tcp_connection_t * tc)
/* Just sent new data, enable retransmit */
tcp_retransmit_timer_update (tc);
+
+update_scheduler:
+
+ if (transport_connection_is_descheduled (&tc->connection))
+ transport_connection_reschedule (&tc->connection);
}
/**