session: improve enable and disable handling

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I3c79d16f6a19767d990e8a4683c296219b559ccd
diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c
index 22aaaeb..c5e2cc1 100644
--- a/src/plugins/http/http.c
+++ b/src/plugins/http/http.c
@@ -1392,8 +1392,6 @@
       return 0;
     }
 
-  vec_validate (hm->wrk, vlib_num_workers ());
-
   clib_memset (a, 0, sizeof (*a));
   clib_memset (options, 0, sizeof (options));
 
@@ -1415,10 +1413,16 @@
   hm->app_index = a->app_index;
   vec_free (a->name);
 
+  if (hm->is_init)
+    return 0;
+
+  vec_validate (hm->wrk, vlib_num_workers ());
+
   clib_timebase_init (&hm->timebase, 0 /* GMT */, CLIB_TIMEBASE_DAYLIGHT_NONE,
 		      &vm->clib_time /* share the system clock */);
 
   http_timers_init (vm, http_conn_timeout_cb);
+  hm->is_init = 1;
 
   return 0;
 }
diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h
index e3ee93b..debdebc 100644
--- a/src/plugins/http/http.h
+++ b/src/plugins/http/http.h
@@ -369,6 +369,7 @@
    * Runtime config
    */
   u8 debug_level;
+  u8 is_init;
 
   /*
    * Config
diff --git a/src/plugins/http/http_timer.c b/src/plugins/http/http_timer.c
index c8fc632..5ee8efc 100644
--- a/src/plugins/http/http_timer.c
+++ b/src/plugins/http/http_timer.c
@@ -71,8 +71,8 @@
   http_tw_ctx_t *twc = &http_tw_ctx;
   vlib_node_t *n;
 
-  if (twc->tw.timers)
-    return;
+  ASSERT (twc->tw.timers == 0);
+
   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/vnet/session/application_local.c b/src/vnet/session/application_local.c
index 064dd6f..3ac2ba4 100644
--- a/src/vnet/session/application_local.c
+++ b/src/vnet/session/application_local.c
@@ -70,6 +70,7 @@
   u32 **fwrk_pending_connects;		/**< First wrk pending half-opens */
   u32 fwrk_thread;			/**< First worker thread */
   u8 fwrk_have_flush;			/**< Flag for connect flush rpc */
+  u8 is_init;
 } ct_main_t;
 
 static ct_main_t ct_main;
@@ -1353,19 +1354,19 @@
   if (is_en == 0)
     return 0;
 
+  if (cm->is_init)
+    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)
-    {
-      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);
+  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);
+  cm->is_init = 1;
+
   return 0;
 }
 
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 5897693..f159851 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -2152,6 +2152,16 @@
     }
 }
 
+static void
+session_main_start_q_process (vlib_main_t *vm, vlib_node_state_t state)
+{
+  vlib_node_t *n;
+
+  vlib_node_set_state (vm, session_queue_process_node.index, state);
+  n = vlib_get_node (vm, session_queue_process_node.index);
+  vlib_start_process (vm, n->runtime_index);
+}
+
 void
 session_node_enable_disable (u8 is_en)
 {
@@ -2159,7 +2169,6 @@
   u8 state = is_en ? VLIB_NODE_STATE_POLLING : VLIB_NODE_STATE_DISABLED;
   session_main_t *sm = &session_main;
   vlib_main_t *vm;
-  vlib_node_t *n;
   int n_vlibs, i;
 
   n_vlibs = vlib_get_n_threads ();
@@ -2173,10 +2182,7 @@
 	  if (is_en)
 	    {
 	      session_main_get_worker (0)->state = SESSION_WRK_INTERRUPT;
-	      vlib_node_set_state (vm, session_queue_process_node.index,
-				   state);
-	      n = vlib_get_node (vm, session_queue_process_node.index);
-	      vlib_start_process (vm, n->runtime_index);
+	      session_main_start_q_process (vm, state);
 	    }
 	  else
 	    {
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index 0ec158f..a6804f7 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -2163,6 +2163,8 @@
 	  session_queue_run_on_main (vm);
 	  break;
 	case SESSION_Q_PROCESS_STOP:
+	  /* Free event_data, the node will be restarted if needed */
+	  vec_free (event_data);
 	  vlib_node_set_state (vm, session_queue_process_node.index,
 			       VLIB_NODE_STATE_DISABLED);
 	  timeout = 100000.0;
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 28d7ed9..1d164f2 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -1512,6 +1512,10 @@
   clib_error_t *error = 0;
   int thread;
 
+  /* Already initialized */
+  if (tm->wrk_ctx)
+    return 0;
+
   if ((error = vlib_call_init_function (vm, ip_main_init)))
     return error;
   if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
diff --git a/src/vnet/tcp/tcp_timer.c b/src/vnet/tcp/tcp_timer.c
index 8ae3f22..4d1c062 100644
--- a/src/vnet/tcp/tcp_timer.c
+++ b/src/vnet/tcp/tcp_timer.c
@@ -20,8 +20,7 @@
 tcp_timer_initialize_wheel (tcp_timer_wheel_t * tw,
 			    void (*expired_timer_cb) (u32 *), f64 now)
 {
-  if (tw->timers)
-    return;
+  ASSERT (tw->timers == 0);
   tw_timer_wheel_init_tcp_twsl (tw, expired_timer_cb, TCP_TIMER_TICK, ~0);
   tw->last_run_time = now;
 }
diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c
index 9c1121f..8deeb9e 100644
--- a/src/vnet/udp/udp.c
+++ b/src/vnet/udp/udp.c
@@ -590,6 +590,9 @@
 {
   udp_main_t *um = &udp_main;
 
+  if (!is_en || um->is_init)
+    return 0;
+
   /* Not ideal. The sparse vector used to map ports to next nodes assumes
    * only a few ports are ever used. When udp transport is enabled this does
    * not hold and, to make matters worse, ports are consumed in a random
@@ -610,6 +613,7 @@
 
   vec_validate (um->transport_ports_refcnt[0], 65535);
   vec_validate (um->transport_ports_refcnt[1], 65535);
+  um->is_init = 1;
 
   return 0;
 }
diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h
index 8e4e87f..c6f8675 100644
--- a/src/vnet/udp/udp.h
+++ b/src/vnet/udp/udp.h
@@ -154,6 +154,7 @@
   u16 default_mtu;
   u16 msg_id_base;
   u8 csum_offload;
+  u8 is_init;
 
   u8 icmp_send_unreachable_disabled;
 } udp_main_t;