#define VLIB_BUFFER_DATA_SIZE (2048)
#define VLIB_BUFFER_PRE_DATA_SIZE __PRE_DATA_SIZE
+typedef u8 vlib_buffer_free_list_index_t;
+
/** \file
vlib buffer structure definition and a few select
access methods. This structure and the buffer allocation
of typing to make it so.
*/
+/**
+ * Buffer Flags
+ */
+#define foreach_vlib_buffer_flag \
+ _( 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")
+
+/* NOTE: only buffer generic flags should be defined here, please consider
+ using user flags. i.e. src/vnet/buffer.h */
+
+enum
+{
+#define _(bit, name, v) VLIB_BUFFER_##name = (1 << (bit)),
+ foreach_vlib_buffer_flag
+#undef _
+};
+
+enum
+{
+#define _(bit, name, v) VLIB_BUFFER_LOG2_##name = (bit),
+ foreach_vlib_buffer_flag
+#undef _
+};
+
+ /* 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))
+
/* VLIB buffer representation. */
typedef struct
{
<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_FLOW_REPORT: buffer is a flow report,
<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
*/
-/* any change to the following line requres update of
- * vlib_buffer_get_free_list_index(...) and
- * vlib_buffer_set_free_list_index(...) functions */
-#define VLIB_BUFFER_FREE_LIST_INDEX_MASK ((1 << 5) - 1)
-
-#define VLIB_BUFFER_IS_TRACED (1 << 5)
-#define VLIB_BUFFER_LOG2_NEXT_PRESENT (6)
-#define VLIB_BUFFER_NEXT_PRESENT (1 << VLIB_BUFFER_LOG2_NEXT_PRESENT)
-#define VLIB_BUFFER_IS_RECYCLED (1 << 7)
-#define VLIB_BUFFER_TOTAL_LENGTH_VALID (1 << 8)
-#define VLIB_BUFFER_REPL_FAIL (1 << 9)
-#define VLIB_BUFFER_RECYCLE (1 << 10)
-#define VLIB_BUFFER_FLOW_REPORT (1 << 11)
-#define VLIB_BUFFER_EXT_HDR_VALID (1 << 12)
-
- /* 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))
STRUCT_MARK (template_end);
u8 n_add_refs; /**< Number of additional references to this buffer. */
- u8 dont_waste_me[2]; /**< Available space in the (precious)
+ u8 buffer_pool_index; /**< index of buffer pool this buffer belongs. */
+ u8 dont_waste_me[1]; /**< Available space in the (precious)
first 32 octets of buffer metadata
Before allocating any of it, discussion required!
*/
/**< Only valid for first buffer in chain. Current length plus
total length given here give total number of bytes in buffer chain.
*/
- u32 opaque2[13]; /**< More opaque data, currently unused */
+ vlib_buffer_free_list_index_t free_list_index; /** < only used if
+ VLIB_BUFFER_NON_DEFAULT_FREELIST
+ flag is set */
+ u8 align_pad[3]; /**< available */
+ u32 opaque2[12]; /**< More opaque data, see ../vnet/vnet/buffer.h */
/***** end of second cache line */
CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
vlib_buffer_t buffer_init_template;
/* Our index into vlib_main_t's buffer_free_list_pool. */
- u32 index;
+ vlib_buffer_free_list_index_t index;
/* Number of data bytes for buffers in this free list. */
u32 n_data_bytes;
/* Vector of free buffers. Each element is a byte offset into I/O heap. */
u32 *buffers;
+ /* global vector of free buffers, used only on main thread.
+ Bufers are returned to global buffers only in case when number of
+ buffers on free buffers list grows about threshold */
+ u32 *global_buffers;
+ clib_spinlock_t global_buffers_lock;
+
/* Memory chunks allocated for this free list
recorded here so they can be freed when free list
is deleted. */
uword buffer_init_function_opaque;
} __attribute__ ((aligned (16))) vlib_buffer_free_list_t;
+typedef uword (vlib_buffer_fill_free_list_cb_t) (struct vlib_main_t * vm,
+ vlib_buffer_free_list_t * fl,
+ uword min_free_buffers);
+typedef void (vlib_buffer_free_cb_t) (struct vlib_main_t * vm, u32 * buffers,
+ u32 n_buffers);
+typedef void (vlib_buffer_free_no_next_cb_t) (struct vlib_main_t * vm,
+ u32 * buffers, u32 n_buffers);
+
typedef struct
{
- u32 (*vlib_buffer_alloc_cb) (struct vlib_main_t * vm, u32 * buffers,
- u32 n_buffers);
- u32 (*vlib_buffer_alloc_from_free_list_cb) (struct vlib_main_t * vm,
- u32 * buffers, u32 n_buffers,
- u32 free_list_index);
- void (*vlib_buffer_free_cb) (struct vlib_main_t * vm, u32 * buffers,
- u32 n_buffers);
- void (*vlib_buffer_free_no_next_cb) (struct vlib_main_t * vm, u32 * buffers,
- u32 n_buffers);
+ 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,
min_n_buffers_each_physmem_alloc,
u8 * name);
void (*vlib_buffer_delete_free_list_cb) (struct vlib_main_t * vm,
- u32 free_list_index);
+ vlib_buffer_free_list_index_t
+ free_list_index);
} vlib_buffer_callbacks_t;
extern vlib_buffer_callbacks_t *vlib_buffer_callbacks;
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ uword start;
+ uword size;
+ vlib_physmem_region_index_t physmem_region;
+} vlib_buffer_pool_t;
+
typedef struct
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
buffer index */
uword buffer_mem_start;
uword buffer_mem_size;
+ vlib_buffer_pool_t *buffer_pools;
/* Buffer free callback, for subversive activities */
u32 (*buffer_free_callback) (struct vlib_main_t * vm,
int callbacks_registered;
} vlib_buffer_main_t;
-void vlib_buffer_add_mem_range (struct vlib_main_t *vm, uword start,
- uword size);
-void vlib_buffer_cb_init (struct vlib_main_t *vm);
+u8 vlib_buffer_add_physmem_region (struct vlib_main_t *vm,
+ vlib_physmem_region_index_t region);
+
+clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm);
typedef struct
{
u32 next_index;
/* Free list to use to allocate new buffers. */
- u32 free_list_index;
+ vlib_buffer_free_list_index_t free_list_index;
} tx;
struct
#define VLIB_BUFFER_TRACE_TRAJECTORY 0
#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
-#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->pre_data[0]=0
+extern void (*vlib_buffer_trace_trajectory_cb) (vlib_buffer_t * b, u32 index);
+extern void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b);
+extern void vlib_buffer_trace_trajectory_init (vlib_buffer_t * b);
+#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) \
+ vlib_buffer_trace_trajectory_init (b);
#else
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */