summaryrefslogtreecommitdiffstats
path: root/src/vnet/l2/l2_output.c
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2017-07-12 19:56:45 -0400
committerJohn Lo <loj@cisco.com>2017-07-13 11:52:24 +0000
commitb2fd6cb586fe69082cc12995910c65843fc5bb4a (patch)
tree6ff8c02296daf90b786c26685862c5155a2cb5aa /src/vnet/l2/l2_output.c
parent8ae1873a3f3368a942a1b02e7d4b60b005364a90 (diff)
Fix crash with worker threads on 4K VXLAN/BD setup (VPP-907)
Cleanup mapping of interface output node for the l2-output node when interface is configured to L2 or L3 modes. The mapping is now always done in the main thread as part of API/CLI processing, instead of initiate mapping in the forwarding path which can be in the worker threads. Change-Id: Ia789493e7d9f5c76d68edfaf34db43f3e3f53506 Signed-off-by: John Lo <loj@cisco.com> (cherry picked from commit bea5ebf205e0bec922bf26c6c1a6a9392b4cad67)
Diffstat (limited to 'src/vnet/l2/l2_output.c')
-rw-r--r--src/vnet/l2/l2_output.c83
1 files changed, 10 insertions, 73 deletions
diff --git a/src/vnet/l2/l2_output.c b/src/vnet/l2/l2_output.c
index e17b2a16675..51d5e1453fb 100644
--- a/src/vnet/l2/l2_output.c
+++ b/src/vnet/l2/l2_output.c
@@ -601,90 +601,27 @@ VLIB_NODE_FUNCTION_MULTIARCH (l2output_node, l2output_node_fn)
mp->next_nodes.feat_next_node_index);
/* Initialize the output node mapping table */
- l2output_init_output_node_vec (&mp->next_nodes.output_node_index_vec);
+ vec_validate_init_empty (mp->next_nodes.output_node_index_vec, 100,
+ L2OUTPUT_NEXT_DROP);
return 0;
}
VLIB_INIT_FUNCTION (l2output_init);
-typedef struct
-{
- u32 node_index;
- u32 sw_if_index;
-} output_node_mapping_rpc_args_t;
-
-static void output_node_rpc_callback (output_node_mapping_rpc_args_t * a);
-
-static void
-output_node_mapping_send_rpc (u32 node_index, u32 sw_if_index)
-{
- output_node_mapping_rpc_args_t args;
- void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
-
- args.node_index = node_index;
- args.sw_if_index = sw_if_index;
-
- vl_api_rpc_call_main_thread (output_node_rpc_callback,
- (u8 *) & args, sizeof (args));
-}
-
/** Create a mapping in the next node mapping table for the given sw_if_index. */
-u32
-l2output_create_output_node_mapping (vlib_main_t * vlib_main, vnet_main_t * vnet_main, u32 node_index, /* index of current node */
- u32 * output_node_index_vec,
- u32 sw_if_index)
-{
-
- u32 next; /* index of next graph node */
- vnet_hw_interface_t *hw0;
- u32 *node;
-
- hw0 = vnet_get_sup_hw_interface (vnet_main, sw_if_index);
-
- uword thread_index;
-
- thread_index = vlib_get_thread_index ();
-
- if (thread_index)
- {
- u32 oldflags;
-
- oldflags = __sync_fetch_and_or (&hw0->flags,
- VNET_HW_INTERFACE_FLAG_L2OUTPUT_MAPPED);
-
- if ((oldflags & VNET_HW_INTERFACE_FLAG_L2OUTPUT_MAPPED))
- return L2OUTPUT_NEXT_DROP;
-
- output_node_mapping_send_rpc (node_index, sw_if_index);
- return L2OUTPUT_NEXT_DROP;
- }
-
- /* dynamically create graph node arc */
- next = vlib_node_add_next (vlib_main, node_index, hw0->output_node_index);
-
- /* Initialize vector with the mapping */
-
- node = vec_elt_at_index (output_node_index_vec, sw_if_index);
- *node = next;
-
- /* reset mapping bit, includes memory barrier */
- __sync_fetch_and_and (&hw0->flags, ~VNET_HW_INTERFACE_FLAG_L2OUTPUT_MAPPED);
-
- return next;
-}
-
void
-output_node_rpc_callback (output_node_mapping_rpc_args_t * a)
+l2output_create_output_node_mapping (vlib_main_t * vlib_main,
+ vnet_main_t * vnet_main, u32 sw_if_index)
{
- vlib_main_t *vm = vlib_get_main ();
- vnet_main_t *vnm = vnet_get_main ();
- l2output_main_t *mp = &l2output_main;
+ vnet_hw_interface_t *hw0 =
+ vnet_get_sup_hw_interface (vnet_main, sw_if_index);
- (void) l2output_create_output_node_mapping
- (vm, vnm, a->node_index, mp->next_nodes.output_node_index_vec,
- a->sw_if_index);
+ /* dynamically create graph node arc */
+ u32 next = vlib_node_add_next (vlib_main, l2output_node.index,
+ hw0->output_node_index);
+ l2output_main.next_nodes.output_node_index_vec[sw_if_index] = next;
}
/* Get a pointer to the config for the given interface */