#define VLIB_BUFFER_DATA_SIZE (2048)
#define VLIB_BUFFER_PRE_DATA_SIZE __PRE_DATA_SIZE
+/* Minimum buffer chain segment size. Does not apply to last buffer in chain.
+ Dataplane code can safely asume that specified amount of data is not split
+ into 2 chained buffers */
+#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
+
+/* Amount of head buffer data copied to each replica head buffer */
+#define VLIB_BUFFER_CLONE_HEAD_SIZE (256)
+
typedef u8 vlib_buffer_free_list_index_t;
/** \file
_( 0, NON_DEFAULT_FREELIST, "non-default-fl") \
_( 1, IS_TRACED, 0) \
_( 2, NEXT_PRESENT, 0) \
- _( 3, IS_RECYCLED, "is-recycled") \
- _( 4, TOTAL_LENGTH_VALID, 0) \
- _( 5, REPL_FAIL, "repl-fail") \
- _( 6, RECYCLE, "recycle") \
- _( 7, EXT_HDR_VALID, "ext-hdr-valid")
+ _( 3, TOTAL_LENGTH_VALID, 0) \
+ _( 4, EXT_HDR_VALID, "ext-hdr-valid")
/* NOTE: only buffer generic flags should be defined here, please consider
using user flags. i.e. src/vnet/buffer.h */
/* 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))
+#define VLIB_BUFFER_FLAGS_ALL (0x1f)
/* VLIB buffer representation. */
typedef struct
<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_EXT_HDR_VALID: buffer contains valid external buffer manager header,
set to avoid adding it to a flow report
<br> VLIB_BUFFER_FLAG_USER(n): user-defined bit N
*/
#define vlib_prefetch_buffer_header(b,type) CLIB_PREFETCH (b, 64, type)
+#define vlib_prefetch_buffer_data(b,type) \
+ CLIB_PREFETCH (vlib_buffer_get_current(b), CLIB_CACHE_LINE_BYTES, type)
always_inline void
vlib_buffer_struct_is_sane (vlib_buffer_t * b)
ASSERT (b->pre_data + VLIB_BUFFER_PRE_DATA_SIZE == b->data);
}
+always_inline uword
+vlib_buffer_get_va (vlib_buffer_t * b)
+{
+ return pointer_to_uword (b->data);
+}
+
/** \brief Get pointer to current data to process
@param b - (vlib_buffer_t *) pointer to the buffer
return b->data + b->current_data;
}
+always_inline uword
+vlib_buffer_get_current_va (vlib_buffer_t * b)
+{
+ return vlib_buffer_get_va (b) + b->current_data;
+}
+
/** \brief Advance current data pointer by the supplied (signed!) amount
@param b - (vlib_buffer_t *) pointer to the buffer
ASSERT (b->current_length >= l);
b->current_data += l;
b->current_length -= l;
+
+ ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0 ||
+ b->current_length >= VLIB_BUFFER_MIN_CHAIN_SEG_SIZE);
}
/** \brief Check if there is enough space in buffer to advance
* @return pointer to beginning of uninitialized data
*/
always_inline void *
-vlib_buffer_put_uninit (vlib_buffer_t * b, u8 size)
+vlib_buffer_put_uninit (vlib_buffer_t * b, u16 size)
{
void *p = vlib_buffer_get_tail (b);
/* XXX make sure there's enough space */
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);
-
uword buffer_init_function_opaque;
} __attribute__ ((aligned (16))) vlib_buffer_free_list_t;
vlib_buffer_fill_free_list_cb_t *vlib_buffer_fill_free_list_cb;
vlib_buffer_free_cb_t *vlib_buffer_free_cb;
vlib_buffer_free_no_next_cb_t *vlib_buffer_free_no_next_cb;
- void (*vlib_packet_template_init_cb) (struct vlib_main_t * vm, void *t,
- void *packet_data,
- uword n_packet_data_bytes,
- uword
- min_n_buffers_each_physmem_alloc,
- u8 * name);
void (*vlib_buffer_delete_free_list_cb) (struct vlib_main_t * vm,
vlib_buffer_free_list_index_t
free_list_index);
uword start;
uword size;
uword log2_page_size;
- vlib_physmem_region_index_t physmem_region;
-
+ u32 physmem_map_index;
+ u32 buffer_size;
u32 *buffers;
-
- u16 buffer_size;
- uword buffers_per_page;
- uword n_elts;
- uword n_used;
- uword next_clear;
- uword *bitmap;
clib_spinlock_t lock;
} vlib_buffer_pool_t;
return vec_elt_at_index (bm->buffer_pools, buffer_pool_index);
}
-u8 vlib_buffer_pool_create (struct vlib_main_t * vm,
- vlib_physmem_region_index_t region,
- u16 buffer_size);
+u8 vlib_buffer_register_physmem_map (struct vlib_main_t * vm,
+ u32 physmem_map_index);
clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm);
-typedef struct
-{
- struct vlib_main_t *vlib_main;
-
- u32 first_buffer, last_buffer;
-
- 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. */
- u32 max_n_data_bytes_per_chain;
-
- /* Next node to enqueue buffers to relative to current process node. */
- u32 next_index;
-
- /* Free list to use to allocate new buffers. */
- vlib_buffer_free_list_index_t free_list_index;
- } tx;
-
- struct
- {
- /* CLIB fifo of buffer indices waiting to be unserialized. */
- u32 *buffer_fifo;
-
- /* Event type used to signal that RX buffers have been added to fifo. */
- uword ready_one_time_event;
- } rx;
- };
-} 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);
-
-u32 serialize_close_vlib_buffer (serialize_main_t * m);
-void unserialize_close_vlib_buffer (serialize_main_t * m);
-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);
-}
+void *vlib_set_buffer_free_callback (struct vlib_main_t *vm, void *fp);
/*
*/