X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvlib%2Fbuffer.h;h=b548adf4be8c5a17fd11c943486ebc8c9b7f6c5b;hb=e09a2337b82d2dcb5b7379a9581477af291d1a75;hp=514e73bd7ca23bd9870566cf87dc9441c6020b50;hpb=b592d1b64140e248f91dc76ce17da65ea90a4798;p=vpp.git diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h index 514e73bd7ca..b548adf4be8 100644 --- a/src/vlib/buffer.h +++ b/src/vlib/buffer.h @@ -72,7 +72,7 @@ */ #define foreach_vlib_buffer_flag \ _( 0, IS_TRACED, 0) \ - _( 1, NEXT_PRESENT, 0) \ + _( 1, NEXT_PRESENT, "next-present") \ _( 2, TOTAL_LENGTH_VALID, 0) \ _( 3, EXT_HDR_VALID, "ext-hdr-valid") @@ -98,6 +98,15 @@ enum #define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n)) #define VLIB_BUFFER_FLAGS_ALL (0x0f) +/** \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... + See vlib/main.c... +*/ +#ifndef VLIB_BUFFER_TRACE_TRAJECTORY +#define VLIB_BUFFER_TRACE_TRAJECTORY 0 +#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */ + /** VLIB buffer representation. */ typedef union { @@ -139,8 +148,15 @@ typedef union * VLIB_BUFFER_NEXT_PRESENT flag is set. */ u32 next_buffer; - /** Used by feature subgraph arcs to visit enabled feature nodes */ - u32 current_config_index; + /** The following fields can be in a union because once a packet enters + * the punt path, it is no longer on a feature arc */ + union + { + /** Used by feature subgraph arcs to visit enabled feature nodes */ + u32 current_config_index; + /* the reason the packet once punted */ + u32 punt_reason; + }; /** Opaque data used by sub-graphs for their own purposes. */ u32 opaque[10]; @@ -148,12 +164,12 @@ typedef union /** part of buffer metadata which is initialized on alloc ends here. */ STRUCT_MARK (template_end); - /** start of 2nd cache line */ - CLIB_CACHE_LINE_ALIGN_MARK (cacheline1); + /** start of 2nd half (2nd cacheline on systems where cacheline size is 64) */ + CLIB_ALIGN_MARK (second_half, 64); - /** Specifies index into trace buffer if VLIB_PACKET_IS_TRACED flag is + /** Specifies trace buffer handle if VLIB_PACKET_IS_TRACED flag is * set. */ - u32 trace_index; + u32 trace_handle; /** Only valid for first buffer in chain. Current length plus total length * given here give total number of bytes in buffer chain. */ @@ -162,8 +178,22 @@ typedef union /**< More opaque data, see ../vnet/vnet/buffer.h */ u32 opaque2[14]; - /** start of third cache line */ - CLIB_CACHE_LINE_ALIGN_MARK (cacheline2); +#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 + /** trace trajectory data - we use a specific cacheline for that in the + * buffer when it is compiled-in */ +#define VLIB_BUFFER_TRACE_TRAJECTORY_MAX 31 +#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 64 +#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->trajectory_nb = 0 + CLIB_ALIGN_MARK (trajectory, 64); + u16 trajectory_nb; + u16 trajectory_trace[VLIB_BUFFER_TRACE_TRAJECTORY_MAX]; +#else /* VLIB_BUFFER_TRACE_TRAJECTORY */ +#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 0 +#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) +#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */ + + /** start of buffer headroom */ + CLIB_ALIGN_MARK (headroom, 64); /** Space for inserting data before buffer start. Packet rewrite string * will be rewritten backwards and may extend back before @@ -171,7 +201,7 @@ typedef union u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]; /** Packet data */ - u8 data[0]; + u8 data[]; }; #ifdef CLIB_HAVE_VEC128 u8x16 as_u8x16[4]; @@ -184,6 +214,11 @@ typedef union #endif } vlib_buffer_t; +STATIC_ASSERT_SIZEOF (vlib_buffer_t, 128 + VLIB_BUFFER_TRACE_TRAJECTORY_SZ + + VLIB_BUFFER_PRE_DATA_SIZE); +STATIC_ASSERT (VLIB_BUFFER_PRE_DATA_SIZE % CLIB_CACHE_LINE_BYTES == 0, + "VLIB_BUFFER_PRE_DATA_SIZE must be divisible by cache line size"); + #define VLIB_BUFFER_HDR_SIZE (sizeof(vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE) /** \brief Prefetch buffer metadata. @@ -342,11 +377,48 @@ vlib_buffer_push_uninit (vlib_buffer_t * b, u8 size) always_inline void * vlib_buffer_make_headroom (vlib_buffer_t * b, u8 size) { - ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size); b->current_data += size; return vlib_buffer_get_current (b); } +/** \brief Construct a trace handle from thread and pool index + * @param thread Thread id + * @param pool_index Pool index + * @return trace handle + */ +always_inline u32 +vlib_buffer_make_trace_handle (u32 thread, u32 pool_index) +{ + u32 rv; + ASSERT (thread < 0xff); + ASSERT (pool_index < 0x00FFFFFF); + rv = (thread << 24) | (pool_index & 0x00FFFFFF); + return rv; +} + +/** \brief Extract the thread id from a trace handle + * @param trace_handle the trace handle + * @return the thread id + */ +always_inline u32 +vlib_buffer_get_trace_thread (vlib_buffer_t * b) +{ + u32 trace_handle = b->trace_handle; + + return trace_handle >> 24; +} + +/** \brief Extract the trace (pool) index from a trace handle + * @param trace_handle the trace handle + * @return the trace index + */ +always_inline u32 +vlib_buffer_get_trace_index (vlib_buffer_t * b) +{ + u32 trace_handle = b->trace_handle; + return trace_handle & 0x00FFFFFF; +} + /** \brief Retrieve bytes from buffer head * @param b pointer to the buffer * @param size number of bytes to pull @@ -366,12 +438,15 @@ vlib_buffer_pull (vlib_buffer_t * b, u8 size) /* Forward declaration. */ struct vlib_main_t; +#define VLIB_BUFFER_POOL_PER_THREAD_CACHE_SZ 512 + typedef struct { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); - u32 *cached_buffers; - u32 n_alloc; + u32 cached_buffers[VLIB_BUFFER_POOL_PER_THREAD_CACHE_SZ]; + u32 n_cached; } vlib_buffer_pool_thread_t; + typedef struct { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); @@ -383,6 +458,7 @@ typedef struct u32 physmem_map_index; u32 data_size; u32 n_buffers; + u32 n_avail; u32 *buffers; u8 *name; clib_spinlock_t lock; @@ -396,6 +472,10 @@ typedef struct #define VLIB_BUFFER_MAX_NUMA_NODES 32 +typedef u32 (vlib_buffer_alloc_free_callback_t) (struct vlib_main_t *vm, + u8 buffer_pool_index, + u32 *buffers, u32 n_buffers); + typedef struct { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); @@ -405,18 +485,23 @@ typedef struct uword buffer_mem_size; vlib_buffer_pool_t *buffer_pools; - /* 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; - clib_spinlock_t buffer_known_hash_lockp; + vlib_buffer_alloc_free_callback_t *alloc_callback_fn; + vlib_buffer_alloc_free_callback_t *free_callback_fn; + u8 default_buffer_pool_index_for_numa[VLIB_BUFFER_MAX_NUMA_NODES]; /* config */ u32 buffers_per_numa; u16 ext_hdr_size; u32 default_data_size; + clib_mem_page_sz_t log2_page_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; + clib_spinlock_t buffer_known_hash_lockp; /* logging */ vlib_log_class_t log_default; @@ -424,25 +509,11 @@ typedef struct clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm); -/* - */ - -/** \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... - See vlib/main.c... -*/ -#define VLIB_BUFFER_TRACE_TRAJECTORY 0 +format_function_t format_vlib_buffer_pool_all; -#if VLIB_BUFFER_TRACE_TRAJECTORY > 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 */ +int vlib_buffer_set_alloc_free_callback ( + struct vlib_main_t *vm, vlib_buffer_alloc_free_callback_t *alloc_callback_fn, + vlib_buffer_alloc_free_callback_t *free_callback_fn); extern u16 __vlib_buffer_external_hdr_size; #define VLIB_BUFFER_SET_EXT_HDR_SIZE(x) \