nat: fix memory leak and refactor nat44-ed db init/free. 83/37683/5
authorHuawei LI <[email protected]>
Mon, 21 Nov 2022 13:54:50 +0000 (21:54 +0800)
committerOle Tr�an <[email protected]>
Mon, 19 Dec 2022 08:06:53 +0000 (08:06 +0000)
fix memory leak and refactor nat44-ed db init/free through.
how to reproduce memory leak: input "set nat44 session limit
50000 vrf 1" repeatedly.

Program received signal SIGABRT, Aborted.
0x00007ff4b3cc5337 in raise () from /lib64/libc.so.6
(gdb) bt
0  0x00007ff4b3cc5337 in raise () from /lib64/libc.so.6
1  0x00007ff4b3cc6a28 in abort () from /lib64/libc.so.6
2  0x00000000004079db in os_panic () at /usr/src/debug/vpp-23.02/src/vpp/vnet/main.c:417
3  0x00007ff4b43e784f in os_out_of_memory ()
   at /usr/src/debug/vpp-23.02/src/vppinfra/unix-misc.c:221
4  0x00007ff4b43a71aa in clib_mem_heap_alloc_inline (heap=0x0, size=27263040, align=64,
   os_out_of_memory_on_failure=1) at /usr/src/debug/vpp-23.02/src/vppinfra/mem_dlmalloc.c:613
5  0x00007ff4b43a7256 in clib_mem_alloc_aligned (size=27263040, align=64)
   at /usr/src/debug/vpp-23.02/src/vppinfra/mem_dlmalloc.c:635
6  0x00007ff4b522fafa in alloc_aligned_16_8 (h=0x7ff46a7815b8 <snat_main+408>, nbytes=27262976)
   at /usr/src/debug/vpp-23.02/src/vppinfra/bihash_template.c:59
7  0x00007ff4b522fd12 in clib_bihash_instantiate_16_8 (h=0x7ff46a7815b8 <snat_main+408>)
   at /usr/src/debug/vpp-23.02/src/vppinfra/bihash_template.c:163
8  0x00007ff4b5230037 in clib_bihash_init2_16_8 (a=0x7ff465f36870)
   at /usr/src/debug/vpp-23.02/src/vppinfra/bihash_template.c:245
9  0x00007ff4b52300ac in clib_bihash_init_16_8 (h=0x7ff46a7815b8 <snat_main+408>,
   name=0x7ff46a754871 "ed-flow-hash", nbuckets=262144, memory_size=0)
   at /usr/src/debug/vpp-23.02/src/vppinfra/bihash_template.c:260
10 0x00007ff46a7013e8 in reinit_ed_flow_hash ()
   at /usr/src/debug/vpp-23.02/src/plugins/nat/nat44-ed/nat44_ed.c:3264
11 0x00007ff46a7014fd in nat44_ed_sessions_clear ()
   at /usr/src/debug/vpp-23.02/src/plugins/nat/nat44-ed/nat44_ed.c:3299
12 0x00007ff46a701044 in nat44_update_session_limit (session_limit=70000, vrf_id=1)
   at /usr/src/debug/vpp-23.02/src/plugins/nat/nat44-ed/nat44_ed.c:3225
13 0x00007ff46a73d3d1 in nat44_set_session_limit_command_fn (vm=0x7ff473c8f740,
   input=0x7ff465f36ef0, cmd=0x7ff474c5ce48)
   at /usr/src/debug/vpp-23.02/src/plugins/nat/nat44-ed/nat44_ed_cli.c:1638
14 0x00007ff4b5d56527 in vlib_cli_dispatch_sub_commands (vm=0x7ff473c8f740,
   cm=0x4273f0 <vlib_global_main+48>, input=0x7ff465f36ef0, parent_command_index=97)
   at /usr/src/debug/vpp-23.02/src/vlib/cli.c:650
15 0x00007ff4b5d562c3 in vlib_cli_dispatch_sub_commands (vm=0x7ff473c8f740,
   cm=0x4273f0 <vlib_global_main+48>, input=0x7ff465f36ef0, parent_command_index=98)
   at /usr/src/debug/vpp-23.02/src/vlib/cli.c:607
16 0x00007ff4b5d562c3 in vlib_cli_dispatch_sub_commands (vm=0x7ff473c8f740,
   cm=0x4273f0 <vlib_global_main+48>, input=0x7ff465f36ef0, parent_command_index=21)
   at /usr/src/debug/vpp-23.02/src/vlib/cli.c:607
17 0x00007ff4b5d562c3 in vlib_cli_dispatch_sub_commands (vm=0x7ff473c8f740,
   cm=0x4273f0 <vlib_global_main+48>, input=0x7ff465f36ef0, parent_command_index=0)
   at /usr/src/debug/vpp-23.02/src/vlib/cli.c:607
18 0x00007ff4b5d569cb in vlib_cli_input (vm=0x7ff473c8f740, input=0x7ff465f36ef0,
   function=0x7ff4b5dc2406 <unix_vlib_cli_output>, function_arg=0)
---Type <return> to continue, or q <return> to quit---
   at /usr/src/debug/vpp-23.02/src/vlib/cli.c:753
19 0x00007ff4b5dc7b0c in unix_cli_process_input (cm=0x7ff4b5e4ae00 <unix_cli_main>,
   cli_file_index=0) at /usr/src/debug/vpp-23.02/src/vlib/unix/cli.c:2616
20 0x00007ff4b5dc825a in unix_cli_process (vm=0x7ff473c8f740, rt=0x7ff4797a5280, f=0x0)
   at /usr/src/debug/vpp-23.02/src/vlib/unix/cli.c:2745
21 0x00007ff4b5d80a25 in vlib_process_bootstrap (_a=140687718901968)
   at /usr/src/debug/vpp-23.02/src/vlib/main.c:1221
22 0x00007ff4b439e298 in clib_calljmp () at /usr/src/debug/vpp-23.02/src/vppinfra/longjmp.S:123
23 0x00007ff4698268a0 in ?? ()
24 0x00007ff4b5d80b4e in vlib_process_startup (vm=0x7ff4b43a77a3 <clib_mem_size+24>,
   p=0x7ff4698268d0, f=0x7ff474b1e580) at /usr/src/debug/vpp-23.02/src/vlib/main.c:1246
25 0x00007ff4b5dbdbe6 in vec_max_bytes (v=0x8)
   at /usr/src/debug/vpp-23.02/src/vppinfra/vec_bootstrap.h:161
26 0x00007ff474b1e598 in ?? ()
27 0x0000000000000004 in ?? ()
28 0x00000000000000ff in ?? ()
29 0x00007ff469826980 in ?? ()
30 0x00007ff4b5dbddcb in _vec_set_len (
   v=<error reading variable: Cannot access memory at address 0xfffffffffffffff5>,
   len=<error reading variable: Cannot access memory at address 0xffffffffffffffed>,
   elt_sz=<error reading variable: Cannot access memory at address 0xffffffffffffffe5>)
   at /usr/src/debug/vpp-23.02/src/vppinfra/vec_bootstrap.h:196
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb)

Type: fix

Signed-off-by: Huawei LI <[email protected]>
Change-Id: I52a7d229c95e4ab30f7f2cfe574440aa37bed6a2

src/plugins/nat/nat44-ed/nat44_ed.c

index 82b9de1..e2ced3d 100644 (file)
@@ -147,7 +147,8 @@ VLIB_PLUGIN_REGISTER () = {
     .description = "Network Address Translation (NAT)",
 };
 
-static void nat44_ed_db_init (u32 translations, u32 translation_buckets);
+static void nat44_ed_db_init ();
+static void nat44_ed_db_free ();
 static void nat44_ed_worker_db_free (snat_main_per_thread_data_t *tsm);
 
 static int nat44_ed_add_static_mapping_internal (
@@ -2452,7 +2453,7 @@ nat44_plugin_enable (nat44_config_t c)
   sm->outside_fib_index = fib_table_find_or_create_and_lock (
     FIB_PROTOCOL_IP4, c.outside_vrf, sm->fib_src_hi);
 
-  nat44_ed_db_init (sm->max_translations_per_thread, sm->translation_buckets);
+  nat44_ed_db_init ();
 
   nat_affinity_enable ();
 
@@ -2667,7 +2668,6 @@ nat44_ed_del_static_mappings ()
 int
 nat44_plugin_disable ()
 {
-  snat_main_per_thread_data_t *tsm;
   snat_main_t *sm = &snat_main;
   int rc, error = 0;
 
@@ -2694,12 +2694,7 @@ nat44_plugin_disable ()
   vec_free (sm->max_translations_per_fib);
   sm->max_translations_per_fib = 0;
 
-  clib_bihash_free_16_8 (&sm->flow_hash);
-
-  vec_foreach (tsm, sm->per_thread_data)
-    {
-      nat44_ed_worker_db_free (tsm);
-    }
+  nat44_ed_db_free ();
 
   clib_memset (&sm->rconfig, 0, sizeof (sm->rconfig));
 
@@ -3276,11 +3271,11 @@ nat44_update_session_limit (u32 session_limit, u32 vrf_id)
 }
 
 static void
-nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations,
-                        u32 translation_buckets)
+nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations)
 {
   dlist_elt_t *head;
 
+  pool_alloc (tsm->per_vrf_sessions_pool, translations);
   pool_alloc (tsm->sessions, translations);
   pool_alloc (tsm->lru_pool, translations);
 
@@ -3306,7 +3301,7 @@ nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations,
 }
 
 static void
-reinit_ed_flow_hash ()
+nat44_ed_flow_hash_init ()
 {
   snat_main_t *sm = &snat_main;
   // we expect 2 flows per session, so multiply translation_buckets by 2
@@ -3317,17 +3312,16 @@ reinit_ed_flow_hash ()
 }
 
 static void
-nat44_ed_db_init (u32 translations, u32 translation_buckets)
+nat44_ed_db_init ()
 {
   snat_main_t *sm = &snat_main;
   snat_main_per_thread_data_t *tsm;
 
-  reinit_ed_flow_hash ();
+  nat44_ed_flow_hash_init ();
 
   vec_foreach (tsm, sm->per_thread_data)
     {
-      nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
-                              sm->translation_buckets);
+      nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread);
     }
 }
 
@@ -3339,20 +3333,35 @@ nat44_ed_worker_db_free (snat_main_per_thread_data_t *tsm)
   pool_free (tsm->per_vrf_sessions_pool);
 }
 
-void
-nat44_ed_sessions_clear ()
+static void
+nat44_ed_flow_hash_free ()
 {
   snat_main_t *sm = &snat_main;
-  snat_main_per_thread_data_t *tsm;
 
-  reinit_ed_flow_hash ();
+  clib_bihash_free_16_8 (&sm->flow_hash);
+}
+
+static void
+nat44_ed_db_free ()
+{
+  snat_main_t *sm = &snat_main;
+  snat_main_per_thread_data_t *tsm;
 
   vec_foreach (tsm, sm->per_thread_data)
     {
       nat44_ed_worker_db_free (tsm);
-      nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
-                              sm->translation_buckets);
     }
+
+  nat44_ed_flow_hash_free ();
+}
+
+void
+nat44_ed_sessions_clear ()
+{
+  snat_main_t *sm = &snat_main;
+
+  nat44_ed_db_free ();
+  nat44_ed_db_init ();
   vlib_zero_simple_counter (&sm->total_sessions, 0);
 }