summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2021-07-06 08:25:36 -0700
committerFlorin Coras <fcoras@cisco.com>2021-07-06 14:53:44 -0700
commit57b2e4acb1104ac34b1c2e29309e0f5f471b42d7 (patch)
tree19b327e6f24f1930d19f747d3f7535d0852edf91
parent3169e9ff1ef673402aa05332096fb877ca2f4b25 (diff)
tcp: use main thread pool for half-opens
Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I4b3427b966f9ff1ba8895fed7db662d56650f3f5
-rw-r--r--src/vnet/tcp/tcp.c50
-rw-r--r--src/vnet/tcp/tcp.h8
-rw-r--r--src/vnet/tcp/tcp_cli.c110
-rw-r--r--src/vnet/tcp/tcp_inlines.h5
-rw-r--r--src/vnet/tcp/tcp_input.c2
5 files changed, 29 insertions, 146 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index c70a44cae90..c54a994fede 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -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);
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index 60b9095aea2..ca650b7fa29 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -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);
diff --git a/src/vnet/tcp/tcp_cli.c b/src/vnet/tcp/tcp_cli.c
index c11b154cebf..e602f114a74 100644
--- a/src/vnet/tcp/tcp_cli.c
+++ b/src/vnet/tcp/tcp_cli.c
@@ -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))
diff --git a/src/vnet/tcp/tcp_inlines.h b/src/vnet/tcp/tcp_inlines.h
index 68eb4b147fa..dfdf801d0ab 100644
--- a/src/vnet/tcp/tcp_inlines.h
+++ b/src/vnet/tcp/tcp_inlines.h
@@ -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);
}
/**
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index 2ba96a5fe78..1e27b7dcb2e 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -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;