X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Funittest%2Fsvm_fifo_test.c;h=87b85da89510ded745be325e63b6580f93824aeb;hb=0e6199dfa20d4c010bf3ac43e051f9f29c213478;hp=8579cec15b4602a32dfaf2cfe4222744d02fd020;hpb=f22f4e562e1b922cff036ef628b77fd2d479d015;p=vpp.git diff --git a/src/plugins/unittest/svm_fifo_test.c b/src/plugins/unittest/svm_fifo_test.c index 8579cec15b4..87b85da8951 100644 --- a/src/plugins/unittest/svm_fifo_test.c +++ b/src/plugins/unittest/svm_fifo_test.c @@ -2009,6 +2009,67 @@ sfifo_test_fifo_replay (vlib_main_t * vm, unformat_input_t * input) 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 @@ -2066,9 +2127,9 @@ sfifo_test_fifo_segment_fifo_grow (int verbose) 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"; @@ -2086,6 +2147,7 @@ sfifo_test_fifo_segment_fifo_grow (int verbose) * Alloc fifo */ fs = fifo_segment_get_segment (sm, a->new_segment_indices[0]); + fs->h->pct_first_alloc = 100; f = fifo_segment_alloc_fifo (fs, fifo_size, FIFO_SEGMENT_RX_FIFO); SFIFO_TEST (f != 0, "svm_fifo_segment_alloc_fifo"); @@ -2236,12 +2298,20 @@ sfifo_test_fifo_segment_fifo_grow (int verbose) 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); @@ -2259,15 +2329,17 @@ sfifo_test_fifo_segment_fifo_grow (int verbose) /* * Allocate fifo and try to grow beyond available space */ - f = fifo_segment_alloc_fifo (fs, fifo_size, FIFO_SEGMENT_RX_FIFO); + f = fifo_segment_alloc_fifo (fs, fifo_segment_free_bytes (fs), + FIFO_SEGMENT_RX_FIFO); /* Try to force fifo growth */ - svm_fifo_set_size (f, svm_fifo_size (f) + n_free_chunk_bytes); - 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); @@ -2451,7 +2523,7 @@ sfifo_test_fifo_segment_prealloc (int verbose) 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; @@ -2464,6 +2536,7 @@ sfifo_test_fifo_segment_prealloc (int verbose) rv = fifo_segment_create (sm, a); SFIFO_TEST (!rv, "svm_fifo_segment_create returned %d", rv); fs = fifo_segment_get_segment (sm, a->new_segment_indices[0]); + fs->h->pct_first_alloc = 100; /* * Prealloc chunks and headers @@ -2497,13 +2570,20 @@ sfifo_test_fifo_segment_prealloc (int verbose) 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 @@ -2558,6 +2638,7 @@ sfifo_test_fifo_segment_prealloc (int verbose) * Cleanup */ fifo_segment_free_fifo (fs, old); + fifo_segment_free_fifo (fs, tf); close (fs->ssvm.fd); fifo_segment_delete (sm, fs); return 0; @@ -2568,7 +2649,6 @@ sfifo_test_fifo_segment (vlib_main_t * vm, unformat_input_t * input) { int rv, verbose = 0; - fifo_segment_main_init (&segment_main, HIGH_SEGMENT_BASEVA, 5); while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "verbose")) @@ -2630,7 +2710,8 @@ svm_fifo_test (vlib_main_t * vm, unformat_input_t * input, int res = 0; char *str; - + clib_warning ("high mem %lu", HIGH_SEGMENT_BASEVA << 4); + fifo_segment_main_init (&segment_main, HIGH_SEGMENT_BASEVA << 4, 5); while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "fifo1")) @@ -2657,6 +2738,8 @@ svm_fifo_test (vlib_main_t * vm, unformat_input_t * input, 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")) @@ -2721,6 +2804,9 @@ svm_fifo_test (vlib_main_t * vm, unformat_input_t * input, 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)))