#include <vnet/fib/fib_walk.h>
#include <vnet/fib/fib_node_list.h>
+vlib_log_class_t fib_walk_logger;
+
/**
* The flags on a walk
*/
/**
* The reasons this walk is occuring.
* This is a vector ordered in time. The reasons and the front were started
- * first, and so should be acted first when a node is visisted.
+ * first, and so should be acted first when a node is visited.
*/
fib_node_back_walk_ctx_t *fw_ctx;
} fib_walk_t;
static const char * const fib_node_bw_reason_names[] = FIB_NODE_BW_REASONS;
/**
- * A represenation of one queue of walk
+ * A representation of one queue of walk
*/
typedef struct fib_walk_queue_t_
{
static const char * const fib_walk_priority_names[] = FIB_WALK_PRIORITIES;
/**
- * @brief Histogram stats on the lenths of each walk in elemenets visisted.
+ * @brief Histogram stats on the lenths of each walk in elemenets visited.
* Store upto 1<<23 elements in increments of 1<<10
*/
#define HISTOGRAM_VISITS_PER_WALK_MAX (1<<23)
} fib_walk_history_t;
static fib_walk_history_t fib_walk_history[HISTORY_N_WALKS];
+static u8* format_fib_walk (u8* s, va_list *ap);
+
+#define FIB_WALK_DBG(_walk, _fmt, _args...) \
+{ \
+ vlib_log_debug(fib_walk_logger, \
+ "[%U]:" _fmt, \
+ format_fib_walk, \
+ fib_walk_get_index(_walk), \
+ ##_args); \
+}
+
u8*
-format_fib_walk_priority (u8 *s, va_list ap)
+format_fib_walk_priority (u8 *s, va_list *ap)
{
- fib_walk_priority_t prio = va_arg(ap, fib_walk_priority_t);
+ fib_walk_priority_t prio = va_arg(*ap, fib_walk_priority_t);
ASSERT(prio < FIB_WALK_PRIORITY_NUM);
return (format(s, "%s", fib_walk_priority_names[prio]));
}
static u8*
-format_fib_walk_queue_stats (u8 *s, va_list ap)
+format_fib_walk_queue_stats (u8 *s, va_list *ap)
{
- fib_walk_queue_stats_t wqs = va_arg(ap, fib_walk_queue_stats_t);
+ fib_walk_queue_stats_t wqs = va_arg(*ap, fib_walk_queue_stats_t);
ASSERT(wqs < FIB_WALK_QUEUE_STATS_NUM);
while (ii < n_ctxs)
{
- wrc = fib_node_back_walk_one(&sibling, &fwalk->fw_ctx[ii]);
+ fib_node_back_walk_ctx_t ctx = fwalk->fw_ctx[ii];
+
+ wrc = fib_node_back_walk_one(&sibling, &ctx);
ii++;
fwalk = fib_walk_get(fwi);
* Histogram on the number of nodes visted in each quota
*/
#define N_ELTS_BUCKETS 128
-static u32 fib_walk_work_nodes_visisted_incr = 2;
+static u32 fib_walk_work_nodes_visited_incr = 2;
static u64 fib_walk_work_nodes_visited[N_ELTS_BUCKETS];
/**
/*
* collect the stats:
- * - for the number of nodes visisted we store 128 increments
+ * - for the number of nodes visited we store 128 increments
* - for the time consumed we store quota/TIME_INCREMENTS increments.
*/
- bucket = ((n_elts/fib_walk_work_nodes_visisted_incr) > N_ELTS_BUCKETS ?
+ bucket = ((n_elts/fib_walk_work_nodes_visited_incr) > N_ELTS_BUCKETS ?
N_ELTS_BUCKETS-1 :
- n_elts/fib_walk_work_nodes_visisted_incr);
+ n_elts/fib_walk_work_nodes_visited_incr);
++fib_walk_work_nodes_visited[bucket];
bucket = (consumed_time - quota) / (quota / TIME_INCREMENTS);
fib_walk_get_index(fwalk));
fwalk->fw_prio_sibling = fib_walk_prio_queue_enquue(prio, fwalk);
+
+ FIB_WALK_DBG(fwalk, "async-start: %U",
+ format_fib_node_bw_reason, ctx->fnbw_reason);
}
/**
* @brief Back walk all the children of a FIB node.
*
* note this is a synchronous depth first walk. Children visited may propagate
- * the walk to thier children. Other children node types may not propagate,
+ * the walk to their children. Other children node types may not propagate,
* synchronously but instead queue the walk for later async completion.
*/
void
FIB_NODE_TYPE_WALK,
fib_walk_get_index(fwalk));
fwi = fib_walk_get_index(fwalk);
+ FIB_WALK_DBG(fwalk, "sync-start: %U",
+ format_fib_node_bw_reason, ctx->fnbw_reason);
while (1)
{
* continue with it now, but let the stack unwind and along the
* appropriate frame to read the depth count and bail.
*/
+ FIB_WALK_DBG(fwalk, "sync-stop: %U",
+ format_fib_node_bw_reason,
+ ctx->fnbw_reason);
+
fwalk = NULL;
break;
}
if (NULL != fwalk)
{
+ FIB_WALK_DBG(fwalk, "sync-stop: %U",
+ format_fib_node_bw_reason,
+ ctx->fnbw_reason);
fib_walk_destroy(fwi);
}
}
}
fib_node_register_type(FIB_NODE_TYPE_WALK, &fib_walk_vft);
+ fib_walk_logger = vlib_log_register_class("fib", "walk");
}
static u8*
-format_fib_walk (u8* s, va_list ap)
+format_fib_walk (u8* s, va_list *ap)
{
- fib_node_index_t fwi = va_arg(ap, fib_node_index_t);
+ fib_node_index_t fwi = va_arg(*ap, fib_node_index_t);
fib_walk_t *fwalk;
fwalk = fib_walk_get(fwi);
- return (format(s, " parent:{%s:%d} visits:%d flags:%d",
+ return (format(s, "[@%d] parent:{%s:%d} visits:%d flags:%d", fwi,
fib_node_type_get_name(fwalk->fw_parent.fnp_type),
fwalk->fw_parent.fnp_index,
fwalk->fw_n_visits,
fwalk->fw_flags));
}
+u8 *
+format_fib_node_bw_reason (u8 *s, va_list *args)
+{
+ fib_node_bw_reason_flag_t flag = va_arg (*args, int);
+ fib_node_back_walk_reason_t reason;
+
+ FOR_EACH_FIB_NODE_BW_REASON(reason) {
+ if ((1<<reason) & flag)
+ s = format(s, "%s", fib_node_bw_reason_names[reason]);
+ }
+
+ return (s);
+}
+
static clib_error_t *
fib_walk_show (vlib_main_t * vm,
unformat_input_t * input,
{
if (0 != fib_walk_work_nodes_visited[ii])
s = format(s, "%d:%d ",
- (ii * fib_walk_work_nodes_visisted_incr),
+ (ii * fib_walk_work_nodes_visited_incr),
fib_walk_work_nodes_visited[ii]);
}
vlib_cli_output(vm, " %v", s);
{
if (0 != fib_walk_history[ii].fwh_reason[0])
{
- fib_node_back_walk_reason_t reason;
u8 *s = NULL;
u32 jj;
jj = 0;
while (0 != fib_walk_history[ii].fwh_reason[jj])
{
- FOR_EACH_FIB_NODE_BW_REASON(reason) {
- if ((1<<reason) & fib_walk_history[ii].fwh_reason[jj]) {
- s = format (s, "%s,", fib_node_bw_reason_names[reason]);
- }
- }
+ s = format (s, "%U,", format_fib_node_bw_reason,
+ fib_walk_history[ii].fwh_reason[jj]);
jj++;
}
vlib_cli_output(vm, "%v", s);
if (unformat (input, "%d", &new))
{
- fib_walk_work_nodes_visisted_incr = new;
+ fib_walk_work_nodes_visited_incr = new;
}
else
{
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
- memset(fib_walk_hist_vists_per_walk, 0, sizeof(fib_walk_hist_vists_per_walk));
- memset(fib_walk_history, 0, sizeof(fib_walk_history));
- memset(fib_walk_work_time_taken, 0, sizeof(fib_walk_work_time_taken));
- memset(fib_walk_work_nodes_visited, 0, sizeof(fib_walk_work_nodes_visited));
- memset(fib_walk_sleep_lengths, 0, sizeof(fib_walk_sleep_lengths));
+ clib_memset(fib_walk_hist_vists_per_walk, 0, sizeof(fib_walk_hist_vists_per_walk));
+ clib_memset(fib_walk_history, 0, sizeof(fib_walk_history));
+ clib_memset(fib_walk_work_time_taken, 0, sizeof(fib_walk_work_time_taken));
+ clib_memset(fib_walk_work_nodes_visited, 0, sizeof(fib_walk_work_nodes_visited));
+ clib_memset(fib_walk_sleep_lengths, 0, sizeof(fib_walk_sleep_lengths));
return (NULL);
}