aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Luong <sluong@cisco.com>2024-06-28 15:12:11 -0700
committerSteven Luong <sluong@cisco.com>2024-06-28 15:19:08 -0700
commitd2d41bc34e1663803037fc0a6c7bda9078cef2b6 (patch)
treef067ffe0b6b6aaaae19dad00ec3f10173d758a98
parent6d44aabe8d5e0015fd851788ef7c7bee48340dee (diff)
session: memory leaks on various transports when session disable and enable
When toggling session disable and enable, memory leaks found on various transports. Don't create the timer wheels on enable when they are already creaded. Don't create the spin locks when they are already created. Add session enable disable test in session unit test. Type: fix Change-Id: I08988a96bbf2d67a67c743b50b63f5b1e27402a3 Signed-off-by: Steven Luong <sluong@cisco.com>
-rw-r--r--src/plugins/http/http_timer.c2
-rw-r--r--src/plugins/unittest/session_test.c61
-rw-r--r--src/vnet/session/application_local.c14
-rw-r--r--src/vnet/tcp/tcp_timer.c2
4 files changed, 76 insertions, 3 deletions
diff --git a/src/plugins/http/http_timer.c b/src/plugins/http/http_timer.c
index 42fe69076fe..c8fc6328855 100644
--- a/src/plugins/http/http_timer.c
+++ b/src/plugins/http/http_timer.c
@@ -71,6 +71,8 @@ http_timers_init (vlib_main_t *vm, http_conn_timeout_fn *cb_fn)
http_tw_ctx_t *twc = &http_tw_ctx;
vlib_node_t *n;
+ if (twc->tw.timers)
+ return;
tw_timer_wheel_init_2t_1w_2048sl (&twc->tw, http_timer_process_expired_cb,
1.0 /* timer interval */, ~0);
clib_spinlock_init (&twc->tw_lock);
diff --git a/src/plugins/unittest/session_test.c b/src/plugins/unittest/session_test.c
index b7627acc129..33649662e5e 100644
--- a/src/plugins/unittest/session_test.c
+++ b/src/plugins/unittest/session_test.c
@@ -2073,6 +2073,63 @@ session_test_mq_basic (vlib_main_t * vm, unformat_input_t * input)
return 0;
}
+static f32
+session_get_memory_usage (void)
+{
+ clib_mem_heap_t *heap = clib_mem_get_per_cpu_heap ();
+ u8 *s = 0;
+ char *ss;
+ f32 used;
+
+ s = format (s, "%U\n", format_clib_mem_heap, heap, 0);
+ ss = strstr ((char *) s, "used:");
+ sscanf (ss, "used: %f", &used);
+ vec_free (s);
+ return (used);
+}
+
+static int
+session_test_enable_disable (vlib_main_t *vm, unformat_input_t *input)
+{
+ u32 iteration = 100, i;
+ uword was_enabled;
+ f32 was_using, now_using;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "repeat %d", &iteration))
+ ;
+ else
+ {
+ vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
+ input);
+ return -1;
+ }
+ }
+
+ was_enabled = clib_mem_trace_enable_disable (0);
+ /* warm up */
+ for (i = 0; i < 10; i++)
+ {
+ vnet_session_enable_disable (vm, 0);
+ vnet_session_enable_disable (vm, 1);
+ }
+ was_using = session_get_memory_usage ();
+
+ for (i = 0; i < iteration; i++)
+ {
+ vnet_session_enable_disable (vm, 0);
+ vnet_session_enable_disable (vm, 1);
+ }
+ now_using = session_get_memory_usage ();
+
+ clib_mem_trace_enable_disable (was_enabled);
+ SESSION_TEST ((was_using == now_using), "was using %.2fM, now using %.2fM",
+ was_using, now_using);
+
+ return 0;
+}
+
static clib_error_t *
session_test (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd_arg)
@@ -2099,6 +2156,8 @@ session_test (vlib_main_t * vm,
res = session_test_mq_speed (vm, input);
else if (unformat (input, "mq-basic"))
res = session_test_mq_basic (vm, input);
+ else if (unformat (input, "enable-disable"))
+ res = session_test_enable_disable (vm, input);
else if (unformat (input, "all"))
{
if ((res = session_test_basic (vm, input)))
@@ -2117,6 +2176,8 @@ session_test (vlib_main_t * vm,
goto done;
if ((res = session_test_mq_basic (vm, input)))
goto done;
+ if ((res = session_test_enable_disable (vm, input)))
+ goto done;
}
else
break;
diff --git a/src/vnet/session/application_local.c b/src/vnet/session/application_local.c
index 3cb743d10e0..064dd6fe77e 100644
--- a/src/vnet/session/application_local.c
+++ b/src/vnet/session/application_local.c
@@ -1350,13 +1350,21 @@ ct_enable_disable (vlib_main_t * vm, u8 is_en)
ct_main_t *cm = &ct_main;
ct_worker_t *wrk;
+ if (is_en == 0)
+ return 0;
+
cm->n_workers = vlib_num_workers ();
cm->fwrk_thread = transport_cl_thread ();
vec_validate (cm->wrk, vtm->n_vlib_mains);
vec_foreach (wrk, cm->wrk)
- clib_spinlock_init (&wrk->pending_connects_lock);
- clib_spinlock_init (&cm->ho_reuseable_lock);
- clib_rwlock_init (&cm->app_segs_lock);
+ {
+ if (wrk->pending_connects_lock == 0)
+ clib_spinlock_init (&wrk->pending_connects_lock);
+ }
+ if (cm->ho_reuseable_lock == 0)
+ clib_spinlock_init (&cm->ho_reuseable_lock);
+ if (cm->app_segs_lock == 0)
+ clib_rwlock_init (&cm->app_segs_lock);
vec_validate (cm->fwrk_pending_connects, cm->n_workers);
return 0;
}
diff --git a/src/vnet/tcp/tcp_timer.c b/src/vnet/tcp/tcp_timer.c
index d98d0d14b17..8ae3f22eaa6 100644
--- a/src/vnet/tcp/tcp_timer.c
+++ b/src/vnet/tcp/tcp_timer.c
@@ -20,6 +20,8 @@ void
tcp_timer_initialize_wheel (tcp_timer_wheel_t * tw,
void (*expired_timer_cb) (u32 *), f64 now)
{
+ if (tw->timers)
+ return;
tw_timer_wheel_init_tcp_twsl (tw, expired_timer_cb, TCP_TIMER_TICK, ~0);
tw->last_run_time = now;
}