nat: avoid running pointless session cleanups 10/25210/4
authorKlement Sekera <ksekera@cisco.com>
Mon, 17 Feb 2020 13:37:20 +0000 (13:37 +0000)
committerOle Trøan <otroan@employees.org>
Thu, 20 Feb 2020 08:49:28 +0000 (08:49 +0000)
Save the next session timeout when sweeping sessions for cleanup so that
we can avoid unnecessary runs of the sweeping algorithm.

Type: fix
Change-Id: I736d00f2dfe242af10f963fbe34b11128f8b0613
Signed-off-by: Klement Sekera <ksekera@cisco.com>
src/plugins/nat/nat.c
src/plugins/nat/nat.h
src/plugins/nat/nat44/inlines.h

index 9f51658..0714708 100755 (executable)
@@ -3935,6 +3935,7 @@ snat_config (vlib_main_t * vm, unformat_input_t * input)
           /* *INDENT-OFF* */
           vec_foreach (tsm, sm->per_thread_data)
             {
+             tsm->min_session_timeout = 0;
               if (sm->endpoint_dependent)
                 {
                   clib_bihash_init_16_8 (&tsm->in2out_ed, "in2out-ed",
index 9cde968..fd7ec3b 100644 (file)
@@ -516,6 +516,9 @@ typedef struct
 
   /* real thread index */
   u32 thread_index;
+
+  /* discovered minimum session timeout time */
+  u64 min_session_timeout;
 } snat_main_per_thread_data_t;
 
 struct snat_main_s;
index d7c3554..52dd37c 100644 (file)
@@ -65,7 +65,11 @@ nat44_user_try_cleanup (snat_user_t * u, u32 thread_index, f64 now)
        (f64) nat44_session_get_timeout (sm, s);
 
       if (now < sess_timeout_time)
-       continue;
+       {
+         tsm->min_session_timeout =
+           clib_min (sess_timeout_time, tsm->min_session_timeout);
+         continue;
+       }
 
       nat44_session_cleanup (s, thread_index);
     }
@@ -93,19 +97,33 @@ nat44_session_try_cleanup (ip4_address_t * addr,
       if (PREDICT_TRUE (pool_elts (tsm->sessions) < sm->max_translations))
        return;
 
-      // there is no place so we try to cleanup all users in this thread
-      /* *INDENT-OFF* */
-      pool_foreach (u, tsm->users,
-      ({
-        nat44_user_try_cleanup (u, thread_index, now);
-      }));
-      /* *INDENT-ON* */
+      if (now >= tsm->min_session_timeout)
+       {
+         tsm->min_session_timeout = ~0;
+         // there is no place so we try to cleanup all users in this thread
+          /* *INDENT-OFF* */
+          pool_foreach (u, tsm->users,
+                        ({ nat44_user_try_cleanup (u, thread_index, now); }));
+          /* *INDENT-ON* */
+         if (~0 == tsm->min_session_timeout)
+           {
+             tsm->min_session_timeout = 0;
+           }
+       }
       return;
     }
 
-  // each time user creates a new session we try to cleanup expired sessions
-  nat44_user_try_cleanup (pool_elt_at_index (tsm->users, value.value),
-                         thread_index, now);
+  if (now >= tsm->min_session_timeout)
+    {
+      tsm->min_session_timeout = ~0;
+      // each time user creates a new session we try to cleanup expired sessions
+      nat44_user_try_cleanup (pool_elt_at_index (tsm->users, value.value),
+                             thread_index, now);
+      if (~0 == tsm->min_session_timeout)
+       {
+         tsm->min_session_timeout = 0;
+       }
+    }
 }
 
 static_always_inline void