summaryrefslogtreecommitdiffstats
path: root/src/vnet/fib/fib_walk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/fib/fib_walk.c')
-rw-r--r--src/vnet/fib/fib_walk.c122
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,
+};