diff options
Diffstat (limited to 'src/vnet/fib/fib_walk.c')
-rw-r--r-- | src/vnet/fib/fib_walk.c | 122 |
1 files changed, 102 insertions, 20 deletions
diff --git a/src/vnet/fib/fib_walk.c b/src/vnet/fib/fib_walk.c index 938f7b8c1c6..c570476d130 100644 --- a/src/vnet/fib/fib_walk.c +++ b/src/vnet/fib/fib_walk.c @@ -96,11 +96,6 @@ typedef struct fib_walk_t_ static fib_walk_t *fib_walk_pool; /** - * @brief There's only one event type sent to the walk process - */ -#define FIB_WALK_EVENT 0 - -/** * Statistics maintained per-walk queue */ typedef enum fib_walk_queue_stats_t_ @@ -240,10 +235,13 @@ fib_walk_queue_get_front (fib_walk_priority_t prio) } static void -fib_walk_destroy (fib_walk_t *fwalk) +fib_walk_destroy (index_t fwi) { + fib_walk_t *fwalk; u32 bucket, ii; + fwalk = fib_walk_get(fwi); + if (FIB_NODE_INDEX_INVALID != fwalk->fw_prio_sibling) { fib_node_list_elt_remove(fwalk->fw_prio_sibling); @@ -253,6 +251,12 @@ fib_walk_destroy (fib_walk_t *fwalk) fwalk->fw_dep_sibling); /* + * refetch the walk object. More walks could have been spawned as a result + * of releasing the lock on the parent. + */ + fwalk = fib_walk_get(fwi); + + /* * add the stats to the continuous histogram collection. */ bucket = (fwalk->fw_n_visits / HISTOGRAM_VISITS_PER_WALK_INCR); @@ -466,8 +470,7 @@ fib_walk_process_queues (vlib_main_t * vm, */ if (FIB_WALK_ADVANCE_MORE != rc) { - fwalk = fib_walk_get(fwi); - fib_walk_destroy(fwalk); + fib_walk_destroy(fwi); fib_walk_queues.fwqs_queues[prio].fwq_stats[FIB_WALK_COMPLETED]++; } else @@ -511,6 +514,16 @@ that_will_do_for_now: } /** + * Events sent to the FIB walk process + */ +typedef enum fib_walk_process_event_t_ +{ + FIB_WALK_PROCESS_EVENT_DATA, + FIB_WALK_PROCESS_EVENT_ENABLE, + FIB_WALK_PROCESS_EVENT_DISABLE, +} fib_walk_process_event; + +/** * @brief The 'fib-walk' process's main loop. */ static uword @@ -518,22 +531,47 @@ fib_walk_process (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f) { + uword event_type, *event_data = 0; f64 sleep_time; + int enabled; + enabled = 1; sleep_time = fib_walk_sleep_duration[FIB_WALK_SHORT_SLEEP]; while (1) { - vlib_process_wait_for_event_or_clock(vm, sleep_time); + /* + * the feature to disable/enable this walk process is only + * for testing purposes + */ + if (enabled) + { + vlib_process_wait_for_event_or_clock(vm, sleep_time); + } + else + { + vlib_process_wait_for_event(vm); + } - /* - * there may be lots of event queued between the processes, - * but the walks we want to schedule are in the priority queues, - * so we ignore the process events. - */ - vlib_process_get_events(vm, NULL); + event_type = vlib_process_get_events(vm, &event_data); + vec_reset_length(event_data); + + switch (event_type) + { + case FIB_WALK_PROCESS_EVENT_ENABLE: + enabled = 1; + break; + case FIB_WALK_PROCESS_EVENT_DISABLE: + enabled = 0; + break; + default: + break; + } - sleep_time = fib_walk_process_queues(vm, quota); + if (enabled) + { + sleep_time = fib_walk_process_queues(vm, quota); + } } /* @@ -610,8 +648,8 @@ fib_walk_prio_queue_enquue (fib_walk_priority_t prio, */ vlib_process_signal_event(vlib_get_main(), fib_walk_process_node.index, - FIB_WALK_EVENT, - FIB_WALK_EVENT); + FIB_WALK_PROCESS_EVENT_DATA, + 0); return (sibling); } @@ -742,7 +780,7 @@ fib_walk_sync (fib_node_type_t parent_type, ASSERT(FIB_NODE_INDEX_INVALID != merged_walk.fnp_index); ASSERT(FIB_NODE_TYPE_WALK == merged_walk.fnp_type); - fib_walk_destroy(fwalk); + fib_walk_destroy(fwi); fwi = merged_walk.fnp_index; fwalk = fib_walk_get(fwi); @@ -774,7 +812,7 @@ fib_walk_sync (fib_node_type_t parent_type, if (NULL != fwalk) { - fib_walk_destroy(fwalk); + fib_walk_destroy(fwi); } } @@ -1106,3 +1144,47 @@ VLIB_CLI_COMMAND (fib_walk_clear_command, static) = { .short_help = "clear fib walk", .function = fib_walk_clear, }; + +void +fib_walk_process_enable (void) +{ + vlib_process_signal_event(vlib_get_main(), + fib_walk_process_node.index, + FIB_WALK_PROCESS_EVENT_ENABLE, + 0); +} + +void +fib_walk_process_disable (void) +{ + vlib_process_signal_event(vlib_get_main(), + fib_walk_process_node.index, + FIB_WALK_PROCESS_EVENT_DISABLE, + 0); +} + +static clib_error_t * +fib_walk_process_enable_disable (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + if (unformat (input, "enable")) + { + fib_walk_process_enable(); + } + else if (unformat (input, "disable")) + { + fib_walk_process_disable(); + } + else + { + return clib_error_return(0, "choose enable or disable"); + } + return (NULL); +} + +VLIB_CLI_COMMAND (fib_walk_process_command, static) = { + .path = "test fib-walk-process", + .short_help = "test fib-walk-process [enable|disable]", + .function = fib_walk_process_enable_disable, +}; |