X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_walk.c;h=d0942401153ffb6cf093b0f55d1d0ede8af231ac;hb=6bd197ebb9fd9ae271449ad3937ae076d85c6479;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..d0942401153 100644 --- a/src/vnet/fib/fib_walk.c +++ b/src/vnet/fib/fib_walk.c @@ -185,18 +185,18 @@ typedef struct fib_walk_history_t_ { static fib_walk_history_t fib_walk_history[HISTORY_N_WALKS]; 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 +322,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 +339,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 +364,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 +399,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, }; @@ -912,9 +927,9 @@ fib_walk_module_init (void) } 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);