Add support for input nodes in interrupt mode on the worker threads
[vpp.git] / vlib / vlib / buffer.h
index 6322481..e475546 100644 (file)
 #include <vppinfra/serialize.h>
 #include <vppinfra/vector.h>
 #include <vlib/error.h>                /* for vlib_error_t */
-#include <vlib/config.h>        /* for __PRE_DATA_SIZE */
+
+#if DPDK > 0
+#include <rte_config.h>
+#define VLIB_BUFFER_DATA_SIZE          (2048)
+#define VLIB_BUFFER_PRE_DATA_SIZE      RTE_PKTMBUF_HEADROOM
+#else
+#include <vlib/config.h>       /* for __PRE_DATA_SIZE */
+#define VLIB_BUFFER_DATA_SIZE          (512)
+#define VLIB_BUFFER_PRE_DATA_SIZE      __PRE_DATA_SIZE
+#endif
 
 #ifdef CLIB_HAVE_VEC128
 typedef u8x16 vlib_copy_unit_t;
 #else
-typedef uword vlib_copy_unit_t;
+typedef u64 vlib_copy_unit_t;
 #endif
 
 /** \file
     vlib buffer structure definition and a few select
     access methods. This structure and the buffer allocation
-    mechanism should perhaps live in vnet, but it would take a lot 
+    mechanism should perhaps live in vnet, but it would take a lot
     of typing to make it so.
 */
-    
+
 /* VLIB buffer representation. */
-typedef struct {
+typedef struct
+{
+  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
   /* Offset within data[] that we are currently processing.
-     If negative current header points into predata area. */ 
-  i16 current_data;  /**< signed offset in data[], pre_data[]  
+     If negative current header points into predata area. */
+  i16 current_data;  /**< signed offset in data[], pre_data[]
                         that we are currently processing.
                         If negative current header points into predata area.
                      */
-  u16 current_length;  /**< Nbytes between current data and 
+  u16 current_length;  /**< Nbytes between current data and
                           the end of this buffer.
                        */
-  u32 flags; /**< buffer flags: 
+  u32 flags; /**< buffer flags:
                 <br> VLIB_BUFFER_IS_TRACED: trace this buffer.
                 <br> VLIB_BUFFER_NEXT_PRESENT: this is a multi-chunk buffer.
                 <br> VLIB_BUFFER_TOTAL_LENGTH_VALID: as it says
                 <br> VLIB_BUFFER_REPL_FAIL: packet replication failure
+                <br> VLIB_BUFFER_RECYCLE: as it says
                 <br> VLIB_BUFFER_FLAG_USER(n): user-defined bit N
              */
 #define VLIB_BUFFER_IS_TRACED (1 << 0)
 #define VLIB_BUFFER_LOG2_NEXT_PRESENT (1)
-#define VLIB_BUFFER_NEXT_PRESENT (1 << VLIB_BUFFER_LOG2_NEXT_PRESENT) 
-#define VLIB_BUFFER_IS_RECYCLED (1 << 2) 
+#define VLIB_BUFFER_NEXT_PRESENT (1 << VLIB_BUFFER_LOG2_NEXT_PRESENT)
+#define VLIB_BUFFER_IS_RECYCLED (1 << 2)
 #define VLIB_BUFFER_TOTAL_LENGTH_VALID (1 << 3)
-#define VLIB_BUFFER_HGSHM_USER_INDEX_VALID (1 << 4) 
-#define VLIB_BUFFER_REPL_FAIL (1 << 5) 
+#define VLIB_BUFFER_REPL_FAIL (1 << 4)
+#define VLIB_BUFFER_RECYCLE (1 << 5)
 
   /* User defined buffer flags. */
 #define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
 #define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n))
 
-  u32 free_list_index; /**< Buffer free list that this buffer was 
-                          allocated from and will be freed to. 
+  u32 free_list_index; /**< Buffer free list that this buffer was
+                          allocated from and will be freed to.
                        */
 
-  u32 total_length_not_including_first_buffer; 
+  u32 total_length_not_including_first_buffer;
   /**< Only valid for first buffer in chain. Current length plus
      total length given here give total number of bytes in buffer chain.
   */
 
-
   u32 next_buffer;   /**< Next buffer for this linked-list of buffers.
-                        Only valid if VLIB_BUFFER_NEXT_PRESENT flag is set. 
+                        Only valid if VLIB_BUFFER_NEXT_PRESENT flag is set.
                      */
 
-  u32 trace_index; /**< Specifies index into trace buffer 
-                      if VLIB_PACKET_IS_TRACED flag is set. 
-                   */
-
-
-  u32 clone_count; /**< Specifies whether this buffer should be 
-                      reinitialized when freed. It will be reinitialized 
-                      if the value is 0. This field can be used
-                      as a counter or for other state during packet 
-                      replication. The buffer free function does not 
-                      modify this value. 
-                   */
-
-  vlib_error_t error;   /**< Error code for buffers to be enqueued 
-                           to error handler. 
+  vlib_error_t error;  /**< Error code for buffers to be enqueued
+                           to error handler.
                         */
+  u32 current_config_index; /**< Used by feature subgraph arcs to
+                               visit enabled feature nodes
+                            */
+
+  u32 dont_waste_me; /**< Available space in the (precious)
+                        first 32 octets of buffer metadata
+                        Before allocating any of it, discussion required!
+                     */
 
-  u32 opaque[8]; /**< Opaque data used by sub-graphs for their own purposes. 
+  u32 opaque[8]; /**< Opaque data used by sub-graphs for their own purposes.
                     See .../vnet/vnet/buffer.h
                  */
-  /***** end of first cache line */
+    CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
 
-  u32 opaque2[16];  /**< More opaque data, in its own cache line */
+  u32 trace_index; /**< Specifies index into trace buffer
+                      if VLIB_PACKET_IS_TRACED flag is set.
+                   */
+  u32 recycle_count; /**< Used by L2 path recycle code */
+  u32 opaque2[14];  /**< More opaque data, currently unused */
 
   /***** end of second cache line */
-  u8 pre_data [__PRE_DATA_SIZE]; /**< Space for inserting data 
-                                     before buffer start.  
-                                     Packet rewrite string will be
-                                     rewritten backwards and may extend 
-                                     back before buffer->data[0].
-                                     Must come directly before packet data.
-                                 */
-
-#define VLIB_BUFFER_PRE_DATA_SIZE (ARRAY_LEN (((vlib_buffer_t *)0)->pre_data))
+    CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
+  u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE];  /**< Space for inserting data
+                                               before buffer start.
+                                               Packet rewrite string will be
+                                               rewritten backwards and may extend
+                                               back before buffer->data[0].
+                                               Must come directly before packet data.
+                                            */
+
   u8 data[0]; /**< Packet data. Hardware DMA here */
-} vlib_buffer_t;  /* Must be a multiple of 64B. */
+} vlib_buffer_t;               /* Must be a multiple of 64B. */
+
+#define VLIB_BUFFER_HDR_SIZE  (sizeof(vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE)
 
 /** \brief Prefetch buffer metadata.
     The first 64 bytes of buffer contains most header information
@@ -152,7 +164,9 @@ typedef struct {
 
 always_inline vlib_buffer_t *
 vlib_buffer_next_contiguous (vlib_buffer_t * b, u32 buffer_bytes)
-{ return (void *) (b + 1) + buffer_bytes; }
+{
+  return (void *) (b + 1) + buffer_bytes;
+}
 
 always_inline void
 vlib_buffer_struct_is_sane (vlib_buffer_t * b)
@@ -167,7 +181,7 @@ vlib_buffer_struct_is_sane (vlib_buffer_t * b)
 
     @param b - (vlib_buffer_t *) pointer to the buffer
     @return - (void *) (b->data + b->current_data)
-*/    
+*/
 
 always_inline void *
 vlib_buffer_get_current (vlib_buffer_t * b)
@@ -181,7 +195,7 @@ vlib_buffer_get_current (vlib_buffer_t * b)
 
     @param b - (vlib_buffer_t *) pointer to the buffer
     @param l - (word) signed increment
-*/    
+*/
 always_inline void
 vlib_buffer_advance (vlib_buffer_t * b, word l)
 {
@@ -210,7 +224,9 @@ vlib_buffer_reset (vlib_buffer_t * b)
 */
 always_inline void *
 vlib_get_buffer_opaque (vlib_buffer_t * b)
-{ return (void *) b->opaque; }
+{
+  return (void *) b->opaque;
+}
 
 /** \brief Get pointer to buffer's opaque2 data array
 
@@ -219,12 +235,15 @@ vlib_get_buffer_opaque (vlib_buffer_t * b)
 */
 always_inline void *
 vlib_get_buffer_opaque2 (vlib_buffer_t * b)
-{ return (void *) b->opaque2; }
+{
+  return (void *) b->opaque2;
+}
 
 /* Forward declaration. */
 struct vlib_main_t;
 
-typedef struct vlib_buffer_free_list_t {
+typedef struct vlib_buffer_free_list_t
+{
   /* Template buffer used to initialize first 16 bytes of buffers
      allocated on this free list. */
   vlib_buffer_t buffer_init_template;
@@ -246,82 +265,78 @@ typedef struct vlib_buffer_free_list_t {
      Aligned vectors always has naturally aligned vlib_copy_unit_t sized chunks
      of buffer indices.  Unaligned vector has any left over.  This is meant to
      speed up copy routines. */
-  u32 * aligned_buffers, * unaligned_buffers;
+  u32 *aligned_buffers, *unaligned_buffers;
 
   /* Memory chunks allocated for this free list
      recorded here so they can be freed when free list
      is deleted. */
-  void ** buffer_memory_allocated;
+  void **buffer_memory_allocated;
 
   /* Free list name. */
-  u8 * name;
+  u8 *name;
 
   /* Callback functions to initialize newly allocated buffers.
      If null buffers are zeroed. */
-  void (* buffer_init_function) (struct vlib_main_t * vm,
-                                struct vlib_buffer_free_list_t * fl,
-                                u32 * buffers, u32 n_buffers);
+  void (*buffer_init_function) (struct vlib_main_t * vm,
+                               struct vlib_buffer_free_list_t * fl,
+                               u32 * buffers, u32 n_buffers);
 
   /* Callback function to announce that buffers have been
      added to the freelist */
-  void (* buffers_added_to_freelist_function) 
-  (struct vlib_main_t * vm,
-   struct vlib_buffer_free_list_t * fl);
+  void (*buffers_added_to_freelist_function)
+    (struct vlib_main_t * vm, struct vlib_buffer_free_list_t * fl);
 
   uword buffer_init_function_opaque;
 } __attribute__ ((aligned (16))) vlib_buffer_free_list_t;
 
-typedef struct {
+typedef struct
+{
   /* Buffer free callback, for subversive activities */
-  u32 (*buffer_free_callback) (struct vlib_main_t *vm, 
-                               u32 * buffers,
-                               u32 n_buffers,
-                               u32 follow_buffer_next);
+  u32 (*buffer_free_callback) (struct vlib_main_t * vm,
+                              u32 * buffers,
+                              u32 n_buffers, u32 follow_buffer_next);
   /* Pool of buffer free lists.
      Multiple free lists exist for packet generator which uses
      separate free lists for each packet stream --- so as to avoid
      initializing static data for each packet generated. */
-  vlib_buffer_free_list_t * buffer_free_list_pool;
+  vlib_buffer_free_list_t *buffer_free_list_pool;
 #define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX (0)
-
-#if DPDK == 1
-/* must be same as dpdk buffer size */
-#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES (2048)
-#else
-#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES (512)
-#endif
+#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES VLIB_BUFFER_DATA_SIZE
 
   /* Hash table mapping buffer size (rounded to next unit of
      sizeof (vlib_buffer_t)) to free list index. */
-  uword * free_list_by_size;
+  uword *free_list_by_size;
 
   /* Hash table mapping buffer index into number
      0 => allocated but free, 1 => allocated and not-free.
      If buffer index is not in hash table then this buffer
      has never been allocated. */
-  uword * buffer_known_hash;
+  uword *buffer_known_hash;
 
   /* List of free-lists needing Blue Light Special announcements */
   vlib_buffer_free_list_t **announce_list;
 
   /*  Vector of rte_mempools per socket */
 #if DPDK == 1
-  struct rte_mempool ** pktmbuf_pools;
+  struct rte_mempool **pktmbuf_pools;
 #endif
 } vlib_buffer_main_t;
 
-typedef struct {
-  struct vlib_main_t * vlib_main;
+typedef struct
+{
+  struct vlib_main_t *vlib_main;
 
   u32 first_buffer, last_buffer;
 
-  union {
-    struct {
+  union
+  {
+    struct
+    {
       /* Total accumulated bytes in chain starting with first_buffer. */
       u32 n_total_data_bytes;
 
       /* Max number of bytes to accumulate in chain starting with first_buffer.
-        As this limit is reached buffers are enqueued to next node. */
+         As this limit is reached buffers are enqueued to next node. */
       u32 max_n_data_bytes_per_chain;
 
       /* Next node to enqueue buffers to relative to current process node. */
@@ -331,9 +346,10 @@ typedef struct {
       u32 free_list_index;
     } tx;
 
-    struct {
+    struct
+    {
       /* CLIB fifo of buffer indices waiting to be unserialized. */
-      u32 * buffer_fifo;
+      u32 *buffer_fifo;
 
       /* Event type used to signal that RX buffers have been added to fifo. */
       uword ready_one_time_event;
@@ -341,8 +357,11 @@ typedef struct {
   };
 } vlib_serialize_buffer_main_t;
 
-void serialize_open_vlib_buffer (serialize_main_t * m, struct vlib_main_t * vm, vlib_serialize_buffer_main_t * sm);
-void unserialize_open_vlib_buffer (serialize_main_t * m, struct vlib_main_t * vm, vlib_serialize_buffer_main_t * sm);
+void serialize_open_vlib_buffer (serialize_main_t * m, struct vlib_main_t *vm,
+                                vlib_serialize_buffer_main_t * sm);
+void unserialize_open_vlib_buffer (serialize_main_t * m,
+                                  struct vlib_main_t *vm,
+                                  vlib_serialize_buffer_main_t * sm);
 
 u32 serialize_close_vlib_buffer (serialize_main_t * m);
 void unserialize_close_vlib_buffer (serialize_main_t * m);
@@ -351,26 +370,41 @@ void *vlib_set_buffer_free_callback (struct vlib_main_t *vm, void *fp);
 always_inline u32
 serialize_vlib_buffer_n_bytes (serialize_main_t * m)
 {
-  serialize_stream_t * s = &m->stream;
-  vlib_serialize_buffer_main_t * sm
-    = uword_to_pointer (m->stream.data_function_opaque, vlib_serialize_buffer_main_t *);
-  return sm->tx.n_total_data_bytes + s->current_buffer_index + vec_len (s->overflow_buffer);
+  serialize_stream_t *s = &m->stream;
+  vlib_serialize_buffer_main_t *sm
+    = uword_to_pointer (m->stream.data_function_opaque,
+                       vlib_serialize_buffer_main_t *);
+  return sm->tx.n_total_data_bytes + s->current_buffer_index +
+    vec_len (s->overflow_buffer);
 }
 
+#if DPDK > 0
+#define rte_mbuf_from_vlib_buffer(x) (((struct rte_mbuf *)x) - 1)
+#define vlib_buffer_from_rte_mbuf(x) ((vlib_buffer_t *)(x+1))
+#endif
+
 /*
  */
 
 /** \brief Compile time buffer trajectory tracing option
-    Turn this on if you run into "bad monkey" contexts, 
-    and you want to know exactly which nodes they've visited... 
+    Turn this on if you run into "bad monkey" contexts,
+    and you want to know exactly which nodes they've visited...
     See vlib/main.c...
 */
 #define VLIB_BUFFER_TRACE_TRAJECTORY 0
 
 #if VLIB_BUFFER_TRACE_TRAJECTORY > 0
 #define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->pre_data[0]=0
-#else 
+#else
 #define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
 #endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
 
 #endif /* included_vlib_buffer_h */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */