aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/session/session.c4
-rw-r--r--src/vnet/session/session_node.c16
-rw-r--r--src/vnet/session/transport.c1
-rw-r--r--src/vnet/session/transport.h4
-rw-r--r--src/vnet/tcp/tcp.c16
-rw-r--r--src/vnet/tcp/tcp.h9
-rwxr-xr-xsrc/vnet/tcp/tcp_input.c7
-rw-r--r--src/vnet/tcp/tcp_output.c4
8 files changed, 38 insertions, 23 deletions
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 15d949c76b5..8b268c00b64 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -130,7 +130,8 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio)
if (!(s->flags & SESSION_F_CUSTOM_TX))
{
s->flags |= SESSION_F_CUSTOM_TX;
- if (svm_fifo_set_event (s->tx_fifo))
+ if (svm_fifo_set_event (s->tx_fifo)
+ || transport_connection_is_descheduled (tc))
{
session_worker_t *wrk;
session_evt_elt_t *elt;
@@ -141,6 +142,7 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio)
elt = session_evt_alloc_old (wrk);
elt->evt.session_index = tc->s_index;
elt->evt.event_type = SESSION_IO_EVT_TX;
+ tc->flags &= ~TRANSPORT_CONNECTION_F_DESCHED;
}
}
}
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index b1c2428874e..b5f4321c9a8 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -872,7 +872,7 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
(ctx->s->session_state >= SESSION_STATE_TRANSPORT_CLOSED))
return SESSION_TX_OK;
max_burst -= n_custom_tx;
- if (!max_burst)
+ if (!max_burst || (ctx->s->flags & SESSION_F_CUSTOM_TX))
{
session_evt_add_old (wrk, elt);
return SESSION_TX_OK;
@@ -883,18 +883,18 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
if (!ctx->sp.snd_space)
{
- /* This flow queue is "empty" so it should be re-evaluated before
- * the ones that have data to send. */
- if (PREDICT_TRUE (!ctx->sp.flags))
- session_evt_add_head_old (wrk, elt);
+ /* If the deschedule flag was set, remove session from scheduler.
+ * Transport is responsible for rescheduling this session. */
+ if (ctx->sp.flags & TRANSPORT_SND_F_DESCHED)
+ transport_connection_deschedule (ctx->tc);
/* Request to postpone the session, e.g., zero-wnd and transport
* is not currently probing */
else if (ctx->sp.flags & TRANSPORT_SND_F_POSTPONE)
session_evt_add_old (wrk, elt);
- /* If the deschedule flag was set, remove session from scheduler.
- * Transport is responsible for rescheduling this session. */
+ /* This flow queue is "empty" so it should be re-evaluated before
+ * the ones that have data to send. */
else
- transport_connection_deschedule (ctx->tc);
+ session_evt_add_head_old (wrk, elt);
return SESSION_TX_NO_DATA;
}
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index e27aaf3ff6b..16f4f02cbe3 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -725,6 +725,7 @@ void
transport_connection_reschedule (transport_connection_t * tc)
{
tc->flags &= ~TRANSPORT_CONNECTION_F_DESCHED;
+ transport_connection_tx_pacer_reset_bucket (tc, TRANSPORT_PACER_MIN_BURST);
if (transport_max_tx_dequeue (tc))
sesssion_reschedule_tx (tc);
else
diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h
index b2be990947c..3c4e15a9a6b 100644
--- a/src/vnet/session/transport.h
+++ b/src/vnet/session/transport.h
@@ -184,9 +184,7 @@ transport_connection_snd_params (transport_connection_t * tc,
static inline u8
transport_connection_is_descheduled (transport_connection_t * tc)
{
- if (tc->flags & TRANSPORT_CONNECTION_F_DESCHED)
- return 1;
- return 0;
+ return ((tc->flags & TRANSPORT_CONNECTION_F_DESCHED) ? 1 : 0);
}
static inline void
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 4a0ffc137e5..dfcce771654 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -1281,14 +1281,7 @@ tcp_session_send_params (transport_connection_t * trans_conn,
/* This still works if fast retransmit is on */
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;
- }
+ sp->flags = sp->snd_space ? 0 : TRANSPORT_SND_F_DESCHED;
return 0;
}
@@ -1540,6 +1533,13 @@ tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window,
srtt * CLIB_US_TIME_FREQ);
}
+void
+tcp_reschedule (tcp_connection_t * tc)
+{
+ if (tcp_in_cong_recovery (tc) || tcp_snd_space_inline (tc))
+ transport_connection_reschedule (&tc->connection);
+}
+
static void
tcp_expired_timers_dispatch (u32 * expired_timers)
{
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index 8fa9013e31a..4db6040ae64 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -1036,6 +1036,12 @@ tcp_available_cc_snd_space (const tcp_connection_t * tc)
return available_wnd - flight_size;
}
+static inline u8
+tcp_is_descheduled (tcp_connection_t * tc)
+{
+ return (transport_connection_is_descheduled (&tc->connection) ? 1 : 0);
+}
+
always_inline u8
tcp_is_lost_fin (tcp_connection_t * tc)
{
@@ -1046,6 +1052,7 @@ tcp_is_lost_fin (tcp_connection_t * tc)
u32 tcp_snd_space (tcp_connection_t * tc);
int tcp_fastrecovery_prr_snd_space (tcp_connection_t * tc);
+void tcp_reschedule (tcp_connection_t * tc);
fib_node_index_t tcp_lookup_rmt_in_fib (tcp_connection_t * tc);
@@ -1244,8 +1251,6 @@ 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 4f31d21c3c1..bac41473cfa 100755
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -700,6 +700,9 @@ tcp_handle_postponed_dequeues (tcp_worker_ctx_t * wrk)
tc->flags &= ~TCP_CONN_PSH_PENDING;
}
+ if (tcp_is_descheduled (tc))
+ tcp_reschedule (tc);
+
/* If everything has been acked, stop retransmit timer
* otherwise update. */
tcp_retransmit_timer_update (tc);
@@ -1315,6 +1318,9 @@ tcp_update_snd_wnd (tcp_connection_t * tc, u32 seq, u32 ack, u32 snd_wnd)
if (PREDICT_FALSE (tcp_timer_is_active (tc, TCP_TIMER_PERSIST)))
tcp_persist_timer_reset (tc);
+ if (PREDICT_FALSE (tcp_is_descheduled (tc)))
+ tcp_reschedule (tc);
+
if (PREDICT_FALSE (!tcp_in_recovery (tc) && tc->rto_boff > 0))
{
tc->rto_boff = 0;
@@ -1465,6 +1471,7 @@ tcp_cc_recover (tcp_connection_t * tc)
ASSERT (tc->rto_boff == 0);
ASSERT (!tcp_in_cong_recovery (tc));
ASSERT (tcp_scoreboard_is_sane_post_recovery (tc));
+
return is_spurious;
}
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index b77713e1538..d33cbdd4ad4 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -1695,9 +1695,11 @@ tcp_timer_persist_handler (tcp_connection_t * tc)
/* Just sent new data, enable retransmit */
tcp_retransmit_timer_update (tc);
+ return;
+
update_scheduler:
- if (transport_connection_is_descheduled (&tc->connection))
+ if (tcp_is_descheduled (tc))
transport_connection_reschedule (&tc->connection);
}