Introduce l{2,3,4}_hdr_offset fields in the buffer metadata

To save space in the first cacheline following is changed:

- total_length_not_including_first_buffer moved to the 2nd cacheline.
This field is used only when VLIB_BUFFER_TOTAL_LENGTH_VALID and
VLIB_BUFFER_NEXT_PRESENT are both set.

- free_list_index is now stored in 4bits inside flags, which
allows up to 16 free lists. In case we need more we can store index
in the 2nd cachelin

Change-Id: Ic8521350819391af470d31d3fa1013e67ecb7681
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h
index 97442e1..1aaac0b 100644
--- a/src/vlib/buffer_funcs.h
+++ b/src/vlib/buffer_funcs.h
@@ -106,12 +106,15 @@
 always_inline uword
 vlib_buffer_length_in_chain (vlib_main_t * vm, vlib_buffer_t * b)
 {
-  uword l = b->current_length + b->total_length_not_including_first_buffer;
-  if (PREDICT_FALSE ((b->flags & (VLIB_BUFFER_NEXT_PRESENT
-				  | VLIB_BUFFER_TOTAL_LENGTH_VALID))
-		     == VLIB_BUFFER_NEXT_PRESENT))
-    return vlib_buffer_length_in_chain_slow_path (vm, b);
-  return l;
+  uword len = b->current_length;
+
+  if (PREDICT_TRUE ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0))
+    return len;
+
+  if (PREDICT_TRUE (b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID))
+    return len + b->total_length_not_including_first_buffer;
+
+  return vlib_buffer_length_in_chain_slow_path (vm, b);
 }
 
 /** \brief Get length in bytes of the buffer index buffer chain
@@ -261,6 +264,24 @@
   return round_pow2 (size, sizeof (vlib_buffer_t));
 }
 
+always_inline u32
+vlib_buffer_get_free_list_index (vlib_buffer_t * b)
+{
+  return b->flags & VLIB_BUFFER_FREE_LIST_INDEX_MASK;
+}
+
+always_inline void
+vlib_buffer_set_free_list_index (vlib_buffer_t * b, u32 index)
+{
+  /* if there is an need for more free lists we should consider
+     storig data in the 2nd cacheline */
+  ASSERT (VLIB_BUFFER_FREE_LIST_INDEX_MASK & 1);
+  ASSERT (index <= VLIB_BUFFER_FREE_LIST_INDEX_MASK);
+
+  b->flags &= ~VLIB_BUFFER_FREE_LIST_INDEX_MASK;
+  b->flags |= index & VLIB_BUFFER_FREE_LIST_INDEX_MASK;
+}
+
 /** \brief Allocate buffers from specific freelist into supplied array
 
     @param vm - (vlib_main_t *) vlib main data structure pointer
@@ -381,7 +402,7 @@
   vlib_buffer_main_t *bm = vm->buffer_main;
   u32 i;
 
-  *index = i = b->free_list_index;
+  *index = i = vlib_buffer_get_free_list_index (b);
   return pool_elt_at_index (bm->buffer_free_list_pool, i);
 }
 
@@ -569,7 +590,8 @@
     }
 
   n_buffers = vlib_buffer_alloc_from_free_list (vm, buffers, n_buffers,
-						s->free_list_index);
+						vlib_buffer_get_free_list_index
+						(s));
   if (PREDICT_FALSE (n_buffers == 0))
     {
       buffers[0] = src_buffer;
@@ -581,7 +603,8 @@
       vlib_buffer_t *d = vlib_get_buffer (vm, buffers[i]);
       d->current_data = s->current_data;
       d->current_length = head_end_offset;
-      d->free_list_index = s->free_list_index;
+      vlib_buffer_set_free_list_index (d,
+				       vlib_buffer_get_free_list_index (s));
       d->total_length_not_including_first_buffer =
 	s->total_length_not_including_first_buffer + s->current_length -
 	head_end_offset;
@@ -615,7 +638,8 @@
 			  vlib_buffer_t * tail)
 {
   ASSERT ((head->flags & VLIB_BUFFER_NEXT_PRESENT) == 0);
-  ASSERT (head->free_list_index == tail->free_list_index);
+  ASSERT (vlib_buffer_get_free_list_index (head) ==
+	  vlib_buffer_get_free_list_index (tail));
 
   head->flags |= VLIB_BUFFER_NEXT_PRESENT;
   head->flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;
@@ -791,7 +815,7 @@
 	  CLIB_CACHE_LINE_BYTES * 2);
 
   /* Make sure buffer template is sane. */
-  ASSERT (fl->index == fl->buffer_init_template.free_list_index);
+  ASSERT (fl->index == vlib_buffer_get_free_list_index (src));
 
   clib_memcpy (STRUCT_MARK_PTR (dst, template_start),
 	       STRUCT_MARK_PTR (src, template_start),
@@ -806,7 +830,6 @@
   _(current_data);
   _(current_length);
   _(flags);
-  _(free_list_index);
 #undef _
   ASSERT (dst->total_length_not_including_first_buffer == 0);
   ASSERT (dst->n_add_refs == 0);
@@ -832,7 +855,7 @@
   vlib_buffer_t *src = &fl->buffer_init_template;
 
   /* Make sure buffer template is sane. */
-  ASSERT (fl->index == fl->buffer_init_template.free_list_index);
+  ASSERT (fl->index == vlib_buffer_get_free_list_index (src));
 
   clib_memcpy (STRUCT_MARK_PTR (dst0, template_start),
 	       STRUCT_MARK_PTR (src, template_start),
@@ -853,7 +876,6 @@
   _(current_data);
   _(current_length);
   _(flags);
-  _(free_list_index);
 #undef _
 
   ASSERT (dst0->total_length_not_including_first_buffer == 0);