X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Fbihash_template.c;h=38354a129921d942925562e8ba037f1b39a2e49e;hb=bf40da413f8dc1d2d3a2ca355541d6b3648ba532;hp=e408d157da77c8b90709fbc377238a9973d28e75;hpb=2454de2d4539943d4140839facf6a2a2ea795556;p=vpp.git diff --git a/src/vppinfra/bihash_template.c b/src/vppinfra/bihash_template.c index e408d157da7..38354a12992 100644 --- a/src/vppinfra/bihash_template.c +++ b/src/vppinfra/bihash_template.c @@ -23,6 +23,10 @@ #define BIIHASH_MIN_ALLOC_LOG2_PAGES 10 #endif +#ifndef BIHASH_USE_HEAP +#define BIHASH_USE_HEAP 1 +#endif + static inline void *BV (alloc_aligned) (BVT (clib_bihash) * h, uword nbytes) { uword rv; @@ -161,19 +165,23 @@ static void BV (clib_bihash_instantiate) (BVT (clib_bihash) * h) if (BIHASH_KVP_AT_BUCKET_LEVEL) { - int i; + int i, j; BVT (clib_bihash_bucket) * b; b = h->buckets; for (i = 0; i < h->nbuckets; i++) { + BVT (clib_bihash_kv) * v; b->offset = BV (clib_bihash_get_offset) (h, (void *) (b + 1)); b->refcnt = 1; /* Mark all elements free */ - clib_memset_u8 ((b + 1), 0xff, BIHASH_KVP_PER_PAGE * - sizeof (BVT (clib_bihash_kv))); - + v = (void *) (b + 1); + for (j = 0; j < BIHASH_KVP_PER_PAGE; j++) + { + BV (clib_bihash_mark_free) (v); + v++; + } /* Compute next bucket start address */ b = (void *) (((uword) b) + sizeof (*b) + (BIHASH_KVP_PER_PAGE * @@ -197,7 +205,9 @@ void BV (clib_bihash_init2) (BVT (clib_bihash_init2_args) * a) h->log2_nbuckets = max_log2 (a->nbuckets); h->memory_size = BIHASH_USE_HEAP ? 0 : a->memory_size; h->instantiated = 0; - h->fmt_fn = a->fmt_fn; + h->dont_add_to_all_bihash_list = a->dont_add_to_all_bihash_list; + h->fmt_fn = BV (format_bihash); + h->kvp_fmt_fn = a->kvp_fmt_fn; alloc_arena (h) = 0; @@ -271,7 +281,7 @@ void BV (clib_bihash_initiator_init_svm) ASSERT (memory_size < (1ULL << 32)); /* Set up for memfd sharing */ - if ((fd = memfd_create (name, MFD_ALLOW_SEALING)) == -1) + if ((fd = clib_mem_vm_create_fd (CLIB_MEM_PAGE_SZ_DEFAULT, name) == -1) { clib_unix_warning ("memfd_create"); return; @@ -327,7 +337,8 @@ void BV (clib_bihash_initiator_init_svm) (u64) BV (clib_bihash_get_offset) (h, freelist_vh->vector_data); h->freelists = (void *) (freelist_vh->vector_data); - h->fmt_fn = NULL; + h->fmt_fn = BV (format_bihash); + h->kvp_fmt_fn = NULL; h->instantiated = 1; } @@ -377,14 +388,20 @@ void BV (clib_bihash_responder_init_svm) h->alloc_lock = BV (clib_bihash_get_value) (h, h->sh->alloc_lock_as_u64); h->freelists = BV (clib_bihash_get_value) (h, h->sh->freelists_as_u64); - h->fmt_fn = NULL; + h->fmt_fn = BV (format_bihash); + h->kvp_fmt_fn = NULL; } #endif /* BIHASH_32_64_SVM */ void BV (clib_bihash_set_kvp_format_fn) (BVT (clib_bihash) * h, - format_function_t * fmt_fn) + format_function_t * kvp_fmt_fn) +{ + h->kvp_fmt_fn = kvp_fmt_fn; +} + +int BV (clib_bihash_is_initialised) (const BVT (clib_bihash) * h) { - h->fmt_fn = fmt_fn; + return (h->instantiated != 0); } void BV (clib_bihash_free) (BVT (clib_bihash) * h) @@ -413,6 +430,7 @@ void BV (clib_bihash_free) (BVT (clib_bihash) * h) vec_free (h->working_copies); vec_free (h->working_copy_lengths); + clib_mem_free ((void *) h->alloc_lock); #if BIHASH_32_64_SVM == 0 vec_free (h->freelists); #else @@ -423,6 +441,11 @@ void BV (clib_bihash_free) (BVT (clib_bihash) * h) clib_mem_vm_free ((void *) (uword) (alloc_arena (h)), alloc_arena_size (h)); never_initialized: + if (h->dont_add_to_all_bihash_list) + { + clib_memset_u8 (h, 0, sizeof (*h)); + return; + } clib_memset_u8 (h, 0, sizeof (*h)); for (i = 0; i < vec_len (clib_all_bihashes); i++) { @@ -440,6 +463,7 @@ static BVT (clib_bihash_value) * BV (value_alloc) (BVT (clib_bihash) * h, u32 log2_pages) { + int i; BVT (clib_bihash_value) * rv = 0; ASSERT (h->alloc_lock[0]); @@ -459,12 +483,15 @@ BV (value_alloc) (BVT (clib_bihash) * h, u32 log2_pages) initialize: ASSERT (rv); - /* - * Latest gcc complains that the length arg is zero - * if we replace (1<instantiated != 0); #endif + /* + * Debug image: make sure that an item being added doesn't accidentally + * look like a free item. + */ + ASSERT ((is_add && BV (clib_bihash_is_free) (add_v)) == 0); + b = BV (clib_bihash_get_bucket) (h, hash); BV (clib_bihash_lock_bucket) (b); @@ -749,6 +783,8 @@ static_always_inline int BV (clib_bihash_add_del_inline_with_hash) */ for (i = 0; i < limit; i++) { + if (BV (clib_bihash_is_free) (&(v->kvp[i]))) + continue; if (BV (clib_bihash_key_compare) (v->kvp[i].key, add_v->key)) { /* Add but do not overwrite? */ @@ -757,7 +793,8 @@ static_always_inline int BV (clib_bihash_add_del_inline_with_hash) BV (clib_bihash_unlock_bucket) (b); return (-2); } - + if (overwrite_cb) + overwrite_cb (&(v->kvp[i]), overwrite_arg); clib_memcpy_fast (&(v->kvp[i].value), &add_v->value, sizeof (add_v->value)); BV (clib_bihash_unlock_bucket) (b); @@ -793,7 +830,7 @@ static_always_inline int BV (clib_bihash_add_del_inline_with_hash) { for (i = 0; i < limit; i++) { - if (is_stale_cb (&(v->kvp[i]), arg)) + if (is_stale_cb (&(v->kvp[i]), is_stale_arg)) { clib_memcpy_fast (&(v->kvp[i]), add_v, sizeof (*add_v)); CLIB_MEMORY_STORE_BARRIER (); @@ -809,10 +846,13 @@ static_always_inline int BV (clib_bihash_add_del_inline_with_hash) { for (i = 0; i < limit; i++) { + /* no sense even looking at this one */ + if (BV (clib_bihash_is_free) (&(v->kvp[i]))) + continue; /* Found the key? Kill it... */ if (BV (clib_bihash_key_compare) (v->kvp[i].key, add_v->key)) { - clib_memset_u8 (&(v->kvp[i]), 0xff, sizeof (*(add_v))); + BV (clib_bihash_mark_free) (&(v->kvp[i])); /* Is the bucket empty? */ if (PREDICT_TRUE (b->refcnt > 1)) { @@ -827,8 +867,13 @@ static_always_inline int BV (clib_bihash_add_del_inline_with_hash) b->linear_search = 0; b->log2_pages = 0; /* Clean up the bucket-level kvp array */ - clib_memset_u8 ((b + 1), 0xff, BIHASH_KVP_PER_PAGE * - sizeof (BVT (clib_bihash_kv))); + BVT (clib_bihash_kv) *v = (void *) (b + 1); + int j; + for (j = 0; j < BIHASH_KVP_PER_PAGE; j++) + { + BV (clib_bihash_mark_free) (v); + v++; + } CLIB_MEMORY_STORE_BARRIER (); BV (clib_bihash_unlock_bucket) (b); BV (clib_bihash_increment_stat) (h, BIHASH_STAT_del, 1); @@ -975,7 +1020,15 @@ static_always_inline int BV (clib_bihash_add_del_inline) { u64 hash = BV (clib_bihash_hash) (add_v); return BV (clib_bihash_add_del_inline_with_hash) (h, add_v, hash, is_add, - is_stale_cb, arg); + is_stale_cb, arg, 0, 0); +} + +int BV (clib_bihash_add_del_with_hash) (BVT (clib_bihash) * h, + BVT (clib_bihash_kv) * add_v, u64 hash, + int is_add) +{ + return BV (clib_bihash_add_del_inline_with_hash) (h, add_v, hash, is_add, 0, + 0, 0, 0); } int BV (clib_bihash_add_del) @@ -991,6 +1044,15 @@ int BV (clib_bihash_add_or_overwrite_stale) return BV (clib_bihash_add_del_inline) (h, add_v, 1, stale_callback, arg); } +int BV (clib_bihash_add_with_overwrite_cb) ( + BVT (clib_bihash) * h, BVT (clib_bihash_kv) * add_v, + void (overwrite_cb) (BVT (clib_bihash_kv) *, void *), void *arg) +{ + u64 hash = BV (clib_bihash_hash) (add_v); + return BV (clib_bihash_add_del_inline_with_hash) (h, add_v, hash, 1, 0, 0, + overwrite_cb, arg); +} + int BV (clib_bihash_search) (BVT (clib_bihash) * h, BVT (clib_bihash_kv) * search_key, BVT (clib_bihash_kv) * valuep) @@ -1009,11 +1071,11 @@ u8 *BV (format_bihash) (u8 * s, va_list * args) u64 active_buckets = 0; u64 linear_buckets = 0; - s = format (s, "Hash table %s\n", h->name ? h->name : (u8 *) "(unnamed)"); + s = format (s, "Hash table '%s'\n", h->name ? h->name : (u8 *) "(unnamed)"); #if BIHASH_LAZY_INSTANTIATE if (PREDICT_FALSE (h->instantiated == 0)) - return format (s, "[empty, uninitialized]"); + return format (s, " empty, uninitialized"); #endif for (i = 0; i < h->nbuckets; i++) @@ -1052,11 +1114,11 @@ u8 *BV (format_bihash) (u8 * s, va_list * args) } if (verbose) { - if (h->fmt_fn) + if (h->kvp_fmt_fn) { s = format (s, " %d: %U\n", j * BIHASH_KVP_PER_PAGE + k, - h->fmt_fn, &(v->kvp[k]), verbose); + h->kvp_fmt_fn, &(v->kvp[k]), verbose); } else { @@ -1106,8 +1168,8 @@ u8 *BV (format_bihash) (u8 * s, va_list * args) c = c->next; } s = format (s, - " heap: %u chunks allocated\n" - " used %UB, scrap %UB\n", n_chunks, + " heap: %u chunk(s) allocated\n" + " bytes: used %U, scrap %U\n", n_chunks, format_memory_size, total_size, format_memory_size, bytes_left); }