vlib: fix counter_will_expand prediction 21/30721/2
authorMiklos Tirpak <miklos.tirpak@gmail.com>
Wed, 13 Jan 2021 09:00:38 +0000 (10:00 +0100)
committerOle Tr�an <otroan@employees.org>
Fri, 15 Jan 2021 09:46:23 +0000 (09:46 +0000)
vlib_validate_combined_counter_will_expand() was calling
_vec_resize_will_expand() with wrong arguments, which resulted in false
return value. Apart from the initial call, it never indicated a vector
resize.

The callers relying on this function did not perform a barrier sync
because of the wrong prediction even if the vector got extended by
a subsequent vlib_validate_combined_counter() call.

The fix introduces a new, simplified macro that is easier to call.
vec_resize_will_expand() accepts the same arguments as vec_resize().

Type: fix
Signed-off-by: Miklos Tirpak <miklos.tirpak@gmail.com>
Change-Id: Ib2c2c8afd3e665e0e3d6ae62ff5cfa287acf670f

src/vlib/counter.c
src/vppinfra/vec.h

index adf667f..81c81ae 100644 (file)
@@ -140,12 +140,9 @@ int
       /* Trivially OK, and proves that index >= vec_len(...) */
       if (index < vec_len (cm->counters[i]))
        continue;
-      if (_vec_resize_will_expand
-         (cm->counters[i],
-          index - vec_len (cm->counters[i]) /* length_increment */ ,
-          sizeof (cm->counters[i]) /* data_bytes */ ,
-          0 /* header_bytes */ ,
-          CLIB_CACHE_LINE_BYTES /* data_alignment */ ))
+      if (vec_resize_will_expand (cm->counters[i],
+                                 index - vec_len (cm->counters[i]) +
+                                   1 /* length_increment */))
        {
          vlib_stats_pop_heap (cm, oldheap, index,
                               3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ );
index 1fcb5f1..e8146af 100644 (file)
@@ -209,6 +209,21 @@ _vec_resize_will_expand (void *v,
   return 1;
 }
 
+/** \brief Determine if vector will resize with next allocation
+
+    @param V pointer to a vector
+    @param N number of elements to add
+    @return 1 if vector will resize 0 otherwise
+*/
+
+#define vec_resize_will_expand(V, N)                                          \
+  ({                                                                          \
+    word _v (n) = (N);                                                        \
+    word _v (l) = vec_len (V);                                                \
+    _vec_resize_will_expand ((V), _v (n),                                     \
+                            (_v (l) + _v (n)) * sizeof ((V)[0]), 0, 0);      \
+  })
+
 /** \brief Predicate function, says whether the supplied vector is a clib heap
     object (general version).