[aarch64] Fixes CLI crashes on dpaa2 platform.
[vpp.git] / src / vnet / fib / fib_walk.c
index c570476..d094240 100644 (file)
@@ -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);