X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fbuffer_funcs.h;h=0ac05f3f703c32f47e60a2e9ce1c33bcf51b15af;hb=70488ab7f87096534aaadd7eab30e8515ac3d60d;hp=b73fb266d647d8e78ba7d0e05c6834accf2777fb;hpb=8f36e4a3f8e647796c273f82325a9ba4738ea49a;p=vpp.git diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h index b73fb266d64..0ac05f3f703 100644 --- a/src/vlib/buffer_funcs.h +++ b/src/vlib/buffer_funcs.h @@ -56,7 +56,7 @@ always_inline vlib_buffer_t * vlib_get_buffer (vlib_main_t * vm, u32 buffer_index) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; uword offset = ((uword) buffer_index) << CLIB_LOG2_CACHE_LINE_BYTES; ASSERT (offset < bm->buffer_mem_size); @@ -73,7 +73,7 @@ vlib_get_buffer (vlib_main_t * vm, u32 buffer_index) always_inline u32 vlib_get_buffer_index (vlib_main_t * vm, void *p) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; uword offset = pointer_to_uword (p) - bm->buffer_mem_start; ASSERT (pointer_to_uword (p) >= bm->buffer_mem_start); ASSERT (offset < bm->buffer_mem_size); @@ -162,7 +162,7 @@ vlib_buffer_contents (vlib_main_t * vm, u32 buffer_index, u8 * contents) always_inline u64 vlib_get_buffer_data_physical_address (vlib_main_t * vm, u32 buffer_index) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; vlib_buffer_t *b = vlib_get_buffer (vm, buffer_index); vlib_buffer_pool_t *pool = vec_elt_at_index (bm->buffer_pools, b->buffer_pool_index); @@ -224,7 +224,7 @@ void vlib_buffer_validate_alloc_free (vlib_main_t * vm, u32 * buffers, always_inline vlib_buffer_known_state_t vlib_buffer_is_known (u32 buffer_index) { - vlib_buffer_main_t *bm = vlib_global_main.buffer_main; + vlib_buffer_main_t *bm = &buffer_main; clib_spinlock_lock (&bm->buffer_known_hash_lockp); uword *p = hash_get (bm->buffer_known_hash, buffer_index); @@ -236,7 +236,7 @@ always_inline void vlib_buffer_set_known_state (u32 buffer_index, vlib_buffer_known_state_t state) { - vlib_buffer_main_t *bm = vlib_global_main.buffer_main; + vlib_buffer_main_t *bm = &buffer_main; clib_spinlock_lock (&bm->buffer_known_hash_lockp); hash_set (bm->buffer_known_hash, buffer_index, state); @@ -254,22 +254,26 @@ vlib_buffer_round_size (u32 size) return round_pow2 (size, sizeof (vlib_buffer_t)); } -always_inline u32 +always_inline vlib_buffer_free_list_index_t vlib_buffer_get_free_list_index (vlib_buffer_t * b) { - return b->flags & VLIB_BUFFER_FREE_LIST_INDEX_MASK; + if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NON_DEFAULT_FREELIST)) + return b->free_list_index; + + return 0; } always_inline void -vlib_buffer_set_free_list_index (vlib_buffer_t * b, u32 index) +vlib_buffer_set_free_list_index (vlib_buffer_t * b, + vlib_buffer_free_list_index_t 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; + if (PREDICT_FALSE (index)) + { + b->flags |= VLIB_BUFFER_NON_DEFAULT_FREELIST; + b->free_list_index = index; + } + else + b->flags &= ~VLIB_BUFFER_NON_DEFAULT_FREELIST; } /** \brief Allocate buffers from specific freelist into supplied array @@ -283,23 +287,25 @@ vlib_buffer_set_free_list_index (vlib_buffer_t * b, u32 index) always_inline u32 vlib_buffer_alloc_from_free_list (vlib_main_t * vm, u32 * buffers, - u32 n_buffers, u32 free_list_index) + u32 n_buffers, + vlib_buffer_free_list_index_t index) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; vlib_buffer_free_list_t *fl; u32 *src; uword len; ASSERT (bm->cb.vlib_buffer_fill_free_list_cb); - fl = pool_elt_at_index (bm->buffer_free_list_pool, free_list_index); + fl = pool_elt_at_index (vm->buffer_free_list_pool, index); len = vec_len (fl->buffers); if (PREDICT_FALSE (len < n_buffers)) { bm->cb.vlib_buffer_fill_free_list_cb (vm, fl, n_buffers); - len = vec_len (fl->buffers); + if (PREDICT_FALSE ((len = vec_len (fl->buffers)) == 0)) + return 0; /* even if fill free list didn't manage to refill free list we should give what we have */ @@ -388,7 +394,7 @@ vlib_buffer_free (vlib_main_t * vm, /* number of buffers to free */ u32 n_buffers) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; ASSERT (bm->cb.vlib_buffer_free_cb); @@ -409,7 +415,7 @@ vlib_buffer_free_no_next (vlib_main_t * vm, /* number of buffers to free */ u32 n_buffers) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; ASSERT (bm->cb.vlib_buffer_free_no_next_cb); @@ -428,61 +434,70 @@ vlib_buffer_free_one (vlib_main_t * vm, u32 buffer_index) vlib_buffer_free (vm, &buffer_index, /* n_buffers */ 1); } +/** \brief Free buffers from ring + + @param vm - (vlib_main_t *) vlib main data structure pointer + @param buffers - (u32 * ) buffer index ring + @param start - (u32) first slot in the ring + @param ring_size - (u32) ring size + @param n_buffers - (u32) number of buffers +*/ +always_inline void +vlib_buffer_free_from_ring (vlib_main_t * vm, u32 * ring, u32 start, + u32 ring_size, u32 n_buffers) +{ + ASSERT (n_buffers <= ring_size); + + if (PREDICT_TRUE (start + n_buffers <= ring_size)) + { + vlib_buffer_free (vm, ring + start, n_buffers); + } + else + { + vlib_buffer_free (vm, ring + start, ring_size - start); + vlib_buffer_free (vm, ring, n_buffers - (ring_size - start)); + } +} + + /* Add/delete buffer free lists. */ -u32 vlib_buffer_create_free_list (vlib_main_t * vm, u32 n_data_bytes, - char *fmt, ...); +vlib_buffer_free_list_index_t vlib_buffer_create_free_list (vlib_main_t * vm, + u32 n_data_bytes, + char *fmt, ...); always_inline void -vlib_buffer_delete_free_list (vlib_main_t * vm, u32 free_list_index) +vlib_buffer_delete_free_list (vlib_main_t * vm, + vlib_buffer_free_list_index_t free_list_index) { - vlib_buffer_main_t *bm = vm->buffer_main; + vlib_buffer_main_t *bm = &buffer_main; ASSERT (bm->cb.vlib_buffer_delete_free_list_cb); bm->cb.vlib_buffer_delete_free_list_cb (vm, free_list_index); } -/* Find already existing public free list with given size or create one. */ -u32 vlib_buffer_get_or_create_free_list (vlib_main_t * vm, u32 n_data_bytes, - char *fmt, ...); - -/* Merge two free lists */ -void vlib_buffer_merge_free_lists (vlib_buffer_free_list_t * dst, - vlib_buffer_free_list_t * src); - /* Make sure we have at least given number of unaligned buffers. */ void vlib_buffer_free_list_fill_unaligned (vlib_main_t * vm, vlib_buffer_free_list_t * free_list, uword n_unaligned_buffers); -always_inline u32 -vlib_buffer_get_free_list_with_size (vlib_main_t * vm, u32 size) -{ - vlib_buffer_main_t *bm = vm->buffer_main; - - size = vlib_buffer_round_size (size); - uword *p = hash_get (bm->free_list_by_size, size); - return p ? p[0] : ~0; -} - always_inline vlib_buffer_free_list_t * vlib_buffer_get_buffer_free_list (vlib_main_t * vm, vlib_buffer_t * b, - u32 * index) + vlib_buffer_free_list_index_t * index) { - vlib_buffer_main_t *bm = vm->buffer_main; - u32 i; + vlib_buffer_free_list_index_t i; *index = i = vlib_buffer_get_free_list_index (b); - return pool_elt_at_index (bm->buffer_free_list_pool, i); + return pool_elt_at_index (vm->buffer_free_list_pool, i); } always_inline vlib_buffer_free_list_t * -vlib_buffer_get_free_list (vlib_main_t * vm, u32 free_list_index) +vlib_buffer_get_free_list (vlib_main_t * vm, + vlib_buffer_free_list_index_t free_list_index) { - vlib_buffer_main_t *bm = vm->buffer_main; vlib_buffer_free_list_t *f; - f = pool_elt_at_index (bm->buffer_free_list_pool, free_list_index); + f = pool_elt_at_index (vm->buffer_free_list_pool, free_list_index); /* Sanity: indices must match. */ ASSERT (f->index == free_list_index); @@ -491,10 +506,10 @@ vlib_buffer_get_free_list (vlib_main_t * vm, u32 free_list_index) } always_inline u32 -vlib_buffer_free_list_buffer_size (vlib_main_t * vm, u32 free_list_index) +vlib_buffer_free_list_buffer_size (vlib_main_t * vm, + vlib_buffer_free_list_index_t index) { - vlib_buffer_free_list_t *f = - vlib_buffer_get_free_list (vm, free_list_index); + vlib_buffer_free_list_t *f = vlib_buffer_get_free_list (vm, index); return f->n_data_bytes; } @@ -525,7 +540,7 @@ vlib_copy_buffers (u32 * dst, u32 * src, u32 n) /* Append given data to end of buffer, possibly allocating new buffers. */ u32 vlib_buffer_add_data (vlib_main_t * vm, - u32 free_list_index, + vlib_buffer_free_list_index_t free_list_index, u32 buffer_index, void *data, u32 n_data_bytes); /* duplicate all buffers in chain */ @@ -772,7 +787,7 @@ vlib_buffer_chain_increase_length (vlib_buffer_t * first, * Returns the number of copied bytes. */ always_inline u16 vlib_buffer_chain_append_data (vlib_main_t * vm, - u32 free_list_index, + vlib_buffer_free_list_index_t free_list_index, vlib_buffer_t * first, vlib_buffer_t * last, void *data, u16 data_len) { @@ -795,10 +810,11 @@ vlib_buffer_chain_append_data (vlib_main_t * vm, * chained and points to the last buffer in the chain. */ u16 vlib_buffer_chain_append_data_with_alloc (vlib_main_t * vm, - u32 free_list_index, + vlib_buffer_free_list_index_t + free_list_index, vlib_buffer_t * first, - vlib_buffer_t ** last, - void *data, u16 data_len); + vlib_buffer_t ** last, void *data, + u16 data_len); void vlib_buffer_chain_validate (vlib_main_t * vm, vlib_buffer_t * first); format_function_t format_vlib_buffer, format_vlib_buffer_and_data, @@ -809,12 +825,11 @@ typedef struct /* Vector of packet data. */ u8 *packet_data; - /* Number of buffers to allocate in each call to physmem - allocator. */ - u32 min_n_buffers_each_physmem_alloc; + /* Number of buffers to allocate in each call to allocator. */ + u32 min_n_buffers_each_alloc; /* Buffer free list for this template. */ - u32 free_list_index; + vlib_buffer_free_list_index_t free_list_index; u32 *free_buffers; } vlib_packet_template_t; @@ -826,7 +841,7 @@ void vlib_packet_template_init (vlib_main_t * vm, vlib_packet_template_t * t, void *packet_data, uword n_packet_data_bytes, - uword min_n_buffers_each_physmem_alloc, + uword min_n_buffers_each_alloc, char *fmt, ...); void *vlib_packet_template_get_packet (vlib_main_t * vm, @@ -895,6 +910,7 @@ vlib_buffer_init_for_free_list (vlib_buffer_t * dst, /* Not in the first 16 octets. */ dst->n_add_refs = src->n_add_refs; + vlib_buffer_set_free_list_index (dst, fl->index); /* Make sure it really worked. */ #define _(f) ASSERT (dst->f == src->f); @@ -916,6 +932,7 @@ vlib_buffer_add_to_free_list (vlib_main_t * vm, vlib_buffer_free_list_t * f, u32 buffer_index, u8 do_init) { + vlib_buffer_pool_t *bp = vlib_buffer_pool_get (f->buffer_pool_index); vlib_buffer_t *b; b = vlib_get_buffer (vm, buffer_index); if (PREDICT_TRUE (do_init)) @@ -924,55 +941,16 @@ vlib_buffer_add_to_free_list (vlib_main_t * vm, if (vec_len (f->buffers) > 4 * VLIB_FRAME_SIZE) { - vlib_buffer_free_list_t *mf; - mf = vlib_buffer_get_free_list (vlib_mains[0], f->index); - clib_spinlock_lock (&mf->global_buffers_lock); + clib_spinlock_lock (&bp->lock); /* keep last stored buffers, as they are more likely hot in the cache */ - vec_add_aligned (mf->global_buffers, f->buffers, VLIB_FRAME_SIZE, + vec_add_aligned (bp->buffers, f->buffers, VLIB_FRAME_SIZE, CLIB_CACHE_LINE_BYTES); vec_delete (f->buffers, VLIB_FRAME_SIZE, 0); f->n_alloc -= VLIB_FRAME_SIZE; - clib_spinlock_unlock (&mf->global_buffers_lock); + clib_spinlock_unlock (&bp->lock); } } -always_inline void -vlib_buffer_init_two_for_free_list (vlib_buffer_t * dst0, - vlib_buffer_t * dst1, - vlib_buffer_free_list_t * fl) -{ - vlib_buffer_t *src = &fl->buffer_init_template; - - /* Make sure buffer template is sane. */ - ASSERT (fl->index == vlib_buffer_get_free_list_index (src)); - - clib_memcpy (STRUCT_MARK_PTR (dst0, template_start), - STRUCT_MARK_PTR (src, template_start), - STRUCT_OFFSET_OF (vlib_buffer_t, template_end) - - STRUCT_OFFSET_OF (vlib_buffer_t, template_start)); - - clib_memcpy (STRUCT_MARK_PTR (dst1, template_start), - STRUCT_MARK_PTR (src, template_start), - STRUCT_OFFSET_OF (vlib_buffer_t, template_end) - - STRUCT_OFFSET_OF (vlib_buffer_t, template_start)); - - /* Not in the first 16 octets. */ - dst0->n_add_refs = src->n_add_refs; - dst1->n_add_refs = src->n_add_refs; - - /* Make sure it really worked. */ -#define _(f) ASSERT (dst0->f == src->f); ASSERT( dst1->f == src->f) - _(current_data); - _(current_length); - _(flags); -#undef _ - - ASSERT (dst0->total_length_not_including_first_buffer == 0); - ASSERT (dst1->total_length_not_including_first_buffer == 0); - ASSERT (dst0->n_add_refs == 0); - ASSERT (dst1->n_add_refs == 0); -} - #if CLIB_DEBUG > 0 extern u32 *vlib_buffer_state_validation_lock; extern uword *vlib_buffer_state_validation_hash; @@ -1065,7 +1043,7 @@ vlib_buffer_chain_compress (vlib_main_t * vm, return; } /* probe free list to find allocated buffer size to avoid overfill */ - u32 index; + vlib_buffer_free_list_index_t index; vlib_buffer_free_list_t *free_list = vlib_buffer_get_buffer_free_list (vm, first, &index);