tcp: force deschedule if no send space available 81/25881/12
authorFlorin Coras <fcoras@cisco.com>
Fri, 13 Mar 2020 20:39:43 +0000 (20:39 +0000)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 19 Mar 2020 14:48:15 +0000 (14:48 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Iae9f118f710153b6c0e390265039db7434e67ed8

src/vnet/session/session.c
src/vnet/session/session_node.c
src/vnet/session/transport.c
src/vnet/session/transport.h
src/vnet/tcp/tcp.c
src/vnet/tcp/tcp.h
src/vnet/tcp/tcp_input.c
src/vnet/tcp/tcp_output.c

index 15d949c..8b268c0 100644 (file)
@@ -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;
        }
     }
 }
index b1c2428..b5f4321 100644 (file)
@@ -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;
     }
index e27aaf3..16f4f02 100644 (file)
@@ -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
index b2be990..3c4e15a 100644 (file)
@@ -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
index 4a0ffc1..dfcce77 100644 (file)
@@ -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)
 {
index 8fa9013..4db6040 100644 (file)
@@ -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);
 }
 
index 4f31d21..bac4147 100755 (executable)
@@ -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;
 }
 
index b77713e..d33cbdd 100644 (file)
@@ -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);
 }