Use thread local storage for thread index
[vpp.git] / src / vlib / buffer.c
index 4f5eb09..be3b41e 100644 (file)
@@ -44,6 +44,7 @@
  */
 
 #include <vlib/vlib.h>
+#include <vlib/unix/unix.h>
 
 uword
 vlib_buffer_length_in_chain_slow_path (vlib_main_t * vm,
@@ -261,7 +262,28 @@ done:
   return result;
 }
 
-vlib_main_t **vlib_mains;
+/*
+ * Hand-craft a static vector w/ length 1, so vec_len(vlib_mains) =1
+ * and vlib_mains[0] = &vlib_global_main from the beginning of time.
+ *
+ * The only place which should ever expand vlib_mains is start_workers()
+ * in threads.c. It knows about the bootstrap vector.
+ */
+/* *INDENT-OFF* */
+static struct
+{
+  vec_header_t h;
+  vlib_main_t *vm;
+} __attribute__ ((packed)) __bootstrap_vlib_main_vector
+  __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES))) =
+{
+  .h.len = 1,
+  .vm = &vlib_global_main,
+};
+/* *INDENT-ON* */
+
+vlib_main_t **vlib_mains = &__bootstrap_vlib_main_vector.vm;
+
 
 /* When dubugging validate that given buffers are either known allocated
    or known free. */
@@ -277,10 +299,10 @@ vlib_buffer_validate_alloc_free (vlib_main_t * vm,
   if (CLIB_DEBUG == 0)
     return;
 
-  ASSERT (os_get_cpu_number () == 0);
+  ASSERT (vlib_get_thread_index () == 0);
 
   /* smp disaster check */
-  if (vlib_mains)
+  if (vec_len (vlib_mains) > 1)
     ASSERT (vm == vlib_mains[0]);
 
   is_free = expected_state == VLIB_BUFFER_KNOWN_ALLOCATED;
@@ -333,7 +355,7 @@ vlib_buffer_create_free_list_helper (vlib_main_t * vm,
   vlib_buffer_free_list_t *f;
   int i;
 
-  ASSERT (os_get_cpu_number () == 0);
+  ASSERT (vlib_get_thread_index () == 0);
 
   if (!is_default && pool_elts (bm->buffer_free_list_pool) == 0)
     {
@@ -360,7 +382,7 @@ vlib_buffer_create_free_list_helper (vlib_main_t * vm,
   memset (f, 0, sizeof (f[0]));
   f->index = f - bm->buffer_free_list_pool;
   f->n_data_bytes = vlib_buffer_round_size (n_data_bytes);
-  f->min_n_buffers_each_physmem_alloc = 16;
+  f->min_n_buffers_each_physmem_alloc = VLIB_FRAME_SIZE;
   f->name = clib_mem_is_heap_object (name) ? name : format (0, "%s", name);
 
   /* Setup free buffer template. */
@@ -452,7 +474,7 @@ vlib_buffer_delete_free_list_internal (vlib_main_t * vm, u32 free_list_index)
   u32 merge_index;
   int i;
 
-  ASSERT (os_get_cpu_number () == 0);
+  ASSERT (vlib_get_thread_index () == 0);
 
   f = vlib_buffer_get_free_list (vm, free_list_index);
 
@@ -562,6 +584,11 @@ alloc_from_free_list (vlib_main_t * vm,
 
   dst = alloc_buffers;
 
+  /* wait with buffer memory allocation as long as possible
+     in case external buffer manager takes over */
+  if (PREDICT_FALSE (vm->os_physmem_alloc_aligned == 0))
+    unix_physmem_init (vm, 0 /* fail_if_physical_memory_not_present */ );
+
   n_filled = fill_free_list (vm, free_list, n_alloc_buffers);
   if (n_filled == 0)
     return 0;
@@ -956,7 +983,7 @@ show_buffers (vlib_main_t * vm,
 
   do
     {
-      curr_vm = vec_len (vlib_mains) ? vlib_mains[vm_index] : vm;
+      curr_vm = vlib_mains[vm_index];
       bm = curr_vm->buffer_main;
 
     /* *INDENT-OFF* */