4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include <sys/queue.h>
43 #include <rte_common.h>
45 #include <rte_memory.h>
46 #include <rte_memzone.h>
47 #include <rte_launch.h>
48 #include <rte_cycles.h>
49 #include <rte_tailq.h>
51 #include <rte_per_lcore.h>
52 #include <rte_lcore.h>
53 #include <rte_atomic.h>
54 #include <rte_branch_prediction.h>
55 #include <rte_malloc.h>
57 #include <rte_random.h>
58 #include <rte_common.h>
59 #include <rte_errno.h>
60 #include <rte_hexdump.h>
62 #include <cmdline_parse.h>
70 * #. Basic tests: done on one core:
72 * - Using single producer/single consumer functions:
74 * - Enqueue one object, two objects, MAX_BULK objects
75 * - Dequeue one object, two objects, MAX_BULK objects
76 * - Check that dequeued pointers are correct
78 * - Using multi producers/multi consumers functions:
80 * - Enqueue one object, two objects, MAX_BULK objects
81 * - Dequeue one object, two objects, MAX_BULK objects
82 * - Check that dequeued pointers are correct
84 * - Test watermark and default bulk enqueue/dequeue:
87 * - Set default bulk value
88 * - Enqueue objects, check that -EDQUOT is returned when
89 * watermark is exceeded
90 * - Check that dequeued pointers are correct
92 * #. Check live watermark change
94 * - Start a loop on another lcore that will enqueue and dequeue
95 * objects in a ring. It will monitor the value of watermark.
96 * - At the same time, change the watermark on the master lcore.
97 * - The slave lcore will check that watermark changes from 16 to 32.
99 * #. Performance tests.
101 * Tests done in test_ring_perf.c
104 #define RING_SIZE 4096
109 static rte_atomic32_t synchro;
111 static struct rte_ring *r;
113 #define TEST_RING_VERIFY(exp) \
115 printf("error at %s:%d\tcondition " #exp " failed\n", \
116 __func__, __LINE__); \
121 #define TEST_RING_FULL_EMTPY_ITER 8
124 check_live_watermark_change(__attribute__((unused)) void *dummy)
126 uint64_t hz = rte_get_timer_hz();
127 void *obj_table[MAX_BULK];
128 unsigned watermark, watermark_old = 16;
129 uint64_t cur_time, end_time;
134 /* init the object table */
135 memset(obj_table, 0, sizeof(obj_table));
136 end_time = rte_get_timer_cycles() + (hz * 2);
138 /* check that bulk and watermark are 4 and 32 (respectively) */
141 /* add in ring until we reach watermark */
143 for (i = 0; i < 16; i ++) {
146 ret = rte_ring_enqueue_bulk(r, obj_table, count);
149 if (ret != -EDQUOT) {
150 printf("Cannot enqueue objects, or watermark not "
151 "reached (ret=%d)\n", ret);
155 /* read watermark, the only change allowed is from 16 to 32 */
156 watermark = r->prod.watermark;
157 if (watermark != watermark_old &&
158 (watermark_old != 16 || watermark != 32)) {
159 printf("Bad watermark change %u -> %u\n", watermark_old,
163 watermark_old = watermark;
165 /* dequeue objects from ring */
167 ret = rte_ring_dequeue_bulk(r, obj_table, count);
169 printf("Cannot dequeue (ret=%d)\n", ret);
174 cur_time = rte_get_timer_cycles();
175 diff = end_time - cur_time;
178 if (watermark_old != 32 ) {
179 printf(" watermark was not updated (wm=%u)\n",
188 test_live_watermark_change(void)
190 unsigned lcore_id = rte_lcore_id();
191 unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1);
193 printf("Test watermark live modification\n");
194 rte_ring_set_water_mark(r, 16);
196 /* launch a thread that will enqueue and dequeue, checking
197 * watermark and quota */
198 rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2);
201 rte_ring_set_water_mark(r, 32);
204 if (rte_eal_wait_lcore(lcore_id2) < 0)
210 /* Test for catch on invalid watermark values */
212 test_set_watermark( void ){
216 struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex");
218 printf( " ring lookup failed\n" );
221 count = r->prod.size*2;
222 setwm = rte_ring_set_water_mark(r, count);
223 if (setwm != -EINVAL){
224 printf("Test failed to detect invalid watermark count value\n");
229 rte_ring_set_water_mark(r, count);
230 if (r->prod.watermark != r->prod.size) {
231 printf("Test failed to detect invalid watermark count value\n");
241 * helper routine for test_ring_basic
244 test_ring_basic_full_empty(void * const src[], void *dst[])
247 const unsigned rsz = RING_SIZE - 1;
249 printf("Basic full/empty test\n");
251 for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) {
253 /* random shift in the ring */
254 rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
255 printf("%s: iteration %u, random shift: %u;\n",
257 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
259 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand));
262 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
264 TEST_RING_VERIFY(0 == rte_ring_free_count(r));
265 TEST_RING_VERIFY(rsz == rte_ring_count(r));
266 TEST_RING_VERIFY(rte_ring_full(r));
267 TEST_RING_VERIFY(0 == rte_ring_empty(r));
270 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz));
271 TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
272 TEST_RING_VERIFY(0 == rte_ring_count(r));
273 TEST_RING_VERIFY(0 == rte_ring_full(r));
274 TEST_RING_VERIFY(rte_ring_empty(r));
277 TEST_RING_VERIFY(0 == memcmp(src, dst, rsz));
284 test_ring_basic(void)
286 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
288 unsigned i, num_elems;
290 /* alloc dummy object pointers */
291 src = malloc(RING_SIZE*2*sizeof(void *));
295 for (i = 0; i < RING_SIZE*2 ; i++) {
296 src[i] = (void *)(unsigned long)i;
300 /* alloc some room for copied objects */
301 dst = malloc(RING_SIZE*2*sizeof(void *));
305 memset(dst, 0, RING_SIZE*2*sizeof(void *));
308 printf("enqueue 1 obj\n");
309 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1);
314 printf("enqueue 2 objs\n");
315 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2);
320 printf("enqueue MAX_BULK objs\n");
321 ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK);
326 printf("dequeue 1 obj\n");
327 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1);
332 printf("dequeue 2 objs\n");
333 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2);
338 printf("dequeue MAX_BULK objs\n");
339 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK);
345 if (memcmp(src, dst, cur_dst - dst)) {
346 rte_hexdump("src", src, cur_src - src);
347 rte_hexdump("dst", dst, cur_dst - dst);
348 printf("data after dequeue is not the same\n");
354 printf("enqueue 1 obj\n");
355 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1);
360 printf("enqueue 2 objs\n");
361 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2);
366 printf("enqueue MAX_BULK objs\n");
367 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
372 printf("dequeue 1 obj\n");
373 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1);
378 printf("dequeue 2 objs\n");
379 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2);
384 printf("dequeue MAX_BULK objs\n");
385 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
391 if (memcmp(src, dst, cur_dst - dst)) {
392 rte_hexdump("src", src, cur_src - src);
393 rte_hexdump("dst", dst, cur_dst - dst);
394 printf("data after dequeue is not the same\n");
400 printf("fill and empty the ring\n");
401 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
402 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
406 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
413 if (memcmp(src, dst, cur_dst - dst)) {
414 rte_hexdump("src", src, cur_src - src);
415 rte_hexdump("dst", dst, cur_dst - dst);
416 printf("data after dequeue is not the same\n");
420 if (test_ring_basic_full_empty(src, dst) != 0)
426 printf("test watermark and default bulk enqueue / dequeue\n");
427 rte_ring_set_water_mark(r, 20);
433 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
434 cur_src += num_elems;
436 printf("Cannot enqueue\n");
439 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
440 cur_src += num_elems;
441 if (ret != -EDQUOT) {
442 printf("Watermark not exceeded\n");
445 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
446 cur_dst += num_elems;
448 printf("Cannot dequeue\n");
451 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
452 cur_dst += num_elems;
454 printf("Cannot dequeue2\n");
459 if (memcmp(src, dst, cur_dst - dst)) {
460 rte_hexdump("src", src, cur_src - src);
461 rte_hexdump("dst", dst, cur_dst - dst);
462 printf("data after dequeue is not the same\n");
469 ret = rte_ring_mp_enqueue(r, cur_src);
473 ret = rte_ring_mc_dequeue(r, cur_dst);
492 test_ring_burst_basic(void)
494 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
498 /* alloc dummy object pointers */
499 src = malloc(RING_SIZE*2*sizeof(void *));
503 for (i = 0; i < RING_SIZE*2 ; i++) {
504 src[i] = (void *)(unsigned long)i;
508 /* alloc some room for copied objects */
509 dst = malloc(RING_SIZE*2*sizeof(void *));
513 memset(dst, 0, RING_SIZE*2*sizeof(void *));
516 printf("Test SP & SC basic functions \n");
517 printf("enqueue 1 obj\n");
518 ret = rte_ring_sp_enqueue_burst(r, cur_src, 1);
520 if ((ret & RTE_RING_SZ_MASK) != 1)
523 printf("enqueue 2 objs\n");
524 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
526 if ((ret & RTE_RING_SZ_MASK) != 2)
529 printf("enqueue MAX_BULK objs\n");
530 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK) ;
532 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
535 printf("dequeue 1 obj\n");
536 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 1) ;
538 if ((ret & RTE_RING_SZ_MASK) != 1)
541 printf("dequeue 2 objs\n");
542 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
544 if ((ret & RTE_RING_SZ_MASK) != 2)
547 printf("dequeue MAX_BULK objs\n");
548 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
550 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
554 if (memcmp(src, dst, cur_dst - dst)) {
555 rte_hexdump("src", src, cur_src - src);
556 rte_hexdump("dst", dst, cur_dst - dst);
557 printf("data after dequeue is not the same\n");
564 printf("Test enqueue without enough memory space \n");
565 for (i = 0; i< (RING_SIZE/MAX_BULK - 1); i++) {
566 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
568 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK) {
573 printf("Enqueue 2 objects, free entries = MAX_BULK - 2 \n");
574 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
576 if ((ret & RTE_RING_SZ_MASK) != 2)
579 printf("Enqueue the remaining entries = MAX_BULK - 2 \n");
580 /* Always one free entry left */
581 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
582 cur_src += MAX_BULK - 3;
583 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
586 printf("Test if ring is full \n");
587 if (rte_ring_full(r) != 1)
590 printf("Test enqueue for a full entry \n");
591 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
592 if ((ret & RTE_RING_SZ_MASK) != 0)
595 printf("Test dequeue without enough objects \n");
596 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
597 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
599 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
603 /* Available memory space for the exact MAX_BULK entries */
604 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
606 if ((ret & RTE_RING_SZ_MASK) != 2)
609 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
610 cur_dst += MAX_BULK - 3;
611 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
614 printf("Test if ring is empty \n");
615 /* Check if ring is empty */
616 if (1 != rte_ring_empty(r))
620 if (memcmp(src, dst, cur_dst - dst)) {
621 rte_hexdump("src", src, cur_src - src);
622 rte_hexdump("dst", dst, cur_dst - dst);
623 printf("data after dequeue is not the same\n");
630 printf("Test MP & MC basic functions \n");
632 printf("enqueue 1 obj\n");
633 ret = rte_ring_mp_enqueue_burst(r, cur_src, 1);
635 if ((ret & RTE_RING_SZ_MASK) != 1)
638 printf("enqueue 2 objs\n");
639 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
641 if ((ret & RTE_RING_SZ_MASK) != 2)
644 printf("enqueue MAX_BULK objs\n");
645 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
647 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
650 printf("dequeue 1 obj\n");
651 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 1);
653 if ((ret & RTE_RING_SZ_MASK) != 1)
656 printf("dequeue 2 objs\n");
657 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
659 if ((ret & RTE_RING_SZ_MASK) != 2)
662 printf("dequeue MAX_BULK objs\n");
663 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
665 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
669 if (memcmp(src, dst, cur_dst - dst)) {
670 rte_hexdump("src", src, cur_src - src);
671 rte_hexdump("dst", dst, cur_dst - dst);
672 printf("data after dequeue is not the same\n");
679 printf("fill and empty the ring\n");
680 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
681 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
683 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
685 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
687 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
692 if (memcmp(src, dst, cur_dst - dst)) {
693 rte_hexdump("src", src, cur_src - src);
694 rte_hexdump("dst", dst, cur_dst - dst);
695 printf("data after dequeue is not the same\n");
702 printf("Test enqueue without enough memory space \n");
703 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
704 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
706 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
710 /* Available memory space for the exact MAX_BULK objects */
711 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
713 if ((ret & RTE_RING_SZ_MASK) != 2)
716 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
717 cur_src += MAX_BULK - 3;
718 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
722 printf("Test dequeue without enough objects \n");
723 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
724 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
726 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
730 /* Available objects - the exact MAX_BULK */
731 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
733 if ((ret & RTE_RING_SZ_MASK) != 2)
736 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
737 cur_dst += MAX_BULK - 3;
738 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
742 if (memcmp(src, dst, cur_dst - dst)) {
743 rte_hexdump("src", src, cur_src - src);
744 rte_hexdump("dst", dst, cur_dst - dst);
745 printf("data after dequeue is not the same\n");
752 printf("Covering rte_ring_enqueue_burst functions \n");
754 ret = rte_ring_enqueue_burst(r, cur_src, 2);
756 if ((ret & RTE_RING_SZ_MASK) != 2)
759 ret = rte_ring_dequeue_burst(r, cur_dst, 2);
764 /* Free memory before test completed */
780 test_ring_stats(void)
783 #ifndef RTE_LIBRTE_RING_DEBUG
784 printf("Enable RTE_LIBRTE_RING_DEBUG to test ring stats.\n");
787 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
790 unsigned num_items = 0;
791 unsigned failed_enqueue_ops = 0;
792 unsigned failed_enqueue_items = 0;
793 unsigned failed_dequeue_ops = 0;
794 unsigned failed_dequeue_items = 0;
795 unsigned last_enqueue_ops = 0;
796 unsigned last_enqueue_items = 0;
797 unsigned last_quota_ops = 0;
798 unsigned last_quota_items = 0;
799 unsigned lcore_id = rte_lcore_id();
800 struct rte_ring_debug_stats *ring_stats = &r->stats[lcore_id];
802 printf("Test the ring stats.\n");
804 /* Reset the watermark in case it was set in another test. */
805 rte_ring_set_water_mark(r, 0);
807 /* Reset the ring stats. */
808 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
810 /* Allocate some dummy object pointers. */
811 src = malloc(RING_SIZE*2*sizeof(void *));
815 for (i = 0; i < RING_SIZE*2 ; i++) {
816 src[i] = (void *)(unsigned long)i;
819 /* Allocate some memory for copied objects. */
820 dst = malloc(RING_SIZE*2*sizeof(void *));
824 memset(dst, 0, RING_SIZE*2*sizeof(void *));
826 /* Set the head and tail pointers. */
830 /* Do Enqueue tests. */
831 printf("Test the dequeue stats.\n");
833 /* Fill the ring up to RING_SIZE -1. */
834 printf("Fill the ring.\n");
835 for (i = 0; i< (RING_SIZE/MAX_BULK); i++) {
836 rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
840 /* Adjust for final enqueue = MAX_BULK -1. */
843 printf("Verify that the ring is full.\n");
844 if (rte_ring_full(r) != 1)
848 printf("Verify the enqueue success stats.\n");
849 /* Stats should match above enqueue operations to fill the ring. */
850 if (ring_stats->enq_success_bulk != (RING_SIZE/MAX_BULK))
853 /* Current max objects is RING_SIZE -1. */
854 if (ring_stats->enq_success_objs != RING_SIZE -1)
857 /* Shouldn't have any failures yet. */
858 if (ring_stats->enq_fail_bulk != 0)
860 if (ring_stats->enq_fail_objs != 0)
864 printf("Test stats for SP burst enqueue to a full ring.\n");
866 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
867 if ((ret & RTE_RING_SZ_MASK) != 0)
870 failed_enqueue_ops += 1;
871 failed_enqueue_items += num_items;
873 /* The enqueue should have failed. */
874 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
876 if (ring_stats->enq_fail_objs != failed_enqueue_items)
880 printf("Test stats for SP bulk enqueue to a full ring.\n");
882 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
886 failed_enqueue_ops += 1;
887 failed_enqueue_items += num_items;
889 /* The enqueue should have failed. */
890 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
892 if (ring_stats->enq_fail_objs != failed_enqueue_items)
896 printf("Test stats for MP burst enqueue to a full ring.\n");
898 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
899 if ((ret & RTE_RING_SZ_MASK) != 0)
902 failed_enqueue_ops += 1;
903 failed_enqueue_items += num_items;
905 /* The enqueue should have failed. */
906 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
908 if (ring_stats->enq_fail_objs != failed_enqueue_items)
912 printf("Test stats for MP bulk enqueue to a full ring.\n");
914 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
918 failed_enqueue_ops += 1;
919 failed_enqueue_items += num_items;
921 /* The enqueue should have failed. */
922 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
924 if (ring_stats->enq_fail_objs != failed_enqueue_items)
928 /* Do Dequeue tests. */
929 printf("Test the dequeue stats.\n");
931 printf("Empty the ring.\n");
932 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
933 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
937 /* There was only RING_SIZE -1 objects to dequeue. */
940 printf("Verify ring is empty.\n");
941 if (1 != rte_ring_empty(r))
944 printf("Verify the dequeue success stats.\n");
945 /* Stats should match above dequeue operations. */
946 if (ring_stats->deq_success_bulk != (RING_SIZE/MAX_BULK))
949 /* Objects dequeued is RING_SIZE -1. */
950 if (ring_stats->deq_success_objs != RING_SIZE -1)
953 /* Shouldn't have any dequeue failure stats yet. */
954 if (ring_stats->deq_fail_bulk != 0)
957 printf("Test stats for SC burst dequeue with an empty ring.\n");
959 ret = rte_ring_sc_dequeue_burst(r, cur_dst, num_items);
960 if ((ret & RTE_RING_SZ_MASK) != 0)
963 failed_dequeue_ops += 1;
964 failed_dequeue_items += num_items;
966 /* The dequeue should have failed. */
967 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
969 if (ring_stats->deq_fail_objs != failed_dequeue_items)
973 printf("Test stats for SC bulk dequeue with an empty ring.\n");
975 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, num_items);
979 failed_dequeue_ops += 1;
980 failed_dequeue_items += num_items;
982 /* The dequeue should have failed. */
983 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
985 if (ring_stats->deq_fail_objs != failed_dequeue_items)
989 printf("Test stats for MC burst dequeue with an empty ring.\n");
991 ret = rte_ring_mc_dequeue_burst(r, cur_dst, num_items);
992 if ((ret & RTE_RING_SZ_MASK) != 0)
994 failed_dequeue_ops += 1;
995 failed_dequeue_items += num_items;
997 /* The dequeue should have failed. */
998 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
1000 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1004 printf("Test stats for MC bulk dequeue with an empty ring.\n");
1006 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, num_items);
1010 failed_dequeue_ops += 1;
1011 failed_dequeue_items += num_items;
1013 /* The dequeue should have failed. */
1014 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
1016 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1020 printf("Test total enqueue/dequeue stats.\n");
1021 /* At this point the enqueue and dequeue stats should be the same. */
1022 if (ring_stats->enq_success_bulk != ring_stats->deq_success_bulk)
1024 if (ring_stats->enq_success_objs != ring_stats->deq_success_objs)
1026 if (ring_stats->enq_fail_bulk != ring_stats->deq_fail_bulk)
1028 if (ring_stats->enq_fail_objs != ring_stats->deq_fail_objs)
1032 /* Watermark Tests. */
1033 printf("Test the watermark/quota stats.\n");
1035 printf("Verify the initial watermark stats.\n");
1036 /* Watermark stats should be 0 since there is no watermark. */
1037 if (ring_stats->enq_quota_bulk != 0)
1039 if (ring_stats->enq_quota_objs != 0)
1042 /* Set a watermark. */
1043 rte_ring_set_water_mark(r, 16);
1045 /* Reset pointers. */
1049 last_enqueue_ops = ring_stats->enq_success_bulk;
1050 last_enqueue_items = ring_stats->enq_success_objs;
1053 printf("Test stats for SP burst enqueue below watermark.\n");
1055 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1056 if ((ret & RTE_RING_SZ_MASK) != num_items)
1059 /* Watermark stats should still be 0. */
1060 if (ring_stats->enq_quota_bulk != 0)
1062 if (ring_stats->enq_quota_objs != 0)
1065 /* Success stats should have increased. */
1066 if (ring_stats->enq_success_bulk != last_enqueue_ops + 1)
1068 if (ring_stats->enq_success_objs != last_enqueue_items + num_items)
1071 last_enqueue_ops = ring_stats->enq_success_bulk;
1072 last_enqueue_items = ring_stats->enq_success_objs;
1075 printf("Test stats for SP burst enqueue at watermark.\n");
1077 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1078 if ((ret & RTE_RING_SZ_MASK) != num_items)
1081 /* Watermark stats should have changed. */
1082 if (ring_stats->enq_quota_bulk != 1)
1084 if (ring_stats->enq_quota_objs != num_items)
1087 last_quota_ops = ring_stats->enq_quota_bulk;
1088 last_quota_items = ring_stats->enq_quota_objs;
1091 printf("Test stats for SP burst enqueue above watermark.\n");
1093 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1094 if ((ret & RTE_RING_SZ_MASK) != num_items)
1097 /* Watermark stats should have changed. */
1098 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1100 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1103 last_quota_ops = ring_stats->enq_quota_bulk;
1104 last_quota_items = ring_stats->enq_quota_objs;
1107 printf("Test stats for MP burst enqueue above watermark.\n");
1109 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
1110 if ((ret & RTE_RING_SZ_MASK) != num_items)
1113 /* Watermark stats should have changed. */
1114 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1116 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1119 last_quota_ops = ring_stats->enq_quota_bulk;
1120 last_quota_items = ring_stats->enq_quota_objs;
1123 printf("Test stats for SP bulk enqueue above watermark.\n");
1125 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
1129 /* Watermark stats should have changed. */
1130 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1132 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1135 last_quota_ops = ring_stats->enq_quota_bulk;
1136 last_quota_items = ring_stats->enq_quota_objs;
1139 printf("Test stats for MP bulk enqueue above watermark.\n");
1141 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
1145 /* Watermark stats should have changed. */
1146 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1148 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1151 printf("Test watermark success stats.\n");
1152 /* Success stats should be same as last non-watermarked enqueue. */
1153 if (ring_stats->enq_success_bulk != last_enqueue_ops)
1155 if (ring_stats->enq_success_objs != last_enqueue_items)
1161 /* Empty the ring. */
1162 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
1163 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
1164 cur_dst += MAX_BULK;
1167 /* Reset the watermark. */
1168 rte_ring_set_water_mark(r, 0);
1170 /* Reset the ring stats. */
1171 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
1173 /* Free memory before test completed */
1190 * it will always fail to create ring with a wrong ring size number in this function
1193 test_ring_creation_with_wrong_size(void)
1195 struct rte_ring * rp = NULL;
1197 /* Test if ring size is not power of 2 */
1198 rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0);
1203 /* Test if ring size is exceeding the limit */
1204 rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0);
1212 * it tests if it would always fail to create ring with an used ring name
1215 test_ring_creation_with_an_used_name(void)
1217 struct rte_ring * rp;
1219 rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1227 * Test to if a non-power of 2 count causes the create
1228 * function to fail correctly
1231 test_create_count_odd(void)
1233 struct rte_ring *r = rte_ring_create("test_ring_count",
1234 4097, SOCKET_ID_ANY, 0 );
1242 test_lookup_null(void)
1244 struct rte_ring *rlp = rte_ring_lookup("ring_not_found");
1246 if (rte_errno != ENOENT){
1247 printf( "test failed to returnn error on null pointer\n");
1254 * it tests some more basic ring operations
1257 test_ring_basic_ex(void)
1261 struct rte_ring * rp;
1264 obj = (void **)rte_zmalloc("test_ring_basic_ex_malloc", (RING_SIZE * sizeof(void *)), 0);
1266 printf("test_ring_basic_ex fail to rte_malloc\n");
1270 rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY,
1271 RING_F_SP_ENQ | RING_F_SC_DEQ);
1273 printf("test_ring_basic_ex fail to create ring\n");
1277 if (rte_ring_lookup("test_ring_basic_ex") != rp) {
1281 if (rte_ring_empty(rp) != 1) {
1282 printf("test_ring_basic_ex ring is not empty but it should be\n");
1286 printf("%u ring entries are now free\n", rte_ring_free_count(rp));
1288 for (i = 0; i < RING_SIZE; i ++) {
1289 rte_ring_enqueue(rp, obj[i]);
1292 if (rte_ring_full(rp) != 1) {
1293 printf("test_ring_basic_ex ring is not full but it should be\n");
1297 for (i = 0; i < RING_SIZE; i ++) {
1298 rte_ring_dequeue(rp, &obj[i]);
1301 if (rte_ring_empty(rp) != 1) {
1302 printf("test_ring_basic_ex ring is not empty but it should be\n");
1306 /* Covering the ring burst operation */
1307 ret = rte_ring_enqueue_burst(rp, obj, 2);
1308 if ((ret & RTE_RING_SZ_MASK) != 2) {
1309 printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n");
1313 ret = rte_ring_dequeue_burst(rp, obj, 2);
1315 printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n");
1330 /* some more basic operations */
1331 if (test_ring_basic_ex() < 0)
1334 rte_atomic32_init(&synchro);
1337 r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1341 /* retrieve the ring from its name */
1342 if (rte_ring_lookup("test") != r) {
1343 printf("Cannot lookup ring from its name\n");
1347 /* burst operations */
1348 if (test_ring_burst_basic() < 0)
1351 /* basic operations */
1352 if (test_ring_basic() < 0)
1356 if (test_ring_stats() < 0)
1359 /* basic operations */
1360 if (test_live_watermark_change() < 0)
1363 if ( test_set_watermark() < 0){
1364 printf ("Test failed to detect invalid parameter\n");
1368 printf ( "Test detected forced bad watermark values\n");
1370 if ( test_create_count_odd() < 0){
1371 printf ("Test failed to detect odd count\n");
1375 printf ( "Test detected odd count\n");
1377 if ( test_lookup_null() < 0){
1378 printf ("Test failed to detect NULL ring lookup\n");
1382 printf ( "Test detected NULL ring lookup \n");
1384 /* test of creating ring with wrong size */
1385 if (test_ring_creation_with_wrong_size() < 0)
1388 /* test of creation ring with an used name */
1389 if (test_ring_creation_with_an_used_name() < 0)
1392 /* dump the ring status */
1393 rte_ring_list_dump();