X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_walk.c;h=64c2527b7b6556d38b75dd40024463c05ebc2bfd;hb=b4d3053;hp=c570476d130fb6735d24213fa78cafa3c4aa1f86;hpb=f12a83f54ff2239d70494d577af3e1bb253692e1;p=vpp.git diff --git a/src/vnet/fib/fib_walk.c b/src/vnet/fib/fib_walk.c index c570476d130..64c2527b7b6 100644 --- a/src/vnet/fib/fib_walk.c +++ b/src/vnet/fib/fib_walk.c @@ -16,6 +16,8 @@ #include #include +vlib_log_class_t fib_walk_logger; + /** * The flags on a walk */ @@ -184,19 +186,30 @@ typedef struct fib_walk_history_t_ { } 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); @@ -322,10 +335,10 @@ typedef enum fib_walk_advance_rc_t_ static fib_walk_advance_rc_t fib_walk_advance (fib_node_index_t fwi) { - fib_node_back_walk_ctx_t *ctx, *old; fib_node_back_walk_rc_t wrc; fib_node_ptr_t sibling; fib_walk_t *fwalk; + uint n_ctxs, ii; int more_elts; /* @@ -339,12 +352,20 @@ fib_walk_advance (fib_node_index_t fwi) if (more_elts) { - old = fwalk->fw_ctx; - vec_foreach(ctx, fwalk->fw_ctx) - { - wrc = fib_node_back_walk_one(&sibling, ctx); + /* + * loop through the backwalk contexts. This can grow in length + * as walks on the same object meet each other. Order is preserved so the + * most recently started walk as at the back of the vector. + */ + ii = 0; + n_ctxs = vec_len(fwalk->fw_ctx); + while (ii < n_ctxs) + { + wrc = fib_node_back_walk_one(&sibling, &fwalk->fw_ctx[ii]); + + ii++; fwalk = fib_walk_get(fwi); fwalk->fw_n_visits++; @@ -356,14 +377,11 @@ fib_walk_advance (fib_node_index_t fwi) */ return (FIB_WALK_ADVANCE_MERGE); } - if (old != fwalk->fw_ctx) - { - /* - * nasty re-entrant addition of a walk has realloc'd the vector - * break out - */ - return (FIB_WALK_ADVANCE_MERGE); - } + + /* + * re-evaluate the number of backwalk contexts we need to process. + */ + n_ctxs = vec_len(fwalk->fw_ctx); } /* * move foward to the next node to visit @@ -394,7 +412,17 @@ typedef enum fib_walk_sleep_type_t_ * @brief Durations for the sleep types */ static f64 fib_walk_sleep_duration[] = { - [FIB_WALK_LONG_SLEEP] = 1e-3, + /** + * Long sleep when there is no more work, i.e. the queues are empty. + * This is a sleep (as opposed to a wait for event) just to be sure we + * are not missing events by sleeping forever. + */ + [FIB_WALK_LONG_SLEEP] = 2, + + /** + * Short sleep. There is work left in the queues. We are yielding the CPU + * momentarily. + */ [FIB_WALK_SHORT_SLEEP] = 1e-8, }; @@ -699,6 +727,9 @@ fib_walk_async (fib_node_type_t parent_type, 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); } /** @@ -744,6 +775,8 @@ fib_walk_sync (fib_node_type_t parent_type, 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) { @@ -797,6 +830,10 @@ fib_walk_sync (fib_node_type_t parent_type, * 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; } @@ -812,6 +849,9 @@ fib_walk_sync (fib_node_type_t parent_type, if (NULL != fwalk) { + FIB_WALK_DBG(fwalk, "sync-stop: %U", + format_fib_node_bw_reason, + ctx->fnbw_reason); fib_walk_destroy(fwi); } } @@ -909,23 +949,38 @@ fib_walk_module_init (void) } 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<