aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2022-03-23 16:35:05 -0700
committerDamjan Marion <dmarion@me.com>2022-03-24 16:08:12 +0000
commit05ead78945831fbaad6e973d21dfbd9a2c9e2ba4 (patch)
tree48af98e38261fe28576662428a45bb66f876d70f
parentaa7cfd04e7bb89208afe57cd84e96ced32153044 (diff)
session: safe reallocs for transport endpoint pool
Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I6c86d0691bd0594d8b2c05d83d004be1aa8c5e21
-rw-r--r--src/vnet/session/transport.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index 540d6a615ac..93e02247b4e 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -420,17 +420,28 @@ transport_connection_attribute (transport_proto_t tp, u32 conn_index,
#define PORT_MASK ((1 << 16)- 1)
void
-transport_endpoint_del (u32 tepi)
+transport_endpoint_free (u32 tepi)
{
- clib_spinlock_lock_if_init (&local_endpoints_lock);
+ /* All workers can free connections. Synchronize access to pool */
+ clib_spinlock_lock (&local_endpoints_lock);
pool_put_index (local_endpoints, tepi);
- clib_spinlock_unlock_if_init (&local_endpoints_lock);
+ clib_spinlock_unlock (&local_endpoints_lock);
+}
+
+static void
+transport_endpoint_pool_realloc_rpc (void *rpc_args)
+{
+ pool_realloc_safe_aligned (local_endpoints, 0);
}
always_inline local_endpoint_t *
-transport_endpoint_new (void)
+transport_endpoint_alloc (void)
{
local_endpoint_t *lep;
+
+ ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
+ pool_get_aligned_safe (local_endpoints, lep, transport_cl_thread (),
+ transport_endpoint_pool_realloc_rpc, 0);
pool_get_zero (local_endpoints, lep);
return lep;
}
@@ -451,7 +462,7 @@ transport_endpoint_cleanup (u8 proto, ip46_address_t * lcl_ip, u16 port)
{
transport_endpoint_table_del (&local_endpoints_table, proto,
&lep->ep);
- transport_endpoint_del (lepi);
+ transport_endpoint_free (lepi);
}
}
}
@@ -460,14 +471,16 @@ static void
transport_endpoint_mark_used (u8 proto, ip46_address_t * ip, u16 port)
{
local_endpoint_t *lep;
- clib_spinlock_lock_if_init (&local_endpoints_lock);
- lep = transport_endpoint_new ();
+
+ ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
+
+ /* Pool reallocs with worker barrier */
+ lep = transport_endpoint_alloc ();
clib_memcpy_fast (&lep->ep.ip, ip, sizeof (*ip));
lep->ep.port = port;
lep->refcnt = 1;
transport_endpoint_table_add (&local_endpoints_table, proto, &lep->ep,
lep - local_endpoints);
- clib_spinlock_unlock_if_init (&local_endpoints_lock);
}
void
@@ -498,8 +511,8 @@ transport_alloc_local_port (u8 proto, ip46_address_t * ip)
limit = max - min;
- /* Only support active opens from thread 0 */
- ASSERT (vlib_get_thread_index () == 0);
+ /* Only support active opens from one of ctrl threads */
+ ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
/* Search for first free slot */
for (tries = 0; tries < limit; tries++)
@@ -854,10 +867,11 @@ transport_init (void)
clib_bihash_init_24_8 (&local_endpoints_table, "local endpoints table",
smm->local_endpoints_table_buckets,
smm->local_endpoints_table_memory);
+ clib_spinlock_init (&local_endpoints_lock);
+
num_threads = 1 /* main thread */ + vtm->n_threads;
if (num_threads > 1)
{
- clib_spinlock_init (&local_endpoints_lock);
/* Main not polled if there are workers */
smm->transport_cl_thread = 1;
}