IPSEC-GRE: fixes and API update to common types.
[vpp.git] / src / vlib / threads.c
index 45e4d89..7d17c7b 100644 (file)
@@ -719,8 +719,6 @@ start_workers (vlib_main_t * vm)
       for (i = 0; i < vec_len (tm->registrations); i++)
        {
          vlib_node_main_t *nm, *nm_clone;
-         vlib_buffer_free_list_t *fl_clone, *fl_orig;
-         vlib_buffer_free_list_t *orig_freelist_pool;
          int k;
 
          tr = tm->registrations[i];
@@ -801,7 +799,7 @@ start_workers (vlib_main_t * vm)
 
              /* fork the frame dispatch queue */
              nm_clone->pending_frames = 0;
-             vec_validate (nm_clone->pending_frames, 10);      /* $$$$$?????? */
+             vec_validate (nm_clone->pending_frames, 10);
              _vec_len (nm_clone->pending_frames) = 0;
 
              /* fork nodes */
@@ -850,12 +848,29 @@ start_workers (vlib_main_t * vm)
                                         n->runtime_data_bytes));
              }
 
+             nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT] =
+               vec_dup_aligned (nm->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT],
+                                CLIB_CACHE_LINE_BYTES);
+             vec_foreach (rt,
+                          nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT])
+             {
+               vlib_node_t *n = vlib_get_node (vm, rt->node_index);
+               rt->thread_index = vm_clone->thread_index;
+               /* copy initial runtime_data from node */
+               if (n->runtime_data && n->runtime_data_bytes > 0)
+                 clib_memcpy (rt->runtime_data, n->runtime_data,
+                              clib_min (VLIB_NODE_RUNTIME_DATA_SIZE,
+                                        n->runtime_data_bytes));
+             }
+
              nm_clone->processes = vec_dup_aligned (nm->processes,
                                                     CLIB_CACHE_LINE_BYTES);
 
-             /* zap the (per worker) frame freelists, etc */
-             nm_clone->frame_sizes = 0;
+             /* Create per-thread frame freelist */
+             nm_clone->frame_sizes = vec_new (vlib_frame_size_t, 1);
+#ifdef VLIB_SUPPORTS_ARBITRARY_SCALAR_SIZES
              nm_clone->frame_size_hash = hash_create (0, sizeof (uword));
+#endif
 
              /* Packet trace buffers are guaranteed to be empty, nothing to do here */
 
@@ -868,26 +883,6 @@ start_workers (vlib_main_t * vm)
                (vlib_mains[0]->error_main.counters_last_clear,
                 CLIB_CACHE_LINE_BYTES);
 
-             /* Fork the vlib_buffer_main_t free lists, etc. */
-             orig_freelist_pool = vm_clone->buffer_free_list_pool;
-             vm_clone->buffer_free_list_pool = 0;
-
-            /* *INDENT-OFF* */
-            pool_foreach (fl_orig, orig_freelist_pool,
-                          ({
-                            pool_get_aligned (vm_clone->buffer_free_list_pool,
-                                              fl_clone, CLIB_CACHE_LINE_BYTES);
-                            ASSERT (fl_orig - orig_freelist_pool
-                                    == fl_clone - vm_clone->buffer_free_list_pool);
-
-                            fl_clone[0] = fl_orig[0];
-                            fl_clone->buffers = 0;
-                            vec_validate(fl_clone->buffers, 0);
-                            vec_reset_length(fl_clone->buffers);
-                            fl_clone->n_alloc = 0;
-                          }));
-/* *INDENT-ON* */
-
              worker_thread_index++;
            }
        }
@@ -1173,6 +1168,33 @@ vlib_worker_thread_node_refork (void)
 
   vec_free (old_rt);
 
+  /* re-clone pre-input nodes */
+  old_rt = nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT];
+  nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT] =
+    vec_dup_aligned (nm->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT],
+                    CLIB_CACHE_LINE_BYTES);
+
+  vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT])
+  {
+    vlib_node_t *n = vlib_get_node (vm, rt->node_index);
+    rt->thread_index = vm_clone->thread_index;
+    /* copy runtime_data, will be overwritten later for existing rt */
+    if (n->runtime_data && n->runtime_data_bytes > 0)
+      clib_memcpy_fast (rt->runtime_data, n->runtime_data,
+                       clib_min (VLIB_NODE_RUNTIME_DATA_SIZE,
+                                 n->runtime_data_bytes));
+  }
+
+  for (j = 0; j < vec_len (old_rt); j++)
+    {
+      rt = vlib_node_get_runtime (vm_clone, old_rt[j].node_index);
+      rt->state = old_rt[j].state;
+      clib_memcpy_fast (rt->runtime_data, old_rt[j].runtime_data,
+                       VLIB_NODE_RUNTIME_DATA_SIZE);
+    }
+
+  vec_free (old_rt);
+
   nm_clone->processes = vec_dup_aligned (nm->processes,
                                         CLIB_CACHE_LINE_BYTES);
 }
@@ -1360,7 +1382,7 @@ vlib_worker_thread_fork_fixup (vlib_fork_fixup_t which)
 #endif
 
 void
-vlib_worker_thread_barrier_sync_int (vlib_main_t * vm)
+vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name)
 {
   f64 deadline;
   f64 now;
@@ -1374,6 +1396,7 @@ vlib_worker_thread_barrier_sync_int (vlib_main_t * vm)
 
   ASSERT (vlib_get_thread_index () == 0);
 
+  vlib_worker_threads[0].barrier_caller = func_name;
   count = vec_len (vlib_mains) - 1;
 
   /* Record entry relative to last close */
@@ -1490,6 +1513,14 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm)
 
   deadline = now + BARRIER_SYNC_TIMEOUT;
 
+  /*
+   * Note when we let go of the barrier.
+   * Workers can use this to derive a reasonably accurate
+   * time offset. See vlib_time_now(...)
+   */
+  vm->time_last_barrier_release = vlib_time_now (vm);
+  CLIB_MEMORY_STORE_BARRIER ();
+
   *vlib_worker_threads->wait_at_barrier = 0;
 
   while (*vlib_worker_threads->workers_at_barrier > 0)
@@ -1681,9 +1712,6 @@ vlib_worker_thread_fn (void *arg)
 
   ASSERT (vm->thread_index == vlib_get_thread_index ());
 
-  vm->cpu_index = clib_get_current_cpu_index ();
-  vm->numa_node = clib_get_current_numa_node ();
-
   vlib_worker_thread_init (w);
   clib_time_init (&vm->clib_time);
   clib_mem_set_heap (w->thread_mheap);
@@ -1791,6 +1819,45 @@ threads_init (vlib_main_t * vm)
 
 VLIB_INIT_FUNCTION (threads_init);
 
+
+static clib_error_t *
+show_clock_command_fn (vlib_main_t * vm,
+                      unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+  int i;
+  f64 now;
+
+  now = vlib_time_now (vm);
+
+  vlib_cli_output (vm, "Time now %.9f", now);
+
+  if (vec_len (vlib_mains) == 1)
+    return 0;
+
+  vlib_cli_output (vm, "Time last barrier release %.9f",
+                  vm->time_last_barrier_release);
+
+  for (i = 1; i < vec_len (vlib_mains); i++)
+    {
+      if (vlib_mains[i] == 0)
+       continue;
+      vlib_cli_output (vm, "Thread %d offset %.9f error %.9f", i,
+                      vlib_mains[i]->time_offset,
+                      vm->time_last_barrier_release -
+                      vlib_mains[i]->time_last_barrier_release);
+    }
+  return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (f_command, static) =
+{
+  .path = "show clock",
+  .short_help = "show clock",
+  .function = show_clock_command_fn,
+};
+/* *INDENT-ON* */
+
 /*
  * fd.io coding-style-patch-verification: ON
  *