aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-06-29 00:19:08 -0700
committerNeale Ranns <nranns@cisco.com>2017-06-30 11:56:59 +0000
commita8f93f87b9bac7e76795fbd6b46dc0305c34c3e1 (patch)
tree896d57b3f818a2fafc67747498119bc7d9e86463
parent65ebc02dc9ea893e1a0408a7d733ba1968b034e3 (diff)
VPP debug image with worker threads hit assert on adding IP route with traffic (VPP-892)stable/1704
When stacking DPOs the VLIB graph is also updated to add the edge between the nodes, if this edge does not yet exist. This addition should be done with the workers stopped. Change-Id: I327e4d7d26f0b23eb280f17e4619ff2093ff7940 Signed-off-by: Neale Ranns <nranns@cisco.com> (cherry picked from commit c02bd03ddf5eec9e9c79811360685f13e4ba8ee1)
-rw-r--r--src/vlib/node.c20
-rw-r--r--src/vlib/node_funcs.h3
-rw-r--r--src/vnet/dpo/dpo.c17
3 files changed, 39 insertions, 1 deletions
diff --git a/src/vlib/node.c b/src/vlib/node.c
index dc0a4de5082..fe0abbdc394 100644
--- a/src/vlib/node.c
+++ b/src/vlib/node.c
@@ -151,6 +151,26 @@ vlib_node_runtime_update (vlib_main_t * vm, u32 node_index, u32 next_index)
vlib_worker_thread_barrier_release (vm);
}
+uword
+vlib_node_get_next (vlib_main_t * vm, uword node_index, uword next_node_index)
+{
+ vlib_node_main_t *nm = &vm->node_main;
+ vlib_node_t *node;
+ uword *p;
+
+ node = vec_elt (nm->nodes, node_index);
+
+ /* 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)))
+ {
+ return p[0];
+ }
+
+ return (~0);
+}
+
/* Add next node to given node in given slot. */
uword
vlib_node_add_next_with_slot (vlib_main_t * vm,
diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h
index 8ccfc438020..ee877a303d3 100644
--- a/src/vlib/node_funcs.h
+++ b/src/vlib/node_funcs.h
@@ -1052,6 +1052,9 @@ vlib_node_vectors_per_main_loop_as_integer (vlib_main_t * vm, u32 node_index)
void
vlib_frame_free (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_frame_t * f);
+/* Return the edge index if present, ~0 otherwise */
+uword vlib_node_get_next (vlib_main_t * vm, uword node, uword next_node);
+
/* Add next node to given node in given slot. */
uword
vlib_node_add_next_with_slot (vlib_main_t * vm,
diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c
index d8e075a7f2f..b51fb23dd65 100644
--- a/src/vnet/dpo/dpo.c
+++ b/src/vnet/dpo/dpo.c
@@ -316,6 +316,8 @@ dpo_get_next_node (dpo_type_t child_type,
vm = vlib_get_main();
+ vlib_worker_thread_barrier_sync(vm);
+
ASSERT(NULL != dpo_nodes[child_type]);
ASSERT(NULL != dpo_nodes[child_type][child_proto]);
ASSERT(NULL != dpo_nodes[parent_type]);
@@ -357,6 +359,8 @@ dpo_get_next_node (dpo_type_t child_type,
}
cc++;
}
+
+ vlib_worker_thread_barrier_release(vm);
}
return (dpo_edges[child_type][child_proto][parent_type][parent_proto]);
@@ -434,10 +438,21 @@ dpo_stack_from_node (u32 child_node_index,
parent_node =
vlib_get_node_by_name(vm, (u8*) dpo_nodes[parent_type][parent_proto][0]);
- edge = vlib_node_add_next(vm,
+ edge = vlib_node_get_next(vm,
child_node_index,
parent_node->index);
+ if (~0 == edge)
+ {
+ vlib_worker_thread_barrier_sync(vm);
+
+ edge = vlib_node_add_next(vm,
+ child_node_index,
+ parent_node->index);
+
+ vlib_worker_thread_barrier_release(vm);
+ }
+
dpo_stack_i(edge, dpo, parent);
}