tcp: use main thread pool for half-opens 21/33021/6
authorFlorin Coras <fcoras@cisco.com>
Tue, 6 Jul 2021 15:25:36 +0000 (08:25 -0700)
committerFlorin Coras <fcoras@cisco.com>
Tue, 6 Jul 2021 21:53:44 +0000 (14:53 -0700)
Type: improvement

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

src/vnet/tcp/tcp.c
src/vnet/tcp/tcp.h
src/vnet/tcp/tcp_cli.c
src/vnet/tcp/tcp_inlines.h
src/vnet/tcp/tcp_input.c

index c70a44c..c54a994 100644 (file)
@@ -181,6 +181,13 @@ tcp_session_get_listener (u32 listener_index)
   return &tc->connection;
 }
 
+static tcp_connection_t *
+tcp_half_open_connection_alloc (void)
+{
+  ASSERT (vlib_get_thread_index () == 0);
+  return tcp_connection_alloc (0);
+}
+
 /**
  * Cleanup half-open connection
  *
@@ -188,10 +195,8 @@ tcp_session_get_listener (u32 listener_index)
 static void
 tcp_half_open_connection_free (tcp_connection_t * tc)
 {
-  tcp_main_t *tm = vnet_get_tcp_main ();
-  if (CLIB_DEBUG)
-    clib_memset (tc, 0xFA, sizeof (*tc));
-  pool_put (tm->half_open_connections, tc);
+  ASSERT (vlib_get_thread_index () == 0);
+  return tcp_connection_free (tc);
 }
 
 /**
@@ -219,18 +224,6 @@ tcp_half_open_connection_cleanup (tcp_connection_t * tc)
   return 0;
 }
 
-static tcp_connection_t *
-tcp_half_open_connection_new (void)
-{
-  tcp_main_t *tm = vnet_get_tcp_main ();
-  tcp_connection_t *tc = 0;
-  ASSERT (vlib_get_thread_index () == 0);
-  pool_get (tm->half_open_connections, tc);
-  clib_memset (tc, 0, sizeof (*tc));
-  tc->c_c_index = tc - tm->half_open_connections;
-  return tc;
-}
-
 /**
  * Cleans up connection state.
  *
@@ -304,13 +297,23 @@ tcp_connection_alloc (u8 thread_index)
 }
 
 tcp_connection_t *
-tcp_connection_alloc_w_base (u8 thread_index, tcp_connection_t * base)
+tcp_connection_alloc_w_base (u8 thread_index, tcp_connection_t **base)
 {
   tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
   tcp_connection_t *tc;
 
-  pool_get (wrk->connections, tc);
-  clib_memcpy_fast (tc, base, sizeof (*tc));
+  /* Make sure connection is still valid if pool moves */
+  if ((*base)->c_thread_index == thread_index)
+    {
+      u32 base_index = (*base)->c_c_index;
+      pool_get (wrk->connections, tc);
+      *base = tcp_connection_get (base_index, thread_index);
+    }
+  else
+    {
+      pool_get (wrk->connections, tc);
+    }
+  clib_memcpy_fast (tc, *base, sizeof (*tc));
   tc->c_c_index = tc - wrk->connections;
   tc->c_thread_index = thread_index;
   return tc;
@@ -816,7 +819,7 @@ tcp_session_open (transport_endpoint_cfg_t * rmt)
   /*
    * Create connection and send SYN
    */
-  tc = tcp_half_open_connection_new ();
+  tc = tcp_half_open_connection_alloc ();
   ip_copy (&tc->c_rmt_ip, &rmt->ip, rmt->is_ip4);
   ip_copy (&tc->c_lcl_ip, &lcl_addr, rmt->is_ip4);
   tc->c_rmt_port = rmt->port;
@@ -1515,13 +1518,6 @@ tcp_main_enable (vlib_main_t * vm)
                                  vlib_time_now (vm));
     }
 
-  /*
-   * Use a preallocated half-open connection pool?
-   */
-  if (tcp_cfg.preallocated_half_open_connections)
-    pool_init_fixed (tm->half_open_connections,
-                    tcp_cfg.preallocated_half_open_connections);
-
   tcp_initialize_iss_seed (tm);
 
   tm->bytes_per_buffer = vlib_buffer_get_default_data_size (vm);
index 60b9095..ca650b7 100644 (file)
@@ -193,9 +193,6 @@ typedef struct tcp_configuration_
   /** Number of preallocated connections */
   u32 preallocated_connections;
 
-  /** Number of preallocated half-open connections */
-  u32 preallocated_half_open_connections;
-
   /** Maxium allowed GSO packet size */
   u32 max_gso_size;
 
@@ -224,9 +221,6 @@ typedef struct _tcp_main
   /** Dispatch table by state and flags */
   tcp_lookup_dispatch_t dispatch_table[TCP_N_STATES][64];
 
-  /** Pool of half-open connections on which we've sent a SYN */
-  tcp_connection_t *half_open_connections;
-
   /** Seed used to generate random iss */
   tcp_iss_seed_t iss_seed;
 
@@ -294,7 +288,7 @@ tcp_get_worker (u32 thread_index)
 
 tcp_connection_t *tcp_connection_alloc (u8 thread_index);
 tcp_connection_t *tcp_connection_alloc_w_base (u8 thread_index,
-                                              tcp_connection_t * base);
+                                              tcp_connection_t **base);
 void tcp_connection_free (tcp_connection_t * tc);
 void tcp_connection_close (tcp_connection_t * tc);
 void tcp_connection_cleanup (tcp_connection_t * tc);
index c11b154..e602f11 100644 (file)
@@ -899,110 +899,6 @@ VLIB_CLI_COMMAND (clear_tcp_stats_command, static) =
 };
 /* *INDENT-ON* */
 
-static void
-tcp_show_half_open (vlib_main_t * vm, u32 start, u32 end, u8 verbose)
-{
-  tcp_main_t *tm = &tcp_main;
-  u8 output_suppressed = 0;
-  u32 n_elts, count = 0;
-  tcp_connection_t *tc;
-  int max_index, i;
-
-  n_elts = pool_elts (tm->half_open_connections);
-  max_index = clib_max (pool_len (tm->half_open_connections), 1) - 1;
-  if (verbose && end == ~0 && n_elts > 50)
-    {
-      vlib_cli_output (vm, "Too many connections, use range <start> <end>");
-      return;
-    }
-
-  if (!verbose)
-    {
-      vlib_cli_output (vm, "%u tcp half-open connections", n_elts);
-      return;
-    }
-
-  for (i = start; i <= clib_min (end, max_index); i++)
-    {
-      if (pool_is_free_index (tm->half_open_connections, i))
-       continue;
-
-      tc = pool_elt_at_index (tm->half_open_connections, i);
-
-      count += 1;
-      if (verbose)
-       {
-         if (count > 50 || (verbose > 1 && count > 10))
-           {
-             output_suppressed = 1;
-             continue;
-           }
-       }
-      vlib_cli_output (vm, "%U", format_tcp_connection, tc, verbose);
-    }
-  if (!output_suppressed)
-    vlib_cli_output (vm, "%u tcp half-open connections", n_elts);
-  else
-    vlib_cli_output (vm, "%u tcp half-open connections matched. Output "
-                    "suppressed. Use finer grained filter.", count);
-
-}
-
-static clib_error_t *
-show_tcp_half_open_fn (vlib_main_t * vm, unformat_input_t * input,
-                      vlib_cli_command_t * cmd)
-{
-  unformat_input_t _line_input, *line_input = &_line_input;
-  u32 start, end = ~0, verbose = 0;
-  clib_error_t *error = 0;
-
-  session_cli_return_if_not_enabled ();
-
-  if (!unformat_user (input, unformat_line_input, line_input))
-    {
-      tcp_show_half_open (vm, 0, ~0, 0);
-      return 0;
-    }
-
-  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (line_input, "range %u %u", &start, &end))
-       ;
-      else if (unformat (line_input, "verbose %d", &verbose))
-       ;
-      else if (unformat (line_input, "verbose"))
-       verbose = 1;
-      else
-       {
-         error = clib_error_return (0, "unknown input `%U'",
-                                    format_unformat_error, input);
-         goto done;
-       }
-    }
-
-  if (start > end)
-    {
-      error = clib_error_return (0, "invalid range start: %u end: %u", start,
-                                end);
-      goto done;
-    }
-
-  tcp_show_half_open (vm, start, end, verbose);
-
-done:
-  unformat_free (line_input);
-  return error;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (show_tcp_half_open_command, static) =
-{
-  .path = "show tcp half-open",
-  .short_help = "show tcp half-open [verbose <n>] [range <start> <end>]",
-  .function = show_tcp_half_open_fn,
-};
-/* *INDENT-ON* */
-
 uword
 unformat_tcp_cc_algo (unformat_input_t * input, va_list * va)
 {
@@ -1049,7 +945,7 @@ unformat_tcp_cc_algo_cfg (unformat_input_t * input, va_list * va)
 static clib_error_t *
 tcp_config_fn (vlib_main_t * vm, unformat_input_t * input)
 {
-  u32 cwnd_multiplier, tmp_time, mtu, max_gso_size;
+  u32 cwnd_multiplier, tmp_time, mtu, max_gso_size, tmp;
   uword memory_size;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -1057,8 +953,8 @@ tcp_config_fn (vlib_main_t * vm, unformat_input_t * input)
       if (unformat (input, "preallocated-connections %d",
                    &tcp_cfg.preallocated_connections))
        ;
-      else if (unformat (input, "preallocated-half-open-connections %d",
-                        &tcp_cfg.preallocated_half_open_connections))
+      /* Config deprecated. Will be removed in a later release */
+      else if (unformat (input, "preallocated-half-open-connections %d", &tmp))
        ;
       else if (unformat (input, "buffer-fail-fraction %f",
                         &tcp_cfg.buffer_fail_fraction))
index 68eb4b1..dfdf801 100644 (file)
@@ -66,10 +66,7 @@ tcp_listener_get (u32 tli)
 always_inline tcp_connection_t *
 tcp_half_open_connection_get (u32 conn_index)
 {
-  tcp_connection_t *tc = 0;
-  if (!pool_is_free_index (tcp_main.half_open_connections, conn_index))
-    tc = pool_elt_at_index (tcp_main.half_open_connections, conn_index);
-  return tc;
+  return tcp_connection_get (conn_index, 0);
 }
 
 /**
index 2ba96a5..1e27b7d 100644 (file)
@@ -1929,7 +1929,7 @@ tcp46_syn_sent_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
 
       /* Valid SYN or SYN-ACK. Move connection from half-open pool to
        * current thread pool. */
-      new_tc = tcp_connection_alloc_w_base (thread_index, tc);
+      new_tc = tcp_connection_alloc_w_base (thread_index, &tc);
       new_tc->rcv_nxt = vnet_buffer (b[0])->tcp.seq_end;
       new_tc->irs = seq;
       new_tc->timers[TCP_TIMER_RETRANSMIT_SYN] = TCP_TIMER_HANDLE_INVALID;