X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fsvm%2Ffifo_segment.c;h=dab97a55209af76b15355c7f417d767515bc0ea1;hb=d51880c5de3a1b22d9ac510305bdfe98fa12e51c;hp=04b3f5aadbe0dfcb138e22c8b2e120e020049ada;hpb=f9d4ab42724b260d5c242f7291d05f74cd725d7d;p=vpp.git diff --git a/src/svm/fifo_segment.c b/src/svm/fifo_segment.c index 04b3f5aadbe..dab97a55209 100644 --- a/src/svm/fifo_segment.c +++ b/src/svm/fifo_segment.c @@ -233,6 +233,10 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_t * fs, u32 data_bytes) return 0; memset (f, 0, sizeof (*f)); } + else + { + fsh->free_fifos = f->next; + } fl_index = fs_freelist_for_size (data_bytes) - 1; vec_validate_init_empty (fsh->free_chunks, fl_index, 0); @@ -248,7 +252,7 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_t * fs, u32 data_bytes) last = c; c->next = first; first = c; - n_alloc += c->length; + n_alloc += fl_size; c->length = clib_min (fl_size, data_bytes); data_bytes -= c->length; } @@ -394,6 +398,14 @@ fifo_segment_alloc_fifo (fifo_segment_t * fs, u32 data_bytes, /* (re)initialize the fifo, as in svm_fifo_create */ svm_fifo_init (f, data_bytes); + /* Initialize chunks and rbtree for multi-chunk fifos */ + if (f->start_chunk->next != f->start_chunk) + { + void *oldheap = ssvm_push_heap (fs->ssvm.sh); + svm_fifo_init_chunks (f); + ssvm_pop_heap (oldheap); + } + /* If rx fifo type add to active fifos list. When cleaning up segment, * we need a list of active sessions that should be disconnected. Since * both rx and tx fifos keep pointers to the session, it's enough to track @@ -468,6 +480,9 @@ fifo_segment_free_fifo (fifo_segment_t * fs, svm_fifo_t * f) } while (cur != f->start_chunk); + f->start_chunk = f->end_chunk = f->new_chunks = 0; + f->head_chunk = f->tail_chunk = f->ooo_enq = f->ooo_deq = 0; + oldheap = ssvm_push_heap (sh); svm_fifo_free_chunk_lookup (f); ssvm_pop_heap (oldheap); @@ -610,12 +625,16 @@ fifo_segment_preallocate_fifo_pairs (fifo_segment_t * fs, /* Calculate space requirements */ pair_size = 2 * hdrs + rx_rounded_data_size + tx_rounded_data_size; space_available = fs_free_space (fs); - pairs_to_alloc = clib_min (space_available / pair_size, *n_fifo_pairs); + pairs_to_alloc = space_available / pair_size; + pairs_to_alloc = clib_min (pairs_to_alloc, *n_fifo_pairs); + + if (!pairs_to_alloc) + return; if (fs_try_alloc_fifo_batch (fs, rx_fl_index, pairs_to_alloc)) - clib_warning ("rx prealloc failed"); + clib_warning ("rx prealloc failed: pairs %u", pairs_to_alloc); if (fs_try_alloc_fifo_batch (fs, tx_fl_index, pairs_to_alloc)) - clib_warning ("tx prealloc failed"); + clib_warning ("tx prealloc failed: pairs %u", pairs_to_alloc); /* Account for the pairs allocated */ *n_fifo_pairs -= pairs_to_alloc; @@ -632,7 +651,7 @@ fifo_segment_grow_fifo (fifo_segment_t * fs, svm_fifo_t * f, u32 chunk_size) if (!fs_chunk_size_is_valid (chunk_size)) { clib_warning ("chunk size out of range %d", chunk_size); - return 0; + return -1; } fl_index = fs_freelist_for_size (chunk_size); @@ -651,6 +670,7 @@ fifo_segment_grow_fifo (fifo_segment_t * fs, svm_fifo_t * f, u32 chunk_size) if (!c) { ssvm_pop_heap (oldheap); + ssvm_unlock_non_recursive (sh); return -1; } } @@ -658,6 +678,7 @@ fifo_segment_grow_fifo (fifo_segment_t * fs, svm_fifo_t * f, u32 chunk_size) { fs->h->free_chunks[fl_index] = c->next; c->next = 0; + fs->h->n_fl_chunk_bytes -= fs_freelist_index_to_size (fl_index); } svm_fifo_add_chunk (f, c); @@ -783,7 +804,7 @@ fifo_segment_free_bytes (fifo_segment_t * fs) } u32 -fifo_segment_chunk_prealloc_bytes (fifo_segment_t * fs) +fifo_segment_fl_chunk_bytes (fifo_segment_t * fs) { return fs->h->n_fl_chunk_bytes; } @@ -824,21 +845,45 @@ format_fifo_segment_type (u8 * s, va_list * args) u8 * format_fifo_segment (u8 * s, va_list * args) { - fifo_segment_t *sp = va_arg (*args, fifo_segment_t *); + fifo_segment_t *fs = va_arg (*args, fifo_segment_t *); int verbose __attribute__ ((unused)) = va_arg (*args, int); - fifo_segment_header_t *fsh = sp->h; - u32 count, indent; + fifo_segment_header_t *fsh; svm_fifo_chunk_t *c; + u32 count, indent; + u32 active_fifos; + u32 free_fifos; + char *address; + size_t size; int i; indent = format_get_indent (s) + 2; #if USE_DLMALLOC == 0 s = format (s, "%U segment heap: %U\n", format_white_space, indent, - format_mheap, svm_fifo_segment_heap (sp), verbose); + format_mheap, svm_fifo_segment_heap (fs), verbose); s = format (s, "%U segment has %u active fifos\n", - format_white_space, indent, fifo_segment_num_fifos (sp)); + format_white_space, indent, fifo_segment_num_fifos (fs)); #endif + if (fs == 0) + { + s = format (s, "%-15s%15s%15s%15s%15s%15s", "Name", "Type", + "HeapSize (M)", "ActiveFifos", "FreeFifos", "Address"); + return s; + } + + fsh = fs->h; + fifo_segment_info (fs, &address, &size); + active_fifos = fifo_segment_num_fifos (fs); + free_fifos = fifo_segment_num_free_fifos (fs); + + s = format (s, "%-15v%15U%15llu%15u%15u%15llx", ssvm_name (&fs->ssvm), + format_fifo_segment_type, fs, size >> 20ULL, active_fifos, + free_fifos, address); + + if (!verbose) + return s; + + s = format (s, "\n"); for (i = 0; i < vec_len (fsh->free_chunks); i++) { c = fsh->free_chunks[i]; @@ -851,11 +896,13 @@ format_fifo_segment (u8 * s, va_list * args) count++; } - s = format (s, "%U%-5u Kb: %u free", - format_white_space, indent + 2, + s = format (s, "%U%-5u Kb: %u free", format_white_space, indent + 2, 1 << (i + max_log2 (FIFO_SEGMENT_MIN_FIFO_SIZE) - 10), count); } + s = format (s, "%Ufree bytes %U", format_white_space, indent + 2, + format_memory_size, fsh->n_free_bytes); + return s; }