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>
68 * #. Basic tests: done on one core:
70 * - Using single producer/single consumer functions:
72 * - Enqueue one object, two objects, MAX_BULK objects
73 * - Dequeue one object, two objects, MAX_BULK objects
74 * - Check that dequeued pointers are correct
76 * - Using multi producers/multi consumers functions:
78 * - Enqueue one object, two objects, MAX_BULK objects
79 * - Dequeue one object, two objects, MAX_BULK objects
80 * - Check that dequeued pointers are correct
82 * - Test watermark and default bulk enqueue/dequeue:
85 * - Set default bulk value
86 * - Enqueue objects, check that -EDQUOT is returned when
87 * watermark is exceeded
88 * - Check that dequeued pointers are correct
90 * #. Check live watermark change
92 * - Start a loop on another lcore that will enqueue and dequeue
93 * objects in a ring. It will monitor the value of watermark.
94 * - At the same time, change the watermark on the master lcore.
95 * - The slave lcore will check that watermark changes from 16 to 32.
97 * #. Performance tests.
99 * Tests done in test_ring_perf.c
102 #define RING_SIZE 4096
107 static rte_atomic32_t synchro;
109 static struct rte_ring *r;
111 #define TEST_RING_VERIFY(exp) \
113 printf("error at %s:%d\tcondition " #exp " failed\n", \
114 __func__, __LINE__); \
115 rte_ring_dump(stdout, r); \
119 #define TEST_RING_FULL_EMTPY_ITER 8
122 check_live_watermark_change(__attribute__((unused)) void *dummy)
124 uint64_t hz = rte_get_timer_hz();
125 void *obj_table[MAX_BULK];
126 unsigned watermark, watermark_old = 16;
127 uint64_t cur_time, end_time;
132 /* init the object table */
133 memset(obj_table, 0, sizeof(obj_table));
134 end_time = rte_get_timer_cycles() + (hz * 2);
136 /* check that bulk and watermark are 4 and 32 (respectively) */
139 /* add in ring until we reach watermark */
141 for (i = 0; i < 16; i ++) {
144 ret = rte_ring_enqueue_bulk(r, obj_table, count);
147 if (ret != -EDQUOT) {
148 printf("Cannot enqueue objects, or watermark not "
149 "reached (ret=%d)\n", ret);
153 /* read watermark, the only change allowed is from 16 to 32 */
154 watermark = r->prod.watermark;
155 if (watermark != watermark_old &&
156 (watermark_old != 16 || watermark != 32)) {
157 printf("Bad watermark change %u -> %u\n", watermark_old,
161 watermark_old = watermark;
163 /* dequeue objects from ring */
165 ret = rte_ring_dequeue_bulk(r, obj_table, count);
167 printf("Cannot dequeue (ret=%d)\n", ret);
172 cur_time = rte_get_timer_cycles();
173 diff = end_time - cur_time;
176 if (watermark_old != 32 ) {
177 printf(" watermark was not updated (wm=%u)\n",
186 test_live_watermark_change(void)
188 unsigned lcore_id = rte_lcore_id();
189 unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1);
191 printf("Test watermark live modification\n");
192 rte_ring_set_water_mark(r, 16);
194 /* launch a thread that will enqueue and dequeue, checking
195 * watermark and quota */
196 rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2);
199 rte_ring_set_water_mark(r, 32);
202 if (rte_eal_wait_lcore(lcore_id2) < 0)
208 /* Test for catch on invalid watermark values */
210 test_set_watermark( void ){
214 struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex");
216 printf( " ring lookup failed\n" );
219 count = r->prod.size*2;
220 setwm = rte_ring_set_water_mark(r, count);
221 if (setwm != -EINVAL){
222 printf("Test failed to detect invalid watermark count value\n");
227 rte_ring_set_water_mark(r, count);
228 if (r->prod.watermark != r->prod.size) {
229 printf("Test failed to detect invalid watermark count value\n");
239 * helper routine for test_ring_basic
242 test_ring_basic_full_empty(void * const src[], void *dst[])
245 const unsigned rsz = RING_SIZE - 1;
247 printf("Basic full/empty test\n");
249 for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) {
251 /* random shift in the ring */
252 rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
253 printf("%s: iteration %u, random shift: %u;\n",
255 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
257 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand));
260 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
262 TEST_RING_VERIFY(0 == rte_ring_free_count(r));
263 TEST_RING_VERIFY(rsz == rte_ring_count(r));
264 TEST_RING_VERIFY(rte_ring_full(r));
265 TEST_RING_VERIFY(0 == rte_ring_empty(r));
268 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz));
269 TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
270 TEST_RING_VERIFY(0 == rte_ring_count(r));
271 TEST_RING_VERIFY(0 == rte_ring_full(r));
272 TEST_RING_VERIFY(rte_ring_empty(r));
275 TEST_RING_VERIFY(0 == memcmp(src, dst, rsz));
276 rte_ring_dump(stdout, r);
282 test_ring_basic(void)
284 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
286 unsigned i, num_elems;
288 /* alloc dummy object pointers */
289 src = malloc(RING_SIZE*2*sizeof(void *));
293 for (i = 0; i < RING_SIZE*2 ; i++) {
294 src[i] = (void *)(unsigned long)i;
298 /* alloc some room for copied objects */
299 dst = malloc(RING_SIZE*2*sizeof(void *));
303 memset(dst, 0, RING_SIZE*2*sizeof(void *));
306 printf("enqueue 1 obj\n");
307 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1);
312 printf("enqueue 2 objs\n");
313 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2);
318 printf("enqueue MAX_BULK objs\n");
319 ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK);
324 printf("dequeue 1 obj\n");
325 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1);
330 printf("dequeue 2 objs\n");
331 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2);
336 printf("dequeue MAX_BULK objs\n");
337 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK);
343 if (memcmp(src, dst, cur_dst - dst)) {
344 rte_hexdump(stdout, "src", src, cur_src - src);
345 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
346 printf("data after dequeue is not the same\n");
352 printf("enqueue 1 obj\n");
353 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1);
358 printf("enqueue 2 objs\n");
359 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2);
364 printf("enqueue MAX_BULK objs\n");
365 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
370 printf("dequeue 1 obj\n");
371 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1);
376 printf("dequeue 2 objs\n");
377 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2);
382 printf("dequeue MAX_BULK objs\n");
383 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
389 if (memcmp(src, dst, cur_dst - dst)) {
390 rte_hexdump(stdout, "src", src, cur_src - src);
391 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
392 printf("data after dequeue is not the same\n");
398 printf("fill and empty the ring\n");
399 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
400 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
404 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
411 if (memcmp(src, dst, cur_dst - dst)) {
412 rte_hexdump(stdout, "src", src, cur_src - src);
413 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
414 printf("data after dequeue is not the same\n");
418 if (test_ring_basic_full_empty(src, dst) != 0)
424 printf("test watermark and default bulk enqueue / dequeue\n");
425 rte_ring_set_water_mark(r, 20);
431 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
432 cur_src += num_elems;
434 printf("Cannot enqueue\n");
437 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
438 cur_src += num_elems;
439 if (ret != -EDQUOT) {
440 printf("Watermark not exceeded\n");
443 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
444 cur_dst += num_elems;
446 printf("Cannot dequeue\n");
449 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
450 cur_dst += num_elems;
452 printf("Cannot dequeue2\n");
457 if (memcmp(src, dst, cur_dst - dst)) {
458 rte_hexdump(stdout, "src", src, cur_src - src);
459 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
460 printf("data after dequeue is not the same\n");
467 ret = rte_ring_mp_enqueue(r, cur_src);
471 ret = rte_ring_mc_dequeue(r, cur_dst);
490 test_ring_burst_basic(void)
492 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
496 /* alloc dummy object pointers */
497 src = malloc(RING_SIZE*2*sizeof(void *));
501 for (i = 0; i < RING_SIZE*2 ; i++) {
502 src[i] = (void *)(unsigned long)i;
506 /* alloc some room for copied objects */
507 dst = malloc(RING_SIZE*2*sizeof(void *));
511 memset(dst, 0, RING_SIZE*2*sizeof(void *));
514 printf("Test SP & SC basic functions \n");
515 printf("enqueue 1 obj\n");
516 ret = rte_ring_sp_enqueue_burst(r, cur_src, 1);
518 if ((ret & RTE_RING_SZ_MASK) != 1)
521 printf("enqueue 2 objs\n");
522 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
524 if ((ret & RTE_RING_SZ_MASK) != 2)
527 printf("enqueue MAX_BULK objs\n");
528 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK) ;
530 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
533 printf("dequeue 1 obj\n");
534 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 1) ;
536 if ((ret & RTE_RING_SZ_MASK) != 1)
539 printf("dequeue 2 objs\n");
540 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
542 if ((ret & RTE_RING_SZ_MASK) != 2)
545 printf("dequeue MAX_BULK objs\n");
546 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
548 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
552 if (memcmp(src, dst, cur_dst - dst)) {
553 rte_hexdump(stdout, "src", src, cur_src - src);
554 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
555 printf("data after dequeue is not the same\n");
562 printf("Test enqueue without enough memory space \n");
563 for (i = 0; i< (RING_SIZE/MAX_BULK - 1); i++) {
564 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
566 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK) {
571 printf("Enqueue 2 objects, free entries = MAX_BULK - 2 \n");
572 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
574 if ((ret & RTE_RING_SZ_MASK) != 2)
577 printf("Enqueue the remaining entries = MAX_BULK - 2 \n");
578 /* Always one free entry left */
579 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
580 cur_src += MAX_BULK - 3;
581 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
584 printf("Test if ring is full \n");
585 if (rte_ring_full(r) != 1)
588 printf("Test enqueue for a full entry \n");
589 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
590 if ((ret & RTE_RING_SZ_MASK) != 0)
593 printf("Test dequeue without enough objects \n");
594 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
595 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
597 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
601 /* Available memory space for the exact MAX_BULK entries */
602 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
604 if ((ret & RTE_RING_SZ_MASK) != 2)
607 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
608 cur_dst += MAX_BULK - 3;
609 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
612 printf("Test if ring is empty \n");
613 /* Check if ring is empty */
614 if (1 != rte_ring_empty(r))
618 if (memcmp(src, dst, cur_dst - dst)) {
619 rte_hexdump(stdout, "src", src, cur_src - src);
620 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
621 printf("data after dequeue is not the same\n");
628 printf("Test MP & MC basic functions \n");
630 printf("enqueue 1 obj\n");
631 ret = rte_ring_mp_enqueue_burst(r, cur_src, 1);
633 if ((ret & RTE_RING_SZ_MASK) != 1)
636 printf("enqueue 2 objs\n");
637 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
639 if ((ret & RTE_RING_SZ_MASK) != 2)
642 printf("enqueue MAX_BULK objs\n");
643 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
645 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
648 printf("dequeue 1 obj\n");
649 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 1);
651 if ((ret & RTE_RING_SZ_MASK) != 1)
654 printf("dequeue 2 objs\n");
655 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
657 if ((ret & RTE_RING_SZ_MASK) != 2)
660 printf("dequeue MAX_BULK objs\n");
661 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
663 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
667 if (memcmp(src, dst, cur_dst - dst)) {
668 rte_hexdump(stdout, "src", src, cur_src - src);
669 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
670 printf("data after dequeue is not the same\n");
677 printf("fill and empty the ring\n");
678 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
679 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
681 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
683 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
685 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
690 if (memcmp(src, dst, cur_dst - dst)) {
691 rte_hexdump(stdout, "src", src, cur_src - src);
692 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
693 printf("data after dequeue is not the same\n");
700 printf("Test enqueue without enough memory space \n");
701 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
702 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
704 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
708 /* Available memory space for the exact MAX_BULK objects */
709 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
711 if ((ret & RTE_RING_SZ_MASK) != 2)
714 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
715 cur_src += MAX_BULK - 3;
716 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
720 printf("Test dequeue without enough objects \n");
721 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
722 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
724 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
728 /* Available objects - the exact MAX_BULK */
729 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
731 if ((ret & RTE_RING_SZ_MASK) != 2)
734 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
735 cur_dst += MAX_BULK - 3;
736 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
740 if (memcmp(src, dst, cur_dst - dst)) {
741 rte_hexdump(stdout, "src", src, cur_src - src);
742 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
743 printf("data after dequeue is not the same\n");
750 printf("Covering rte_ring_enqueue_burst functions \n");
752 ret = rte_ring_enqueue_burst(r, cur_src, 2);
754 if ((ret & RTE_RING_SZ_MASK) != 2)
757 ret = rte_ring_dequeue_burst(r, cur_dst, 2);
762 /* Free memory before test completed */
778 test_ring_stats(void)
781 #ifndef RTE_LIBRTE_RING_DEBUG
782 printf("Enable RTE_LIBRTE_RING_DEBUG to test ring stats.\n");
785 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
788 unsigned num_items = 0;
789 unsigned failed_enqueue_ops = 0;
790 unsigned failed_enqueue_items = 0;
791 unsigned failed_dequeue_ops = 0;
792 unsigned failed_dequeue_items = 0;
793 unsigned last_enqueue_ops = 0;
794 unsigned last_enqueue_items = 0;
795 unsigned last_quota_ops = 0;
796 unsigned last_quota_items = 0;
797 unsigned lcore_id = rte_lcore_id();
798 struct rte_ring_debug_stats *ring_stats = &r->stats[lcore_id];
800 printf("Test the ring stats.\n");
802 /* Reset the watermark in case it was set in another test. */
803 rte_ring_set_water_mark(r, 0);
805 /* Reset the ring stats. */
806 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
808 /* Allocate some dummy object pointers. */
809 src = malloc(RING_SIZE*2*sizeof(void *));
813 for (i = 0; i < RING_SIZE*2 ; i++) {
814 src[i] = (void *)(unsigned long)i;
817 /* Allocate some memory for copied objects. */
818 dst = malloc(RING_SIZE*2*sizeof(void *));
822 memset(dst, 0, RING_SIZE*2*sizeof(void *));
824 /* Set the head and tail pointers. */
828 /* Do Enqueue tests. */
829 printf("Test the dequeue stats.\n");
831 /* Fill the ring up to RING_SIZE -1. */
832 printf("Fill the ring.\n");
833 for (i = 0; i< (RING_SIZE/MAX_BULK); i++) {
834 rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
838 /* Adjust for final enqueue = MAX_BULK -1. */
841 printf("Verify that the ring is full.\n");
842 if (rte_ring_full(r) != 1)
846 printf("Verify the enqueue success stats.\n");
847 /* Stats should match above enqueue operations to fill the ring. */
848 if (ring_stats->enq_success_bulk != (RING_SIZE/MAX_BULK))
851 /* Current max objects is RING_SIZE -1. */
852 if (ring_stats->enq_success_objs != RING_SIZE -1)
855 /* Shouldn't have any failures yet. */
856 if (ring_stats->enq_fail_bulk != 0)
858 if (ring_stats->enq_fail_objs != 0)
862 printf("Test stats for SP burst enqueue to a full ring.\n");
864 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
865 if ((ret & RTE_RING_SZ_MASK) != 0)
868 failed_enqueue_ops += 1;
869 failed_enqueue_items += num_items;
871 /* The enqueue should have failed. */
872 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
874 if (ring_stats->enq_fail_objs != failed_enqueue_items)
878 printf("Test stats for SP bulk enqueue to a full ring.\n");
880 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
884 failed_enqueue_ops += 1;
885 failed_enqueue_items += num_items;
887 /* The enqueue should have failed. */
888 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
890 if (ring_stats->enq_fail_objs != failed_enqueue_items)
894 printf("Test stats for MP burst enqueue to a full ring.\n");
896 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
897 if ((ret & RTE_RING_SZ_MASK) != 0)
900 failed_enqueue_ops += 1;
901 failed_enqueue_items += num_items;
903 /* The enqueue should have failed. */
904 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
906 if (ring_stats->enq_fail_objs != failed_enqueue_items)
910 printf("Test stats for MP bulk enqueue to a full ring.\n");
912 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
916 failed_enqueue_ops += 1;
917 failed_enqueue_items += num_items;
919 /* The enqueue should have failed. */
920 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
922 if (ring_stats->enq_fail_objs != failed_enqueue_items)
926 /* Do Dequeue tests. */
927 printf("Test the dequeue stats.\n");
929 printf("Empty the ring.\n");
930 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
931 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
935 /* There was only RING_SIZE -1 objects to dequeue. */
938 printf("Verify ring is empty.\n");
939 if (1 != rte_ring_empty(r))
942 printf("Verify the dequeue success stats.\n");
943 /* Stats should match above dequeue operations. */
944 if (ring_stats->deq_success_bulk != (RING_SIZE/MAX_BULK))
947 /* Objects dequeued is RING_SIZE -1. */
948 if (ring_stats->deq_success_objs != RING_SIZE -1)
951 /* Shouldn't have any dequeue failure stats yet. */
952 if (ring_stats->deq_fail_bulk != 0)
955 printf("Test stats for SC burst dequeue with an empty ring.\n");
957 ret = rte_ring_sc_dequeue_burst(r, cur_dst, num_items);
958 if ((ret & RTE_RING_SZ_MASK) != 0)
961 failed_dequeue_ops += 1;
962 failed_dequeue_items += num_items;
964 /* The dequeue should have failed. */
965 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
967 if (ring_stats->deq_fail_objs != failed_dequeue_items)
971 printf("Test stats for SC bulk dequeue with an empty ring.\n");
973 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, num_items);
977 failed_dequeue_ops += 1;
978 failed_dequeue_items += num_items;
980 /* The dequeue should have failed. */
981 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
983 if (ring_stats->deq_fail_objs != failed_dequeue_items)
987 printf("Test stats for MC burst dequeue with an empty ring.\n");
989 ret = rte_ring_mc_dequeue_burst(r, cur_dst, num_items);
990 if ((ret & RTE_RING_SZ_MASK) != 0)
992 failed_dequeue_ops += 1;
993 failed_dequeue_items += num_items;
995 /* The dequeue should have failed. */
996 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
998 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1002 printf("Test stats for MC bulk dequeue with an empty ring.\n");
1004 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, num_items);
1008 failed_dequeue_ops += 1;
1009 failed_dequeue_items += num_items;
1011 /* The dequeue should have failed. */
1012 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
1014 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1018 printf("Test total enqueue/dequeue stats.\n");
1019 /* At this point the enqueue and dequeue stats should be the same. */
1020 if (ring_stats->enq_success_bulk != ring_stats->deq_success_bulk)
1022 if (ring_stats->enq_success_objs != ring_stats->deq_success_objs)
1024 if (ring_stats->enq_fail_bulk != ring_stats->deq_fail_bulk)
1026 if (ring_stats->enq_fail_objs != ring_stats->deq_fail_objs)
1030 /* Watermark Tests. */
1031 printf("Test the watermark/quota stats.\n");
1033 printf("Verify the initial watermark stats.\n");
1034 /* Watermark stats should be 0 since there is no watermark. */
1035 if (ring_stats->enq_quota_bulk != 0)
1037 if (ring_stats->enq_quota_objs != 0)
1040 /* Set a watermark. */
1041 rte_ring_set_water_mark(r, 16);
1043 /* Reset pointers. */
1047 last_enqueue_ops = ring_stats->enq_success_bulk;
1048 last_enqueue_items = ring_stats->enq_success_objs;
1051 printf("Test stats for SP burst enqueue below watermark.\n");
1053 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1054 if ((ret & RTE_RING_SZ_MASK) != num_items)
1057 /* Watermark stats should still be 0. */
1058 if (ring_stats->enq_quota_bulk != 0)
1060 if (ring_stats->enq_quota_objs != 0)
1063 /* Success stats should have increased. */
1064 if (ring_stats->enq_success_bulk != last_enqueue_ops + 1)
1066 if (ring_stats->enq_success_objs != last_enqueue_items + num_items)
1069 last_enqueue_ops = ring_stats->enq_success_bulk;
1070 last_enqueue_items = ring_stats->enq_success_objs;
1073 printf("Test stats for SP burst enqueue at watermark.\n");
1075 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1076 if ((ret & RTE_RING_SZ_MASK) != num_items)
1079 /* Watermark stats should have changed. */
1080 if (ring_stats->enq_quota_bulk != 1)
1082 if (ring_stats->enq_quota_objs != num_items)
1085 last_quota_ops = ring_stats->enq_quota_bulk;
1086 last_quota_items = ring_stats->enq_quota_objs;
1089 printf("Test stats for SP burst enqueue above watermark.\n");
1091 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1092 if ((ret & RTE_RING_SZ_MASK) != num_items)
1095 /* Watermark stats should have changed. */
1096 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1098 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1101 last_quota_ops = ring_stats->enq_quota_bulk;
1102 last_quota_items = ring_stats->enq_quota_objs;
1105 printf("Test stats for MP burst enqueue above watermark.\n");
1107 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
1108 if ((ret & RTE_RING_SZ_MASK) != num_items)
1111 /* Watermark stats should have changed. */
1112 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1114 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1117 last_quota_ops = ring_stats->enq_quota_bulk;
1118 last_quota_items = ring_stats->enq_quota_objs;
1121 printf("Test stats for SP bulk enqueue above watermark.\n");
1123 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
1127 /* Watermark stats should have changed. */
1128 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1130 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1133 last_quota_ops = ring_stats->enq_quota_bulk;
1134 last_quota_items = ring_stats->enq_quota_objs;
1137 printf("Test stats for MP bulk enqueue above watermark.\n");
1139 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
1143 /* Watermark stats should have changed. */
1144 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1146 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1149 printf("Test watermark success stats.\n");
1150 /* Success stats should be same as last non-watermarked enqueue. */
1151 if (ring_stats->enq_success_bulk != last_enqueue_ops)
1153 if (ring_stats->enq_success_objs != last_enqueue_items)
1159 /* Empty the ring. */
1160 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
1161 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
1162 cur_dst += MAX_BULK;
1165 /* Reset the watermark. */
1166 rte_ring_set_water_mark(r, 0);
1168 /* Reset the ring stats. */
1169 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
1171 /* Free memory before test completed */
1188 * it will always fail to create ring with a wrong ring size number in this function
1191 test_ring_creation_with_wrong_size(void)
1193 struct rte_ring * rp = NULL;
1195 /* Test if ring size is not power of 2 */
1196 rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0);
1201 /* Test if ring size is exceeding the limit */
1202 rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0);
1210 * it tests if it would always fail to create ring with an used ring name
1213 test_ring_creation_with_an_used_name(void)
1215 struct rte_ring * rp;
1217 rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1225 * Test to if a non-power of 2 count causes the create
1226 * function to fail correctly
1229 test_create_count_odd(void)
1231 struct rte_ring *r = rte_ring_create("test_ring_count",
1232 4097, SOCKET_ID_ANY, 0 );
1240 test_lookup_null(void)
1242 struct rte_ring *rlp = rte_ring_lookup("ring_not_found");
1244 if (rte_errno != ENOENT){
1245 printf( "test failed to returnn error on null pointer\n");
1252 * it tests some more basic ring operations
1255 test_ring_basic_ex(void)
1259 struct rte_ring * rp;
1262 obj = (void **)rte_zmalloc("test_ring_basic_ex_malloc", (RING_SIZE * sizeof(void *)), 0);
1264 printf("test_ring_basic_ex fail to rte_malloc\n");
1268 rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY,
1269 RING_F_SP_ENQ | RING_F_SC_DEQ);
1271 printf("test_ring_basic_ex fail to create ring\n");
1275 if (rte_ring_lookup("test_ring_basic_ex") != rp) {
1279 if (rte_ring_empty(rp) != 1) {
1280 printf("test_ring_basic_ex ring is not empty but it should be\n");
1284 printf("%u ring entries are now free\n", rte_ring_free_count(rp));
1286 for (i = 0; i < RING_SIZE; i ++) {
1287 rte_ring_enqueue(rp, obj[i]);
1290 if (rte_ring_full(rp) != 1) {
1291 printf("test_ring_basic_ex ring is not full but it should be\n");
1295 for (i = 0; i < RING_SIZE; i ++) {
1296 rte_ring_dequeue(rp, &obj[i]);
1299 if (rte_ring_empty(rp) != 1) {
1300 printf("test_ring_basic_ex ring is not empty but it should be\n");
1304 /* Covering the ring burst operation */
1305 ret = rte_ring_enqueue_burst(rp, obj, 2);
1306 if ((ret & RTE_RING_SZ_MASK) != 2) {
1307 printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n");
1311 ret = rte_ring_dequeue_burst(rp, obj, 2);
1313 printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n");
1328 /* some more basic operations */
1329 if (test_ring_basic_ex() < 0)
1332 rte_atomic32_init(&synchro);
1335 r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1339 /* retrieve the ring from its name */
1340 if (rte_ring_lookup("test") != r) {
1341 printf("Cannot lookup ring from its name\n");
1345 /* burst operations */
1346 if (test_ring_burst_basic() < 0)
1349 /* basic operations */
1350 if (test_ring_basic() < 0)
1354 if (test_ring_stats() < 0)
1357 /* basic operations */
1358 if (test_live_watermark_change() < 0)
1361 if ( test_set_watermark() < 0){
1362 printf ("Test failed to detect invalid parameter\n");
1366 printf ( "Test detected forced bad watermark values\n");
1368 if ( test_create_count_odd() < 0){
1369 printf ("Test failed to detect odd count\n");
1373 printf ( "Test detected odd count\n");
1375 if ( test_lookup_null() < 0){
1376 printf ("Test failed to detect NULL ring lookup\n");
1380 printf ( "Test detected NULL ring lookup \n");
1382 /* test of creating ring with wrong size */
1383 if (test_ring_creation_with_wrong_size() < 0)
1386 /* test of creation ring with an used name */
1387 if (test_ring_creation_with_an_used_name() < 0)
1390 /* dump the ring status */
1391 rte_ring_list_dump(stdout);
1396 static struct test_command ring_cmd = {
1397 .command = "ring_autotest",
1398 .callback = test_ring,
1400 REGISTER_TEST_COMMAND(ring_cmd);