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>
50 #include <rte_per_lcore.h>
51 #include <rte_lcore.h>
52 #include <rte_atomic.h>
53 #include <rte_branch_prediction.h>
54 #include <rte_malloc.h>
56 #include <rte_random.h>
57 #include <rte_common.h>
58 #include <rte_errno.h>
59 #include <rte_hexdump.h>
67 * #. Basic tests: done on one core:
69 * - Using single producer/single consumer functions:
71 * - Enqueue one object, two objects, MAX_BULK objects
72 * - Dequeue one object, two objects, MAX_BULK objects
73 * - Check that dequeued pointers are correct
75 * - Using multi producers/multi consumers functions:
77 * - Enqueue one object, two objects, MAX_BULK objects
78 * - Dequeue one object, two objects, MAX_BULK objects
79 * - Check that dequeued pointers are correct
81 * - Test watermark and default bulk enqueue/dequeue:
84 * - Set default bulk value
85 * - Enqueue objects, check that -EDQUOT is returned when
86 * watermark is exceeded
87 * - Check that dequeued pointers are correct
89 * #. Check live watermark change
91 * - Start a loop on another lcore that will enqueue and dequeue
92 * objects in a ring. It will monitor the value of watermark.
93 * - At the same time, change the watermark on the master lcore.
94 * - The slave lcore will check that watermark changes from 16 to 32.
96 * #. Performance tests.
98 * Tests done in test_ring_perf.c
101 #define RING_SIZE 4096
106 static rte_atomic32_t synchro;
108 static struct rte_ring *r;
110 #define TEST_RING_VERIFY(exp) \
112 printf("error at %s:%d\tcondition " #exp " failed\n", \
113 __func__, __LINE__); \
114 rte_ring_dump(stdout, r); \
118 #define TEST_RING_FULL_EMTPY_ITER 8
121 check_live_watermark_change(__attribute__((unused)) void *dummy)
123 uint64_t hz = rte_get_timer_hz();
124 void *obj_table[MAX_BULK];
125 unsigned watermark, watermark_old = 16;
126 uint64_t cur_time, end_time;
131 /* init the object table */
132 memset(obj_table, 0, sizeof(obj_table));
133 end_time = rte_get_timer_cycles() + (hz * 2);
135 /* check that bulk and watermark are 4 and 32 (respectively) */
138 /* add in ring until we reach watermark */
140 for (i = 0; i < 16; i ++) {
143 ret = rte_ring_enqueue_bulk(r, obj_table, count);
146 if (ret != -EDQUOT) {
147 printf("Cannot enqueue objects, or watermark not "
148 "reached (ret=%d)\n", ret);
152 /* read watermark, the only change allowed is from 16 to 32 */
153 watermark = r->prod.watermark;
154 if (watermark != watermark_old &&
155 (watermark_old != 16 || watermark != 32)) {
156 printf("Bad watermark change %u -> %u\n", watermark_old,
160 watermark_old = watermark;
162 /* dequeue objects from ring */
164 ret = rte_ring_dequeue_bulk(r, obj_table, count);
166 printf("Cannot dequeue (ret=%d)\n", ret);
171 cur_time = rte_get_timer_cycles();
172 diff = end_time - cur_time;
175 if (watermark_old != 32 ) {
176 printf(" watermark was not updated (wm=%u)\n",
185 test_live_watermark_change(void)
187 unsigned lcore_id = rte_lcore_id();
188 unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1);
190 printf("Test watermark live modification\n");
191 rte_ring_set_water_mark(r, 16);
193 /* launch a thread that will enqueue and dequeue, checking
194 * watermark and quota */
195 rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2);
198 rte_ring_set_water_mark(r, 32);
201 if (rte_eal_wait_lcore(lcore_id2) < 0)
207 /* Test for catch on invalid watermark values */
209 test_set_watermark( void ){
213 struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex");
215 printf( " ring lookup failed\n" );
218 count = r->prod.size*2;
219 setwm = rte_ring_set_water_mark(r, count);
220 if (setwm != -EINVAL){
221 printf("Test failed to detect invalid watermark count value\n");
226 rte_ring_set_water_mark(r, count);
227 if (r->prod.watermark != r->prod.size) {
228 printf("Test failed to detect invalid watermark count value\n");
238 * helper routine for test_ring_basic
241 test_ring_basic_full_empty(void * const src[], void *dst[])
244 const unsigned rsz = RING_SIZE - 1;
246 printf("Basic full/empty test\n");
248 for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) {
250 /* random shift in the ring */
251 rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
252 printf("%s: iteration %u, random shift: %u;\n",
254 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
256 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand));
259 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
261 TEST_RING_VERIFY(0 == rte_ring_free_count(r));
262 TEST_RING_VERIFY(rsz == rte_ring_count(r));
263 TEST_RING_VERIFY(rte_ring_full(r));
264 TEST_RING_VERIFY(0 == rte_ring_empty(r));
267 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz));
268 TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
269 TEST_RING_VERIFY(0 == rte_ring_count(r));
270 TEST_RING_VERIFY(0 == rte_ring_full(r));
271 TEST_RING_VERIFY(rte_ring_empty(r));
274 TEST_RING_VERIFY(0 == memcmp(src, dst, rsz));
275 rte_ring_dump(stdout, r);
281 test_ring_basic(void)
283 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
285 unsigned i, num_elems;
287 /* alloc dummy object pointers */
288 src = malloc(RING_SIZE*2*sizeof(void *));
292 for (i = 0; i < RING_SIZE*2 ; i++) {
293 src[i] = (void *)(unsigned long)i;
297 /* alloc some room for copied objects */
298 dst = malloc(RING_SIZE*2*sizeof(void *));
302 memset(dst, 0, RING_SIZE*2*sizeof(void *));
305 printf("enqueue 1 obj\n");
306 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1);
311 printf("enqueue 2 objs\n");
312 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2);
317 printf("enqueue MAX_BULK objs\n");
318 ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK);
323 printf("dequeue 1 obj\n");
324 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1);
329 printf("dequeue 2 objs\n");
330 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2);
335 printf("dequeue MAX_BULK objs\n");
336 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK);
342 if (memcmp(src, dst, cur_dst - dst)) {
343 rte_hexdump(stdout, "src", src, cur_src - src);
344 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
345 printf("data after dequeue is not the same\n");
351 printf("enqueue 1 obj\n");
352 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1);
357 printf("enqueue 2 objs\n");
358 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2);
363 printf("enqueue MAX_BULK objs\n");
364 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
369 printf("dequeue 1 obj\n");
370 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1);
375 printf("dequeue 2 objs\n");
376 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2);
381 printf("dequeue MAX_BULK objs\n");
382 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
388 if (memcmp(src, dst, cur_dst - dst)) {
389 rte_hexdump(stdout, "src", src, cur_src - src);
390 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
391 printf("data after dequeue is not the same\n");
397 printf("fill and empty the ring\n");
398 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
399 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
403 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
410 if (memcmp(src, dst, cur_dst - dst)) {
411 rte_hexdump(stdout, "src", src, cur_src - src);
412 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
413 printf("data after dequeue is not the same\n");
417 if (test_ring_basic_full_empty(src, dst) != 0)
423 printf("test watermark and default bulk enqueue / dequeue\n");
424 rte_ring_set_water_mark(r, 20);
430 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
431 cur_src += num_elems;
433 printf("Cannot enqueue\n");
436 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
437 cur_src += num_elems;
438 if (ret != -EDQUOT) {
439 printf("Watermark not exceeded\n");
442 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
443 cur_dst += num_elems;
445 printf("Cannot dequeue\n");
448 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
449 cur_dst += num_elems;
451 printf("Cannot dequeue2\n");
456 if (memcmp(src, dst, cur_dst - dst)) {
457 rte_hexdump(stdout, "src", src, cur_src - src);
458 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
459 printf("data after dequeue is not the same\n");
466 ret = rte_ring_mp_enqueue(r, cur_src);
470 ret = rte_ring_mc_dequeue(r, cur_dst);
485 test_ring_burst_basic(void)
487 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
491 /* alloc dummy object pointers */
492 src = malloc(RING_SIZE*2*sizeof(void *));
496 for (i = 0; i < RING_SIZE*2 ; i++) {
497 src[i] = (void *)(unsigned long)i;
501 /* alloc some room for copied objects */
502 dst = malloc(RING_SIZE*2*sizeof(void *));
506 memset(dst, 0, RING_SIZE*2*sizeof(void *));
509 printf("Test SP & SC basic functions \n");
510 printf("enqueue 1 obj\n");
511 ret = rte_ring_sp_enqueue_burst(r, cur_src, 1);
513 if ((ret & RTE_RING_SZ_MASK) != 1)
516 printf("enqueue 2 objs\n");
517 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
519 if ((ret & RTE_RING_SZ_MASK) != 2)
522 printf("enqueue MAX_BULK objs\n");
523 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK) ;
525 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
528 printf("dequeue 1 obj\n");
529 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 1) ;
531 if ((ret & RTE_RING_SZ_MASK) != 1)
534 printf("dequeue 2 objs\n");
535 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
537 if ((ret & RTE_RING_SZ_MASK) != 2)
540 printf("dequeue MAX_BULK objs\n");
541 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
543 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
547 if (memcmp(src, dst, cur_dst - dst)) {
548 rte_hexdump(stdout, "src", src, cur_src - src);
549 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
550 printf("data after dequeue is not the same\n");
557 printf("Test enqueue without enough memory space \n");
558 for (i = 0; i< (RING_SIZE/MAX_BULK - 1); i++) {
559 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
561 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK) {
566 printf("Enqueue 2 objects, free entries = MAX_BULK - 2 \n");
567 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
569 if ((ret & RTE_RING_SZ_MASK) != 2)
572 printf("Enqueue the remaining entries = MAX_BULK - 2 \n");
573 /* Always one free entry left */
574 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
575 cur_src += MAX_BULK - 3;
576 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
579 printf("Test if ring is full \n");
580 if (rte_ring_full(r) != 1)
583 printf("Test enqueue for a full entry \n");
584 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
585 if ((ret & RTE_RING_SZ_MASK) != 0)
588 printf("Test dequeue without enough objects \n");
589 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
590 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
592 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
596 /* Available memory space for the exact MAX_BULK entries */
597 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
599 if ((ret & RTE_RING_SZ_MASK) != 2)
602 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
603 cur_dst += MAX_BULK - 3;
604 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
607 printf("Test if ring is empty \n");
608 /* Check if ring is empty */
609 if (1 != rte_ring_empty(r))
613 if (memcmp(src, dst, cur_dst - dst)) {
614 rte_hexdump(stdout, "src", src, cur_src - src);
615 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
616 printf("data after dequeue is not the same\n");
623 printf("Test MP & MC basic functions \n");
625 printf("enqueue 1 obj\n");
626 ret = rte_ring_mp_enqueue_burst(r, cur_src, 1);
628 if ((ret & RTE_RING_SZ_MASK) != 1)
631 printf("enqueue 2 objs\n");
632 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
634 if ((ret & RTE_RING_SZ_MASK) != 2)
637 printf("enqueue MAX_BULK objs\n");
638 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
640 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
643 printf("dequeue 1 obj\n");
644 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 1);
646 if ((ret & RTE_RING_SZ_MASK) != 1)
649 printf("dequeue 2 objs\n");
650 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
652 if ((ret & RTE_RING_SZ_MASK) != 2)
655 printf("dequeue MAX_BULK objs\n");
656 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
658 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
662 if (memcmp(src, dst, cur_dst - dst)) {
663 rte_hexdump(stdout, "src", src, cur_src - src);
664 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
665 printf("data after dequeue is not the same\n");
672 printf("fill and empty the ring\n");
673 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
674 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
676 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
678 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
680 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
685 if (memcmp(src, dst, cur_dst - dst)) {
686 rte_hexdump(stdout, "src", src, cur_src - src);
687 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
688 printf("data after dequeue is not the same\n");
695 printf("Test enqueue without enough memory space \n");
696 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
697 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
699 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
703 /* Available memory space for the exact MAX_BULK objects */
704 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
706 if ((ret & RTE_RING_SZ_MASK) != 2)
709 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
710 cur_src += MAX_BULK - 3;
711 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
715 printf("Test dequeue without enough objects \n");
716 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
717 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
719 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
723 /* Available objects - the exact MAX_BULK */
724 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
726 if ((ret & RTE_RING_SZ_MASK) != 2)
729 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
730 cur_dst += MAX_BULK - 3;
731 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
735 if (memcmp(src, dst, cur_dst - dst)) {
736 rte_hexdump(stdout, "src", src, cur_src - src);
737 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
738 printf("data after dequeue is not the same\n");
745 printf("Covering rte_ring_enqueue_burst functions \n");
747 ret = rte_ring_enqueue_burst(r, cur_src, 2);
749 if ((ret & RTE_RING_SZ_MASK) != 2)
752 ret = rte_ring_dequeue_burst(r, cur_dst, 2);
757 /* Free memory before test completed */
769 test_ring_stats(void)
772 #ifndef RTE_LIBRTE_RING_DEBUG
773 printf("Enable RTE_LIBRTE_RING_DEBUG to test ring stats.\n");
776 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
779 unsigned num_items = 0;
780 unsigned failed_enqueue_ops = 0;
781 unsigned failed_enqueue_items = 0;
782 unsigned failed_dequeue_ops = 0;
783 unsigned failed_dequeue_items = 0;
784 unsigned last_enqueue_ops = 0;
785 unsigned last_enqueue_items = 0;
786 unsigned last_quota_ops = 0;
787 unsigned last_quota_items = 0;
788 unsigned lcore_id = rte_lcore_id();
789 struct rte_ring_debug_stats *ring_stats = &r->stats[lcore_id];
791 printf("Test the ring stats.\n");
793 /* Reset the watermark in case it was set in another test. */
794 rte_ring_set_water_mark(r, 0);
796 /* Reset the ring stats. */
797 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
799 /* Allocate some dummy object pointers. */
800 src = malloc(RING_SIZE*2*sizeof(void *));
804 for (i = 0; i < RING_SIZE*2 ; i++) {
805 src[i] = (void *)(unsigned long)i;
808 /* Allocate some memory for copied objects. */
809 dst = malloc(RING_SIZE*2*sizeof(void *));
813 memset(dst, 0, RING_SIZE*2*sizeof(void *));
815 /* Set the head and tail pointers. */
819 /* Do Enqueue tests. */
820 printf("Test the dequeue stats.\n");
822 /* Fill the ring up to RING_SIZE -1. */
823 printf("Fill the ring.\n");
824 for (i = 0; i< (RING_SIZE/MAX_BULK); i++) {
825 rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
829 /* Adjust for final enqueue = MAX_BULK -1. */
832 printf("Verify that the ring is full.\n");
833 if (rte_ring_full(r) != 1)
837 printf("Verify the enqueue success stats.\n");
838 /* Stats should match above enqueue operations to fill the ring. */
839 if (ring_stats->enq_success_bulk != (RING_SIZE/MAX_BULK))
842 /* Current max objects is RING_SIZE -1. */
843 if (ring_stats->enq_success_objs != RING_SIZE -1)
846 /* Shouldn't have any failures yet. */
847 if (ring_stats->enq_fail_bulk != 0)
849 if (ring_stats->enq_fail_objs != 0)
853 printf("Test stats for SP burst enqueue to a full ring.\n");
855 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
856 if ((ret & RTE_RING_SZ_MASK) != 0)
859 failed_enqueue_ops += 1;
860 failed_enqueue_items += num_items;
862 /* The enqueue should have failed. */
863 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
865 if (ring_stats->enq_fail_objs != failed_enqueue_items)
869 printf("Test stats for SP bulk enqueue to a full ring.\n");
871 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
875 failed_enqueue_ops += 1;
876 failed_enqueue_items += num_items;
878 /* The enqueue should have failed. */
879 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
881 if (ring_stats->enq_fail_objs != failed_enqueue_items)
885 printf("Test stats for MP burst enqueue to a full ring.\n");
887 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
888 if ((ret & RTE_RING_SZ_MASK) != 0)
891 failed_enqueue_ops += 1;
892 failed_enqueue_items += num_items;
894 /* The enqueue should have failed. */
895 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
897 if (ring_stats->enq_fail_objs != failed_enqueue_items)
901 printf("Test stats for MP bulk enqueue to a full ring.\n");
903 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
907 failed_enqueue_ops += 1;
908 failed_enqueue_items += num_items;
910 /* The enqueue should have failed. */
911 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
913 if (ring_stats->enq_fail_objs != failed_enqueue_items)
917 /* Do Dequeue tests. */
918 printf("Test the dequeue stats.\n");
920 printf("Empty the ring.\n");
921 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
922 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
926 /* There was only RING_SIZE -1 objects to dequeue. */
929 printf("Verify ring is empty.\n");
930 if (1 != rte_ring_empty(r))
933 printf("Verify the dequeue success stats.\n");
934 /* Stats should match above dequeue operations. */
935 if (ring_stats->deq_success_bulk != (RING_SIZE/MAX_BULK))
938 /* Objects dequeued is RING_SIZE -1. */
939 if (ring_stats->deq_success_objs != RING_SIZE -1)
942 /* Shouldn't have any dequeue failure stats yet. */
943 if (ring_stats->deq_fail_bulk != 0)
946 printf("Test stats for SC burst dequeue with an empty ring.\n");
948 ret = rte_ring_sc_dequeue_burst(r, cur_dst, num_items);
949 if ((ret & RTE_RING_SZ_MASK) != 0)
952 failed_dequeue_ops += 1;
953 failed_dequeue_items += num_items;
955 /* The dequeue should have failed. */
956 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
958 if (ring_stats->deq_fail_objs != failed_dequeue_items)
962 printf("Test stats for SC bulk dequeue with an empty ring.\n");
964 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, num_items);
968 failed_dequeue_ops += 1;
969 failed_dequeue_items += num_items;
971 /* The dequeue should have failed. */
972 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
974 if (ring_stats->deq_fail_objs != failed_dequeue_items)
978 printf("Test stats for MC burst dequeue with an empty ring.\n");
980 ret = rte_ring_mc_dequeue_burst(r, cur_dst, num_items);
981 if ((ret & RTE_RING_SZ_MASK) != 0)
983 failed_dequeue_ops += 1;
984 failed_dequeue_items += num_items;
986 /* The dequeue should have failed. */
987 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
989 if (ring_stats->deq_fail_objs != failed_dequeue_items)
993 printf("Test stats for MC bulk dequeue with an empty ring.\n");
995 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, num_items);
999 failed_dequeue_ops += 1;
1000 failed_dequeue_items += num_items;
1002 /* The dequeue should have failed. */
1003 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
1005 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1009 printf("Test total enqueue/dequeue stats.\n");
1010 /* At this point the enqueue and dequeue stats should be the same. */
1011 if (ring_stats->enq_success_bulk != ring_stats->deq_success_bulk)
1013 if (ring_stats->enq_success_objs != ring_stats->deq_success_objs)
1015 if (ring_stats->enq_fail_bulk != ring_stats->deq_fail_bulk)
1017 if (ring_stats->enq_fail_objs != ring_stats->deq_fail_objs)
1021 /* Watermark Tests. */
1022 printf("Test the watermark/quota stats.\n");
1024 printf("Verify the initial watermark stats.\n");
1025 /* Watermark stats should be 0 since there is no watermark. */
1026 if (ring_stats->enq_quota_bulk != 0)
1028 if (ring_stats->enq_quota_objs != 0)
1031 /* Set a watermark. */
1032 rte_ring_set_water_mark(r, 16);
1034 /* Reset pointers. */
1038 last_enqueue_ops = ring_stats->enq_success_bulk;
1039 last_enqueue_items = ring_stats->enq_success_objs;
1042 printf("Test stats for SP burst enqueue below watermark.\n");
1044 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1045 if ((ret & RTE_RING_SZ_MASK) != num_items)
1048 /* Watermark stats should still be 0. */
1049 if (ring_stats->enq_quota_bulk != 0)
1051 if (ring_stats->enq_quota_objs != 0)
1054 /* Success stats should have increased. */
1055 if (ring_stats->enq_success_bulk != last_enqueue_ops + 1)
1057 if (ring_stats->enq_success_objs != last_enqueue_items + num_items)
1060 last_enqueue_ops = ring_stats->enq_success_bulk;
1061 last_enqueue_items = ring_stats->enq_success_objs;
1064 printf("Test stats for SP burst enqueue at watermark.\n");
1066 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1067 if ((ret & RTE_RING_SZ_MASK) != num_items)
1070 /* Watermark stats should have changed. */
1071 if (ring_stats->enq_quota_bulk != 1)
1073 if (ring_stats->enq_quota_objs != num_items)
1076 last_quota_ops = ring_stats->enq_quota_bulk;
1077 last_quota_items = ring_stats->enq_quota_objs;
1080 printf("Test stats for SP burst enqueue above watermark.\n");
1082 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1083 if ((ret & RTE_RING_SZ_MASK) != num_items)
1086 /* Watermark stats should have changed. */
1087 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1089 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1092 last_quota_ops = ring_stats->enq_quota_bulk;
1093 last_quota_items = ring_stats->enq_quota_objs;
1096 printf("Test stats for MP burst enqueue above watermark.\n");
1098 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
1099 if ((ret & RTE_RING_SZ_MASK) != num_items)
1102 /* Watermark stats should have changed. */
1103 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1105 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1108 last_quota_ops = ring_stats->enq_quota_bulk;
1109 last_quota_items = ring_stats->enq_quota_objs;
1112 printf("Test stats for SP bulk enqueue above watermark.\n");
1114 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
1118 /* Watermark stats should have changed. */
1119 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1121 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1124 last_quota_ops = ring_stats->enq_quota_bulk;
1125 last_quota_items = ring_stats->enq_quota_objs;
1128 printf("Test stats for MP bulk enqueue above watermark.\n");
1130 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
1134 /* Watermark stats should have changed. */
1135 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1137 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1140 printf("Test watermark success stats.\n");
1141 /* Success stats should be same as last non-watermarked enqueue. */
1142 if (ring_stats->enq_success_bulk != last_enqueue_ops)
1144 if (ring_stats->enq_success_objs != last_enqueue_items)
1150 /* Empty the ring. */
1151 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
1152 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
1153 cur_dst += MAX_BULK;
1156 /* Reset the watermark. */
1157 rte_ring_set_water_mark(r, 0);
1159 /* Reset the ring stats. */
1160 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
1162 /* Free memory before test completed */
1175 * it will always fail to create ring with a wrong ring size number in this function
1178 test_ring_creation_with_wrong_size(void)
1180 struct rte_ring * rp = NULL;
1182 /* Test if ring size is not power of 2 */
1183 rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0);
1188 /* Test if ring size is exceeding the limit */
1189 rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0);
1197 * it tests if it would always fail to create ring with an used ring name
1200 test_ring_creation_with_an_used_name(void)
1202 struct rte_ring * rp;
1204 rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1212 * Test to if a non-power of 2 count causes the create
1213 * function to fail correctly
1216 test_create_count_odd(void)
1218 struct rte_ring *r = rte_ring_create("test_ring_count",
1219 4097, SOCKET_ID_ANY, 0 );
1227 test_lookup_null(void)
1229 struct rte_ring *rlp = rte_ring_lookup("ring_not_found");
1231 if (rte_errno != ENOENT){
1232 printf( "test failed to returnn error on null pointer\n");
1239 * it tests some more basic ring operations
1242 test_ring_basic_ex(void)
1246 struct rte_ring * rp;
1249 obj = rte_calloc("test_ring_basic_ex_malloc", RING_SIZE, sizeof(void *), 0);
1251 printf("test_ring_basic_ex fail to rte_malloc\n");
1255 rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY,
1256 RING_F_SP_ENQ | RING_F_SC_DEQ);
1258 printf("test_ring_basic_ex fail to create ring\n");
1262 if (rte_ring_lookup("test_ring_basic_ex") != rp) {
1266 if (rte_ring_empty(rp) != 1) {
1267 printf("test_ring_basic_ex ring is not empty but it should be\n");
1271 printf("%u ring entries are now free\n", rte_ring_free_count(rp));
1273 for (i = 0; i < RING_SIZE; i ++) {
1274 rte_ring_enqueue(rp, obj[i]);
1277 if (rte_ring_full(rp) != 1) {
1278 printf("test_ring_basic_ex ring is not full but it should be\n");
1282 for (i = 0; i < RING_SIZE; i ++) {
1283 rte_ring_dequeue(rp, &obj[i]);
1286 if (rte_ring_empty(rp) != 1) {
1287 printf("test_ring_basic_ex ring is not empty but it should be\n");
1291 /* Covering the ring burst operation */
1292 ret = rte_ring_enqueue_burst(rp, obj, 2);
1293 if ((ret & RTE_RING_SZ_MASK) != 2) {
1294 printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n");
1298 ret = rte_ring_dequeue_burst(rp, obj, 2);
1300 printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n");
1315 /* some more basic operations */
1316 if (test_ring_basic_ex() < 0)
1319 rte_atomic32_init(&synchro);
1322 r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1326 /* retrieve the ring from its name */
1327 if (rte_ring_lookup("test") != r) {
1328 printf("Cannot lookup ring from its name\n");
1332 /* burst operations */
1333 if (test_ring_burst_basic() < 0)
1336 /* basic operations */
1337 if (test_ring_basic() < 0)
1341 if (test_ring_stats() < 0)
1344 /* basic operations */
1345 if (test_live_watermark_change() < 0)
1348 if ( test_set_watermark() < 0){
1349 printf ("Test failed to detect invalid parameter\n");
1353 printf ( "Test detected forced bad watermark values\n");
1355 if ( test_create_count_odd() < 0){
1356 printf ("Test failed to detect odd count\n");
1360 printf ( "Test detected odd count\n");
1362 if ( test_lookup_null() < 0){
1363 printf ("Test failed to detect NULL ring lookup\n");
1367 printf ( "Test detected NULL ring lookup \n");
1369 /* test of creating ring with wrong size */
1370 if (test_ring_creation_with_wrong_size() < 0)
1373 /* test of creation ring with an used name */
1374 if (test_ring_creation_with_an_used_name() < 0)
1377 /* dump the ring status */
1378 rte_ring_list_dump(stdout);
1383 static struct test_command ring_cmd = {
1384 .command = "ring_autotest",
1385 .callback = test_ring,
1387 REGISTER_TEST_COMMAND(ring_cmd);