Move pkt replication counter to the opaque2 cache line
[vpp.git] / vlib / vlib / node.c
index 4fb117e..5d250d0 100644 (file)
@@ -61,13 +61,13 @@ static void node_set_elog_name (vlib_main_t * vm, uword node_index)
 
   t = vec_elt_at_index (vm->node_call_elog_event_types, node_index);
   vec_free (t->format);
-  t->format = (char *) format (0, "%v (%%d)", n->name);
+  t->format = (char *) format (0, "%v-call: %%d%c", n->name, 0);
 
   t = vec_elt_at_index (vm->node_return_elog_event_types, node_index);
   vec_free (t->format);
-  t->format = (char *) format (0, "%v () = %%d", n->name);
+  t->format = (char *) format (0, "%v-return: %%d%c", n->name, 0);
 
-  n->name_elog_string = elog_string (&vm->elog_main, "%v", n->name);
+  n->name_elog_string = elog_string (&vm->elog_main, "%v%c", n->name,0);
 }
 
 void vlib_node_rename (vlib_main_t * vm, u32 node_index, char * fmt, ...)
@@ -163,17 +163,8 @@ vlib_node_add_next_with_slot (vlib_main_t * vm,
   node = vec_elt (nm->nodes, node_index);
   next = vec_elt (nm->nodes, next_node_index);
 
-  /* Fill in static next nodes if runtime has yet to be initialized. */
-  if (slot == ~0 && ! (nm->flags & VLIB_NODE_MAIN_RUNTIME_STARTED))
-    {
-      uword i;
-      for (i = 0; i < vec_len (node->next_node_names); i++)
-       {
-         char * a = node->next_node_names[i];
-         if (a)
-           vlib_node_add_named_next_with_slot (vm, node->index, a, i);
-       }
-    }
+  /* Runtime has to be initialized. */
+  ASSERT(nm->flags & VLIB_NODE_MAIN_RUNTIME_STARTED);
 
   if ((p = hash_get (node->next_slot_by_node, next_node_index)))
     {
@@ -262,7 +253,7 @@ static void node_elog_init (vlib_main_t * vm, uword ni)
 }
 
 #ifdef CLIB_UNIX
-#define STACK_ALIGN 4096
+#define STACK_ALIGN (clib_mem_get_page_size())
 #else
 #define STACK_ALIGN CLIB_CACHE_LINE_BYTES
 #endif
@@ -272,6 +263,7 @@ static void register_node (vlib_main_t * vm,
 {
   vlib_node_main_t * nm = &vm->node_main;
   vlib_node_t * n;
+  u32 page_size = clib_mem_get_page_size();
   int i;
 
   if (CLIB_DEBUG > 0)
@@ -314,6 +306,8 @@ static void register_node (vlib_main_t * vm,
 
   /* Node index of next sibling will be filled in by vlib_node_main_init. */
   n->sibling_of = r->sibling_of;
+  if (r->sibling_of && r->n_next_nodes > 0)
+    clib_error ("sibling node should not have any next nodes `%v'", n->name);
 
   if (r->type == VLIB_NODE_TYPE_INTERNAL)
     ASSERT (r->vector_size > 0);
@@ -339,7 +333,7 @@ static void register_node (vlib_main_t * vm,
     {
       vec_resize (n->runtime_data, r->runtime_data_bytes);
       if (r->runtime_data)
-       memcpy (n->runtime_data, r->runtime_data, r->runtime_data_bytes);
+       clib_memcpy (n->runtime_data, r->runtime_data, r->runtime_data_bytes);
     }
 
   vec_resize (n->next_node_names, r->n_next_nodes);
@@ -363,9 +357,26 @@ static void register_node (vlib_main_t * vm,
 
        log2_n_stack_bytes = clib_max (r->process_log2_n_stack_bytes, 15);
 
-       p = clib_mem_alloc_aligned_no_fail 
+#ifdef CLIB_UNIX
+        /* 
+         * Bump the stack size if running over a kernel with a large page size,
+         * and the stack isn't any too big to begin with. Otherwise, we'll
+         * trip over the stack guard page for sure.
+         */
+        if ((page_size > (4<<10)) && log2_n_stack_bytes < 19)
+          {
+            if ((1<<log2_n_stack_bytes) <= page_size)
+              log2_n_stack_bytes = min_log2 (page_size) + 1;
+            else
+              log2_n_stack_bytes++;
+          }
+#endif
+
+       p = clib_mem_alloc_aligned_at_offset 
             (sizeof (p[0]) + (1 << log2_n_stack_bytes),
-             STACK_ALIGN);
+             STACK_ALIGN, STRUCT_OFFSET_OF (vlib_process_t, stack));
+        if (p == 0)
+            clib_panic ("failed to allocate process stack (%d bytes)", 1<<log2_n_stack_bytes);
 
        memset (p, 0, sizeof (p[0]));
        p->log2_n_stack_bytes = log2_n_stack_bytes;
@@ -388,7 +399,7 @@ static void register_node (vlib_main_t * vm,
          * Disallow writes to the bottom page of the stack, to
          * catch stack overflows.
          */
-        if (mprotect (p->stack, 4096, PROT_READ) < 0)
+        if (mprotect (p->stack, page_size, PROT_READ) < 0)
             clib_unix_warning ("process stack");
 #endif
 
@@ -421,7 +432,7 @@ static void register_node (vlib_main_t * vm,
 
     ASSERT (vec_len (n->runtime_data) <= sizeof (rt->runtime_data));
     if (vec_len (n->runtime_data) > 0)
-      memcpy (rt->runtime_data, n->runtime_data, vec_len (n->runtime_data));
+      clib_memcpy (rt->runtime_data, n->runtime_data, vec_len (n->runtime_data));
 
     vec_free (n->runtime_data);
   }
@@ -455,6 +466,40 @@ vlib_node_main_init (vlib_main_t * vm)
 
   nm->flags |= VLIB_NODE_MAIN_RUNTIME_STARTED;
 
+  /* Generate sibling relationships */
+  {
+    vlib_node_t * n, * sib;
+    uword si;
+
+    for (ni = 0; ni < vec_len (nm->nodes); ni++)
+      {
+       n = vec_elt (nm->nodes, ni);
+
+       if (! n->sibling_of)
+         continue;
+
+       sib = vlib_get_node_by_name (vm, (u8 *) n->sibling_of);
+       if (! sib)
+         clib_error ("sibling `%s' not found for node `%v'", n->sibling_of, n->name);
+
+       clib_bitmap_foreach (si, sib->sibling_bitmap, ({
+             vlib_node_t * m = vec_elt (nm->nodes, si);
+
+             /* Connect all of sibling's siblings to us. */
+             m->sibling_bitmap = clib_bitmap_ori (m->sibling_bitmap, n->index);
+
+             /* Connect us to all of sibling's siblings. */
+             n->sibling_bitmap = clib_bitmap_ori (n->sibling_bitmap, si);
+           }));
+
+       /* Connect sibling to us. */
+       sib->sibling_bitmap = clib_bitmap_ori (sib->sibling_bitmap, n->index);
+
+       /* Connect us to sibling. */
+       n->sibling_bitmap = clib_bitmap_ori (n->sibling_bitmap, sib->index);
+      }
+  }
+
   /* Resolve next names into next indices. */
   for (ni = 0; ni < vec_len (nm->nodes); ni++)
     {
@@ -527,40 +572,6 @@ vlib_node_main_init (vlib_main_t * vm)
       }
   }
 
-  /* Generate node sibling relationships. */
-  {
-    vlib_node_t * n, * sib;
-    uword si;
-
-    for (ni = 0; ni < vec_len (nm->nodes); ni++)
-      {
-       n = vec_elt (nm->nodes, ni);
-
-       if (! n->sibling_of)
-         continue;
-
-       sib = vlib_get_node_by_name (vm, (u8 *) n->sibling_of);
-       if (! sib)
-         clib_error ("sibling `%s' not found for node `%v'", n->sibling_of, n->name);
-
-       clib_bitmap_foreach (si, sib->sibling_bitmap, ({
-         vlib_node_t * m = vec_elt (nm->nodes, si);
-
-         /* Connect all of sibling's siblings to us. */
-         m->sibling_bitmap = clib_bitmap_ori (m->sibling_bitmap, n->index);
-
-         /* Connect us to all of sibling's siblings. */
-         n->sibling_bitmap = clib_bitmap_ori (n->sibling_bitmap, si);
-       }));
-
-       /* Connect sibling to us. */
-       sib->sibling_bitmap = clib_bitmap_ori (sib->sibling_bitmap, n->index);
-
-       /* Connect us to sibling. */
-       n->sibling_bitmap = clib_bitmap_ori (n->sibling_bitmap, sib->index);
-      }
-  }
-
  done:
   return error;
 }