fifo_prepare (fifo_segment_t * fs, u32 fifo_size)
{
svm_fifo_t *f;
+ svm_fifo_chunk_t *c;
f = fifo_segment_alloc_fifo (fs, fifo_size, FIFO_SEGMENT_RX_FIFO);
- /* Paint fifo data vector with -1's */
- clib_memset (svm_fifo_head_chunk (f)->data, 0xFF, fifo_size);
+ /* Paint 1st fifo chunk with -1's */
+ c = svm_fifo_head_chunk (f);
+ clib_memset (c->data, 0xFF, c->length);
svm_fifo_init_ooo_lookup (f, 1 /* deq ooo */ );
return f;
*/
rv = svm_fifo_enqueue (f, sizeof (u32), (u8 *) test_data);
SFIFO_TEST ((rv == sizeof (u32)), "enqueued %d", rv);
- SFIFO_TEST ((f->tail == 4), "fifo tail %u", f->tail);
+ SFIFO_TEST ((f->shr->tail == 4), "fifo tail %u", f->shr->tail);
/*
* Create 3 chunks in the future. The offsets are relative
*/
for (i = 0; i < 3; i++)
{
- offset = (2 * i + 1) * sizeof (u32) - f->tail;
+ offset = (2 * i + 1) * sizeof (u32) - f->shr->tail;
data = (u8 *) (test_data + (2 * i + 1));
if (i == 0)
{
if (verbose)
vlib_cli_output (vm, "fifo after odd segs: %U", format_svm_fifo, f, 1);
- SFIFO_TEST ((f->tail == 8), "fifo tail %u", f->tail);
+ SFIFO_TEST ((f->shr->tail == 8), "fifo tail %u", f->shr->tail);
SFIFO_TEST ((svm_fifo_n_ooo_segments (f) == 2),
"number of ooo segments %u", svm_fifo_n_ooo_segments (f));
/*
* Try adding a completely overlapped segment
*/
- offset = 3 * sizeof (u32) - f->tail;
+ offset = 3 * sizeof (u32) - f->shr->tail;
data = (u8 *) (test_data + 3);
rv = svm_fifo_enqueue_with_offset (f, offset, sizeof (u32), data);
if (rv)
*/
for (i = 3; i > 1; i--)
{
- offset = (2 * i + 0) * sizeof (u32) - f->tail;
+ offset = (2 * i + 0) * sizeof (u32) - f->shr->tail;
data = (u8 *) (test_data + (2 * i + 0));
rv = svm_fifo_enqueue_with_offset (f, offset, sizeof (u32), data);
if (verbose)
for (i = 0; i < 4; i++)
{
- offset = (2 * i + 1) * sizeof (u32) - f->tail;
+ offset = (2 * i + 1) * sizeof (u32) - f->shr->tail;
data = (u8 *) (test_data + (2 * i + 1));
rv = svm_fifo_enqueue_with_offset (f, offset, sizeof (u32), data);
if (verbose)
}
}
- rv = svm_fifo_enqueue_with_offset (f, 8 - f->tail, 21, data);
+ rv = svm_fifo_enqueue_with_offset (f, 8 - f->shr->tail, 21, data);
SFIFO_TEST ((rv == 0), "ooo enqueued %u", rv);
SFIFO_TEST ((svm_fifo_n_ooo_segments (f) == 1),
"number of ooo segments %u", svm_fifo_n_ooo_segments (f));
for (i = 0; i < 4; i++)
{
- offset = (2 * i + 1) * sizeof (u32) - f->tail;
+ offset = (2 * i + 1) * sizeof (u32) - f->shr->tail;
data = (u8 *) (test_data + (2 * i + 1));
rv = svm_fifo_enqueue_with_offset (f, offset, sizeof (u32), data);
if (verbose)
{
tp = vp + i;
data64 = tp->offset;
- svm_fifo_enqueue_with_offset (f, tp->offset - f->tail, tp->len,
- (u8 *) & data64);
+ svm_fifo_enqueue_with_offset (f, tp->offset - f->shr->tail, tp->len,
+ (u8 *) &data64);
}
/* Expected result: one big fat chunk at offset 4 */
{
tp = &test_data[i];
data64 = tp->offset;
- rv = svm_fifo_enqueue_with_offset (f, tp->offset - f->tail, tp->len,
- (u8 *) & data64);
+ rv = svm_fifo_enqueue_with_offset (f, tp->offset - f->shr->tail, tp->len,
+ (u8 *) &data64);
if (rv)
{
clib_warning ("enqueue returned %d", rv);
for (i = !randomize; i < vec_len (generate); i++)
{
tp = generate + i;
- svm_fifo_enqueue_with_offset (f,
- fifo_initial_offset + tp->offset -
- f->tail, tp->len,
- (u8 *) data_pattern + tp->offset);
+ svm_fifo_enqueue_with_offset (
+ f, fifo_initial_offset + tp->offset - f->shr->tail, tp->len,
+ (u8 *) data_pattern + tp->offset);
}
/* Add the first segment in order for non random data */
for (i = test_n_bytes - 1; i > 0; i--)
{
- rv = svm_fifo_enqueue_with_offset (f, fifo_initial_offset + i - f->tail,
- sizeof (u8), &test_data[i]);
+ rv = svm_fifo_enqueue_with_offset (
+ f, fifo_initial_offset + i - f->shr->tail, sizeof (u8), &test_data[i]);
if (verbose)
vlib_cli_output (vm, "add [%d] [%d, %d]", i, i, i + sizeof (u8));
if (rv)
if (compare_data (data_buf, test_data, 0, n_test_bytes, (u32 *) & j))
SFIFO_TEST (0, "[%d] dequeued %u expected %u", j, data_buf[j],
test_data[j]);
- svm_fifo_init_pointers (f, (~0 - i) % f->size, (~0 - i) % f->size);
+ svm_fifo_init_pointers (f, (~0 - i) % f->shr->size,
+ (~0 - i) % f->shr->size);
}
SFIFO_TEST (1, "passed multiple ooo enqueue/dequeue");
SFIFO_TEST (rv == 2, "should have 2 chunks has %u", rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
- c = f->head_chunk;
+ c = f_head_cptr (f);
SFIFO_TEST (c->start_byte == 0, "head start byte should be %u", 0);
SFIFO_TEST (c->length == 4096, "head chunk length should be %u", 4096);
- SFIFO_TEST (f->tail_chunk == 0, "no tail chunk");
+ SFIFO_TEST (f->shr->tail_chunk == 0, "no tail chunk");
SFIFO_TEST (f->ooo_enq == 0, "should have no ooo enq chunk");
SFIFO_TEST (f->ooo_deq == 0, "should have no ooo deq chunk");
- c = f->end_chunk;
+ c = f_end_cptr (f);
SFIFO_TEST (c->start_byte == last_start_byte, "end chunk start byte should"
" be %u", last_start_byte);
SFIFO_TEST (c->length == 4096, "end chunk length should be %u", 4096);
vlib_cli_output (vm, "[%d] dequeued %u expected %u", i, data_buf[i],
test_data[i]);
SFIFO_TEST ((rv == 0), "dequeued compared to original returned %d", rv);
- SFIFO_TEST (f->head_chunk == 0, "head chunk should be 0");
- SFIFO_TEST (f->tail_chunk == 0, "tail chunk should be 0");
+ SFIFO_TEST (f->shr->head_chunk == 0, "head chunk should be 0");
+ SFIFO_TEST (f->shr->tail_chunk == 0, "tail chunk should be 0");
SFIFO_TEST (f->ooo_deq == 0, "should have no ooo deq chunk");
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
SFIFO_TEST (rv == 2, "should have %u chunks has %u", 2, rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
- SFIFO_TEST (f->head_chunk == 0, "should have no head chunk");
+ SFIFO_TEST (f->shr->head_chunk == 0, "should have no head chunk");
/* When new fifo chunks are allocated, tail is initialized */
- SFIFO_TEST (f->tail_chunk != 0, "should have no tail chunk");
+ SFIFO_TEST (f->shr->tail_chunk != 0, "should have no tail chunk");
SFIFO_TEST (f->ooo_enq != 0, "should have an ooo enq chunk");
- c = f->end_chunk;
+ c = f_end_cptr (f);
SFIFO_TEST (c->start_byte == last_start_byte,
"end chunk should start at %u", last_start_byte);
SFIFO_TEST (c->length == 8192, "end chunk length should be %u", 8192);
SFIFO_TEST (rv == 2, "should have %u chunks has %u", 2, rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
- SFIFO_TEST (f->head_chunk == 0, "should have no head chunk");
+ SFIFO_TEST (f->shr->head_chunk == 0, "should have no head chunk");
/* Fifo is full so tail and ooo_enq should be 0 */
- SFIFO_TEST (f->tail_chunk == 0, "should have no tail chunk");
+ SFIFO_TEST (f->shr->tail_chunk == 0, "should have no tail chunk");
SFIFO_TEST (f->ooo_enq == 0, "should have no ooo enq chunk");
/*
last_start_byte += 8192;
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
- SFIFO_TEST (f->head_chunk == 0, "should have no head chunk");
- SFIFO_TEST (f->tail_chunk == 0, "should have no tail chunk");
+ SFIFO_TEST (f->shr->head_chunk == 0, "should have no head chunk");
+ SFIFO_TEST (f->shr->tail_chunk == 0, "should have no tail chunk");
/* We don't remove the last chunk even when the fifo goes empty */
rv = svm_fifo_n_chunks (f);
SFIFO_TEST (rv == 2, "should have %u chunks has %u", 2, rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
- SFIFO_TEST (f->head_chunk == 0, "should have no head chunk");
+ SFIFO_TEST (f->shr->head_chunk == 0, "should have no head chunk");
/* When new fifo chunks are allocated, tail is initialized */
- SFIFO_TEST (f->tail_chunk != 0, "should have no tail chunk");
+ SFIFO_TEST (f->shr->tail_chunk != 0, "should have no tail chunk");
SFIFO_TEST (f->ooo_enq != 0, "should have an ooo enq chunk");
- c = f->end_chunk;
+ c = f_end_cptr (f);
SFIFO_TEST (c->start_byte == last_start_byte,
"end chunk should start at %u", last_start_byte);
SFIFO_TEST (c->length == 16384, "end chunk length should be %u", 16384);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
/*
- * Dequeue just a part of data
+ * Dequeue just a part of data. Because we're tracking ooo data, we can't
+ * call dequeue. Therefore, first peek and then dequeue drop
*/
- rv = svm_fifo_dequeue (f, fifo_inc, data_buf);
+ rv = svm_fifo_peek (f, 0, fifo_inc, data_buf);
+ SFIFO_TEST (rv == fifo_inc, "should dequeue all data");
+ rv = svm_fifo_dequeue_drop (f, fifo_inc);
SFIFO_TEST (rv == fifo_inc, "should dequeue all data");
rv = svm_fifo_n_chunks (f);
SFIFO_TEST (rv == 1, "should have %u chunks has %u", 1, rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
last_start_byte += 16384;
- c = f->end_chunk;
+ c = f_end_cptr (f);
SFIFO_TEST (c->start_byte == last_start_byte,
"end chunk should start at %u", last_start_byte);
SFIFO_TEST (c->length == 4096, "end chunk length should be %u", 4096);
/*
- * Dequeue all
+ * Dequeue all. Don't call dequeue see above
*/
- rv = svm_fifo_dequeue (f, fifo_size, data_buf + fifo_inc);
+ rv = svm_fifo_peek (f, 0, fifo_size, data_buf + fifo_inc);
SFIFO_TEST (rv == fifo_size, "should dequeue all data");
+ SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
rv = compare_data (data_buf, test_data, 0, vec_len (test_data),
(u32 *) & i);
vlib_cli_output (vm, "[%d] dequeued %u expected %u", i, data_buf[i],
test_data[i]);
SFIFO_TEST ((rv == 0), "dequeued compared to original returned %d", rv);
+
+ rv = svm_fifo_dequeue_drop (f, fifo_size);
+ SFIFO_TEST (rv == fifo_size, "should dequeue all data");
+
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
/* fifo does not end on chunk boundary because of the - 100 */
- SFIFO_TEST (f->head_chunk != 0, "should have head chunk");
- SFIFO_TEST (f->tail_chunk != 0, "should have tail chunk");
+ SFIFO_TEST (f->shr->head_chunk != 0, "should have head chunk");
+ SFIFO_TEST (f->shr->tail_chunk != 0, "should have tail chunk");
/*
* Enqueue and dequeue byte-by-byte ooo
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
last_start_byte += 4096;
- c = f->end_chunk;
+ c = f_end_cptr (f);
SFIFO_TEST (c->start_byte == last_start_byte,
"end chunk should start at %u", last_start_byte);
SFIFO_TEST (c->length == 16384, "end chunk length should be %u", 16384);
SFIFO_TEST ((rv == fifo_size), "all bytes should be dropped %u", rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
- SFIFO_TEST (f->head_chunk != 0, "should have head chunk");
- SFIFO_TEST (f->tail_chunk != 0, "should have tail chunk");
+ SFIFO_TEST (f->shr->head_chunk != 0, "should have head chunk");
+ SFIFO_TEST (f->shr->tail_chunk != 0, "should have tail chunk");
/* We don't remove the last chunk even when the fifo goes empty */
rv = svm_fifo_n_chunks (f);
/*
* Dequeue all
*/
- rv = svm_fifo_dequeue (f, fifo_size, data_buf);
+
+ /* Because we're tracking ooo data, we can't call dequeue. Therefore,
+ * first peek and then dequeue drop */
+ rv = svm_fifo_peek (f, 0, fifo_size, data_buf);
SFIFO_TEST (rv == fifo_size, "should dequeue all data");
rv = compare_data (data_buf, test_data, 0, vec_len (test_data),
test_data[i]);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
SFIFO_TEST ((rv == 0), "dequeued compared to original returned %d", rv);
+
+
+ rv = svm_fifo_dequeue_drop (f, fifo_size);
+ SFIFO_TEST ((rv == fifo_size), "all bytes should be dropped %u", rv);
+ SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
SFIFO_TEST (f->ooo_deq == 0, "should have no ooo deq chunk");
rv = svm_fifo_n_chunks (f);
SFIFO_TEST (rv == 1, "should have %u chunks has %u", 1, rv);
svm_fifo_set_size (f, fifo_size);
validate_test_and_buf_vecs (&test_data, &data_buf, fifo_size);
- c = f->start_chunk;
+ c = f_start_cptr (f);
SFIFO_TEST (c->next == 0, "no next");
svm_fifo_fill_chunk_list (f);
SFIFO_TEST (c->next != 0, "new chunk should've been allocated");
- SFIFO_TEST (c->next->length == 4 << 20, "new chunk should be 4MB");
+ SFIFO_TEST (f_cptr (f, c->next)->length == 4 << 20,
+ "new chunk should be 4MB");
rv = svm_fifo_max_write_chunk (f);
SFIFO_TEST (rv == 4096, "max write chunk %u", rv);
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
c = svm_fifo_tail_chunk (f);
- SFIFO_TEST (c == f->end_chunk, "tail is end chunk");
+ SFIFO_TEST (c == f_end_cptr (f), "tail is end chunk");
/* Initialize head chunk */
rv = svm_fifo_max_read_chunk (f);
SFIFO_TEST (rv == 4096, "dequeue should work");
c = svm_fifo_head_chunk (f);
- SFIFO_TEST (c == f->end_chunk, "head chunk should be last");
+ SFIFO_TEST (c == f_end_cptr (f), "head chunk should be last");
rv = svm_fifo_max_read_chunk (f);
SFIFO_TEST (rv == 0, "max read chunk %u", rv);
return 0;
}
+static int
+sfifo_test_fifo_make_rcv_wnd_zero (vlib_main_t * vm, unformat_input_t * input)
+{
+ int __clib_unused verbose = 0, fifo_size = 4096, deq_chunk;
+ fifo_segment_main_t _fsm = { 0 }, *fsm = &_fsm;
+ u8 *test_data = 0, *data_buf = 0;
+ fifo_segment_t *fs;
+ svm_fifo_t *f;
+ int rv;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "verbose"))
+ verbose = 1;
+ else
+ {
+ vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
+ input);
+ return -1;
+ }
+ }
+
+ /*
+ * Init fifo and enqueue data such that multiple 4096 chunks are allocated
+ */
+ fs = fifo_segment_prepare (fsm, "fifo-rcv-wnd-zero", 0);
+ f = fifo_prepare (fs, fifo_size);
+
+ /* Enqueue 3000 into 4KB chunk, so there'll be 1096 free space */
+ svm_fifo_set_size (f, 4096);
+ validate_test_and_buf_vecs (&test_data, &data_buf, fifo_size);
+ rv = svm_fifo_enqueue (f, 3000, test_data);
+ SFIFO_TEST (rv == 3000, "enqueued %u", rv);
+ rv = svm_fifo_max_enqueue (f);
+ SFIFO_TEST (rv == 1096, "svm_fifo_max_enqueue %u", rv);
+ SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
+
+ /* Shrink fifo size to the in-use size */
+ svm_fifo_set_size (f, 3000);
+ SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
+
+ /* In TCP, this should result in rcv-wnd = 0 */
+ rv = svm_fifo_max_enqueue (f);
+ SFIFO_TEST (rv == 0, "svm_fifo_max_enqueue %u", rv);
+ rv = svm_fifo_max_enqueue_prod (f);
+ SFIFO_TEST (rv == 0, "svm_fifo_max_enqueue_prod %u", rv);
+
+ /* Dequeue and ... */
+ rv = svm_fifo_dequeue (f, 3000, data_buf);
+ SFIFO_TEST (rv == 3000, "dequeued %u", rv);
+
+ /* Clean up */
+ ft_fifo_free (fs, f);
+ ft_fifo_segment_free (fsm, fs);
+ vec_free (test_data);
+ vec_free (data_buf);
+
+ return 0;
+}
+
+
static fifo_segment_main_t segment_main;
static int
clib_memset (a, 0, sizeof (*a));
a->segment_name = "fifo-test1";
a->segment_size = 256 << 10;
+ a->segment_type = SSVM_SEGMENT_PRIVATE;
rv = fifo_segment_create (sm, a);
SFIFO_TEST (!rv, "svm_fifo_segment_create returned %d", rv);
fifo_segment_main_t *sm = &segment_main;
fifo_segment_create_args_t _a, *a = &_a;
u8 *test_data = 0, *data_buf = 0;
- u32 n_free_chunk_bytes;
+ u32 n_free_chunk_bytes, new_size;
fifo_segment_t *fs;
- svm_fifo_t *f;
+ svm_fifo_t *f, *tf;
clib_memset (a, 0, sizeof (*a));
a->segment_name = "fifo-test1";
/* size chosen to be able to force multi chunk allocation lower */
a->segment_size = 256 << 10;
+ /* overhead that reduces the amount of space dedicated to fifos */
+ a->segment_size += 1 << 14;
+ a->segment_type = SSVM_SEGMENT_PRIVATE;
/* fifo allocation allocates chunks in batch */
n_batch = FIFO_SEGMENT_ALLOC_BATCH_SIZE;
n_free_chunk_bytes, rv);
/*
- * Allocate fifo that has all chunks
+ * Allocate fifo that has all chunks. Because we have a chunk size limit of
+ * segment_size / 2, allocate 2 fifos.
*/
- f = fifo_segment_alloc_fifo (fs, n_free_chunk_bytes, FIFO_SEGMENT_RX_FIFO);
+ tf = fifo_segment_alloc_fifo (fs, n_free_chunk_bytes / 2,
+ FIFO_SEGMENT_RX_FIFO);
+ SFIFO_TEST (tf != 0, "allocation should work");
+ SFIFO_TEST (svm_fifo_is_sane (tf), "fifo should be sane");
+
+ f = fifo_segment_alloc_fifo (fs, n_free_chunk_bytes / 2,
+ FIFO_SEGMENT_RX_FIFO);
SFIFO_TEST (f != 0, "allocation should work");
SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
+ fifo_segment_free_fifo (fs, tf);
fifo_segment_free_fifo (fs, f);
rv = fifo_segment_fl_chunk_bytes (fs);
FIFO_SEGMENT_RX_FIFO);
/* Try to force fifo growth */
- svm_fifo_set_size (f, svm_fifo_size (f) + n_free_chunk_bytes + 1);
- validate_test_and_buf_vecs (&test_data, &data_buf, svm_fifo_size (f));
- rv = svm_fifo_enqueue (f, svm_fifo_size (f), test_data);
+ new_size = svm_fifo_size (f) + n_free_chunk_bytes + 1;
+ svm_fifo_set_size (f, new_size);
+ validate_test_and_buf_vecs (&test_data, &data_buf, new_size);
+ rv = svm_fifo_enqueue (f, new_size, test_data);
- SFIFO_TEST (rv != svm_fifo_size (f), "grow should fail size %u wrote %d",
- svm_fifo_size (f), rv);
+ SFIFO_TEST (rv != new_size, "grow should fail size %u wrote %d",
+ new_size, rv);
fifo_segment_free_fifo (fs, f);
svm_fifo_dequeue (f, vec_len (retrieved_data), retrieved_data);
if (memcmp (retrieved_data, test_data, vec_len (retrieved_data)))
{
- result = (u32 *) f->head_chunk->data;
+ result = (u32 *) f_head_cptr (f)->data;
*result = 1;
_exit (0);
}
}
- result = (u32 *) f->head_chunk->data;
+ result = (u32 *) f_head_cptr (f)->data;
*result = 0;
vec_free (test_data);
usleep (1e3);
- result = (u32 *) f->head_chunk->data;
+ result = (u32 *) f_head_cptr (f)->data;
SFIFO_TEST (*result == 0, "slave reported no error");
vec_free (a->new_segment_indices);
a->segment_name = "fifo-test1";
a->segment_size = 256 << 10;
+ a->segment_type = SSVM_SEGMENT_PRIVATE;
rv = fifo_segment_create (sm, a);
return 0;
}
+static int
+approx_leq (uword a, uword b, u32 margin)
+{
+ if (a - margin <= b && b <= a)
+ return 1;
+ return 0;
+}
+
static int
sfifo_test_fifo_segment_prealloc (int verbose)
{
+ u32 max_pairs, pairs_req, free_space, pair_mem, overhead;
fifo_segment_create_args_t _a, *a = &_a;
fifo_segment_main_t *sm = &segment_main;
- u32 max_pairs, pairs_req, free_space, pair_mem;
- svm_fifo_t *f, *old;
+ svm_fifo_t *f, *tf, *old;
fifo_segment_t *fs;
int rv, alloc;
clib_memset (a, 0, sizeof (*a));
+ /* Overhead due to segment internal headers and offsets. The magic 384
+ * bytes are the fsh->n_reserved_bytes after seg init */
+ overhead = (8 << 10) + 384;
a->segment_name = "fifo-test-prealloc";
- a->segment_size = 256 << 10;
- a->segment_type = SSVM_SEGMENT_MEMFD;
+ a->segment_size = (256 << 10) + overhead;
+ a->segment_type = SSVM_SEGMENT_PRIVATE;
rv = fifo_segment_create (sm, a);
SFIFO_TEST (!rv, "svm_fifo_segment_create returned %d", rv);
* Prealloc chunks and headers
*/
free_space = fifo_segment_free_bytes (fs);
- SFIFO_TEST (free_space <= 256 << 10, "free space expected %u is %u",
+ SFIFO_TEST (free_space - 4096 <= 256 << 10, "free space expected %u is %u",
256 << 10, free_space);
rv = fifo_segment_prealloc_fifo_chunks (fs, 0, 4096, 50);
SFIFO_TEST (rv == 0, "chunk prealloc should work");
SFIFO_TEST (rv == 50, "prealloc chunks expected %u is %u", 50, rv);
rv = fifo_segment_free_bytes (fs);
free_space -= (sizeof (svm_fifo_chunk_t) + 4096) * 50;
- SFIFO_TEST (rv == free_space, "free space expected %u is %u", free_space,
- rv);
+ /* Memory alloc alignment accounts for the difference */
+ SFIFO_TEST (approx_leq (free_space, rv, 16), "free space expected %u is %u",
+ free_space, rv);
+ free_space = rv;
rv = fifo_segment_fl_chunk_bytes (fs);
SFIFO_TEST (rv == 4096 * 50, "chunk free space expected %u is %u",
4096 * 50, rv);
rv = fifo_segment_num_free_fifos (fs);
SFIFO_TEST (rv == 50, "prealloc fifo hdrs expected %u is %u", 50, rv);
rv = fifo_segment_free_bytes (fs);
- free_space -= sizeof (svm_fifo_t) * 50;
- SFIFO_TEST (rv == free_space, "free space expected %u is %u", free_space,
- rv);
+ free_space -= sizeof (svm_fifo_shared_t) * 50;
+ /* Memory alloc alignment accounts for the difference */
+ SFIFO_TEST (approx_leq (free_space, rv, 128), "free space expected %u is %u",
+ free_space, rv);
+ free_space = rv;
- fifo_segment_update_free_bytes (fs);
rv = fifo_segment_free_bytes (fs);
SFIFO_TEST (clib_abs (rv - (int) free_space) < 512,
"free space expected %u is %u", free_space, rv);
- f = fifo_segment_alloc_fifo (fs, 200 << 10, FIFO_SEGMENT_RX_FIFO);
+ /* Use all free chunk memory */
+ f = fifo_segment_alloc_fifo (fs, 100 << 10, FIFO_SEGMENT_RX_FIFO);
SFIFO_TEST (f != 0, "fifo allocated");
+ SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
+
+ tf = fifo_segment_alloc_fifo (fs, 100 << 10, FIFO_SEGMENT_RX_FIFO);
+ SFIFO_TEST (tf != 0, "fifo allocated");
+ SFIFO_TEST (svm_fifo_is_sane (tf), "fifo should be sane");
+
rv = fifo_segment_num_free_chunks (fs, 4096);
SFIFO_TEST (rv == 0, "prealloc chunks expected %u is %u", 0, rv);
rv = fifo_segment_fl_chunk_bytes (fs);
SFIFO_TEST (rv == 0, "chunk free space expected %u is %u", 0, rv);
- SFIFO_TEST (svm_fifo_is_sane (f), "fifo should be sane");
+
/*
* Multiple preallocs that consume the remaining space
*/
- fifo_segment_update_free_bytes (fs);
free_space = fifo_segment_free_bytes (fs);
pair_mem = 2 * (4096 + sizeof (*f) + sizeof (svm_fifo_chunk_t));
max_pairs = pairs_req = (free_space / pair_mem) - 1;
SFIFO_TEST (rv == max_pairs * 2, "prealloc chunks expected %u is %u",
max_pairs * 2, rv);
- fifo_segment_update_free_bytes (fs);
rv = fifo_segment_free_bytes (fs);
SFIFO_TEST (rv < 2 * pair_mem, "free bytes %u less than %u", rv,
2 * pair_mem);
* Cleanup
*/
fifo_segment_free_fifo (fs, old);
- close (fs->ssvm.fd);
+ fifo_segment_free_fifo (fs, tf);
fifo_segment_delete (sm, fs);
return 0;
}
int res = 0;
char *str;
- fifo_segment_main_init (&segment_main, HIGH_SEGMENT_BASEVA << 3, 5);
+ clib_warning ("high mem %lu", HIGH_SEGMENT_BASEVA);
+ fifo_segment_main_init (&segment_main, HIGH_SEGMENT_BASEVA, 5);
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "fifo1"))
res = sfifo_test_fifo_shrink (vm, input);
else if (unformat (input, "indirect"))
res = sfifo_test_fifo_indirect (vm, input);
+ else if (unformat (input, "zero"))
+ res = sfifo_test_fifo_make_rcv_wnd_zero (vm, input);
else if (unformat (input, "segment"))
res = sfifo_test_fifo_segment (vm, input);
else if (unformat (input, "all"))
if ((res = sfifo_test_fifo_indirect (vm, input)))
goto done;
+ if ((res = sfifo_test_fifo_make_rcv_wnd_zero (vm, input)))
+ goto done;
+
str = "all";
unformat_init_cstring (input, str);
if ((res = sfifo_test_fifo_segment (vm, input)))