1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <stdarg.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <stdint.h> 10 #include <inttypes.h> 11 #include <errno.h> 12 #include <sys/queue.h> 13 14 #include <rte_common.h> 15 #include <rte_log.h> 16 #include <rte_memory.h> 17 #include <rte_launch.h> 18 #include <rte_cycles.h> 19 #include <rte_eal.h> 20 #include <rte_per_lcore.h> 21 #include <rte_lcore.h> 22 #include <rte_atomic.h> 23 #include <rte_branch_prediction.h> 24 #include <rte_malloc.h> 25 #include <rte_ring.h> 26 #include <rte_ring_elem.h> 27 #include <rte_random.h> 28 #include <rte_errno.h> 29 #include <rte_hexdump.h> 30 31 #include "test.h" 32 #include "test_ring.h" 33 34 /* 35 * Ring 36 * ==== 37 * 38 * #. Functional tests. Tests single/bulk/burst, default/SPSC/MPMC, 39 * legacy/custom element size (4B, 8B, 16B, 20B) APIs. 40 * Some tests incorporate unaligned addresses for objects. 41 * The enqueued/dequeued data is validated for correctness. 42 * 43 * #. Performance tests are in test_ring_perf.c 44 */ 45 46 #define RING_SIZE 4096 47 #define MAX_BULK 32 48 49 #define TEST_RING_VERIFY(exp) \ 50 if (!(exp)) { \ 51 printf("error at %s:%d\tcondition " #exp " failed\n", \ 52 __func__, __LINE__); \ 53 rte_ring_dump(stdout, r); \ 54 return -1; \ 55 } 56 57 #define TEST_RING_FULL_EMTPY_ITER 8 58 59 static const int esize[] = {-1, 4, 8, 16, 20}; 60 61 static void** 62 test_ring_inc_ptr(void **obj, int esize, unsigned int n) 63 { 64 /* Legacy queue APIs? */ 65 if ((esize) == -1) 66 return ((void **)obj) + n; 67 else 68 return (void **)(((uint32_t *)obj) + 69 (n * esize / sizeof(uint32_t))); 70 } 71 72 static void 73 test_ring_mem_init(void *obj, unsigned int count, int esize) 74 { 75 unsigned int i; 76 77 /* Legacy queue APIs? */ 78 if (esize == -1) 79 for (i = 0; i < count; i++) 80 ((void **)obj)[i] = (void *)(unsigned long)i; 81 else 82 for (i = 0; i < (count * esize / sizeof(uint32_t)); i++) 83 ((uint32_t *)obj)[i] = i; 84 } 85 86 static void 87 test_ring_print_test_string(const char *istr, unsigned int api_type, int esize) 88 { 89 printf("\n%s: ", istr); 90 91 if (esize == -1) 92 printf("legacy APIs: "); 93 else 94 printf("elem APIs: element size %dB ", esize); 95 96 if (api_type == TEST_RING_IGNORE_API_TYPE) 97 return; 98 99 if (api_type & TEST_RING_THREAD_DEF) 100 printf(": default enqueue/dequeue: "); 101 else if (api_type & TEST_RING_THREAD_SPSC) 102 printf(": SP/SC: "); 103 else if (api_type & TEST_RING_THREAD_MPMC) 104 printf(": MP/MC: "); 105 106 if (api_type & TEST_RING_ELEM_SINGLE) 107 printf("single\n"); 108 else if (api_type & TEST_RING_ELEM_BULK) 109 printf("bulk\n"); 110 else if (api_type & TEST_RING_ELEM_BURST) 111 printf("burst\n"); 112 } 113 114 /* 115 * Various negative test cases. 116 */ 117 static int 118 test_ring_negative_tests(void) 119 { 120 struct rte_ring *rp = NULL; 121 struct rte_ring *rt = NULL; 122 unsigned int i; 123 124 /* Test with esize not a multiple of 4 */ 125 rp = test_ring_create("test_bad_element_size", 23, 126 RING_SIZE + 1, SOCKET_ID_ANY, 0); 127 if (rp != NULL) { 128 printf("Test failed to detect invalid element size\n"); 129 goto test_fail; 130 } 131 132 133 for (i = 0; i < RTE_DIM(esize); i++) { 134 /* Test if ring size is not power of 2 */ 135 rp = test_ring_create("test_bad_ring_size", esize[i], 136 RING_SIZE + 1, SOCKET_ID_ANY, 0); 137 if (rp != NULL) { 138 printf("Test failed to detect odd count\n"); 139 goto test_fail; 140 } 141 142 /* Test if ring size is exceeding the limit */ 143 rp = test_ring_create("test_bad_ring_size", esize[i], 144 RTE_RING_SZ_MASK + 1, SOCKET_ID_ANY, 0); 145 if (rp != NULL) { 146 printf("Test failed to detect limits\n"); 147 goto test_fail; 148 } 149 150 /* Tests if lookup returns NULL on non-existing ring */ 151 rp = rte_ring_lookup("ring_not_found"); 152 if (rp != NULL && rte_errno != ENOENT) { 153 printf("Test failed to detect NULL ring lookup\n"); 154 goto test_fail; 155 } 156 157 /* Test to if a non-power of 2 count causes the create 158 * function to fail correctly 159 */ 160 rp = test_ring_create("test_ring_count", esize[i], 4097, 161 SOCKET_ID_ANY, 0); 162 if (rp != NULL) 163 goto test_fail; 164 165 rp = test_ring_create("test_ring_negative", esize[i], RING_SIZE, 166 SOCKET_ID_ANY, 167 RING_F_SP_ENQ | RING_F_SC_DEQ); 168 if (rp == NULL) { 169 printf("test_ring_negative fail to create ring\n"); 170 goto test_fail; 171 } 172 173 if (rte_ring_lookup("test_ring_negative") != rp) 174 goto test_fail; 175 176 if (rte_ring_empty(rp) != 1) { 177 printf("test_ring_nagative ring is not empty but it should be\n"); 178 goto test_fail; 179 } 180 181 /* Tests if it would always fail to create ring with an used 182 * ring name. 183 */ 184 rt = test_ring_create("test_ring_negative", esize[i], RING_SIZE, 185 SOCKET_ID_ANY, 0); 186 if (rt != NULL) 187 goto test_fail; 188 189 rte_ring_free(rp); 190 rp = NULL; 191 } 192 193 return 0; 194 195 test_fail: 196 197 rte_ring_free(rp); 198 return -1; 199 } 200 201 /* 202 * Burst and bulk operations with sp/sc, mp/mc and default (during creation) 203 * Random number of elements are enqueued and dequeued. 204 */ 205 static int 206 test_ring_burst_bulk_tests1(unsigned int api_type) 207 { 208 struct rte_ring *r; 209 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; 210 int ret; 211 unsigned int i, j; 212 int rand; 213 const unsigned int rsz = RING_SIZE - 1; 214 215 for (i = 0; i < RTE_DIM(esize); i++) { 216 test_ring_print_test_string("Test standard ring", api_type, 217 esize[i]); 218 219 /* Create the ring */ 220 r = test_ring_create("test_ring_burst_bulk_tests", esize[i], 221 RING_SIZE, SOCKET_ID_ANY, 0); 222 223 /* alloc dummy object pointers */ 224 src = test_ring_calloc(RING_SIZE * 2, esize[i]); 225 if (src == NULL) 226 goto fail; 227 test_ring_mem_init(src, RING_SIZE * 2, esize[i]); 228 cur_src = src; 229 230 /* alloc some room for copied objects */ 231 dst = test_ring_calloc(RING_SIZE * 2, esize[i]); 232 if (dst == NULL) 233 goto fail; 234 cur_dst = dst; 235 236 printf("Random full/empty test\n"); 237 238 for (j = 0; j != TEST_RING_FULL_EMTPY_ITER; j++) { 239 /* random shift in the ring */ 240 rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL); 241 printf("%s: iteration %u, random shift: %u;\n", 242 __func__, i, rand); 243 ret = test_ring_enqueue(r, cur_src, esize[i], rand, 244 api_type); 245 TEST_RING_VERIFY(ret != 0); 246 247 ret = test_ring_dequeue(r, cur_dst, esize[i], rand, 248 api_type); 249 TEST_RING_VERIFY(ret == rand); 250 251 /* fill the ring */ 252 ret = test_ring_enqueue(r, cur_src, esize[i], rsz, 253 api_type); 254 TEST_RING_VERIFY(ret != 0); 255 256 TEST_RING_VERIFY(rte_ring_free_count(r) == 0); 257 TEST_RING_VERIFY(rsz == rte_ring_count(r)); 258 TEST_RING_VERIFY(rte_ring_full(r)); 259 TEST_RING_VERIFY(rte_ring_empty(r) == 0); 260 261 /* empty the ring */ 262 ret = test_ring_dequeue(r, cur_dst, esize[i], rsz, 263 api_type); 264 TEST_RING_VERIFY(ret == (int)rsz); 265 TEST_RING_VERIFY(rsz == rte_ring_free_count(r)); 266 TEST_RING_VERIFY(rte_ring_count(r) == 0); 267 TEST_RING_VERIFY(rte_ring_full(r) == 0); 268 TEST_RING_VERIFY(rte_ring_empty(r)); 269 270 /* check data */ 271 TEST_RING_VERIFY(memcmp(src, dst, rsz) == 0); 272 } 273 274 /* Free memory before test completed */ 275 rte_ring_free(r); 276 rte_free(src); 277 rte_free(dst); 278 r = NULL; 279 src = NULL; 280 dst = NULL; 281 } 282 283 return 0; 284 fail: 285 rte_ring_free(r); 286 rte_free(src); 287 rte_free(dst); 288 return -1; 289 } 290 291 /* 292 * Burst and bulk operations with sp/sc, mp/mc and default (during creation) 293 * Sequence of simple enqueues/dequeues and validate the enqueued and 294 * dequeued data. 295 */ 296 static int 297 test_ring_burst_bulk_tests2(unsigned int api_type) 298 { 299 struct rte_ring *r; 300 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; 301 int ret; 302 unsigned int i; 303 304 for (i = 0; i < RTE_DIM(esize); i++) { 305 test_ring_print_test_string("Test standard ring", api_type, 306 esize[i]); 307 308 /* Create the ring */ 309 r = test_ring_create("test_ring_burst_bulk_tests", esize[i], 310 RING_SIZE, SOCKET_ID_ANY, 0); 311 312 /* alloc dummy object pointers */ 313 src = test_ring_calloc(RING_SIZE * 2, esize[i]); 314 if (src == NULL) 315 goto fail; 316 test_ring_mem_init(src, RING_SIZE * 2, esize[i]); 317 cur_src = src; 318 319 /* alloc some room for copied objects */ 320 dst = test_ring_calloc(RING_SIZE * 2, esize[i]); 321 if (dst == NULL) 322 goto fail; 323 cur_dst = dst; 324 325 printf("enqueue 1 obj\n"); 326 ret = test_ring_enqueue(r, cur_src, esize[i], 1, api_type); 327 if (ret != 1) 328 goto fail; 329 cur_src = test_ring_inc_ptr(cur_src, esize[i], 1); 330 331 printf("enqueue 2 objs\n"); 332 ret = test_ring_enqueue(r, cur_src, esize[i], 2, api_type); 333 if (ret != 2) 334 goto fail; 335 cur_src = test_ring_inc_ptr(cur_src, esize[i], 2); 336 337 printf("enqueue MAX_BULK objs\n"); 338 ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK, 339 api_type); 340 if (ret != MAX_BULK) 341 goto fail; 342 cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK); 343 344 printf("dequeue 1 obj\n"); 345 ret = test_ring_dequeue(r, cur_dst, esize[i], 1, api_type); 346 if (ret != 1) 347 goto fail; 348 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1); 349 350 printf("dequeue 2 objs\n"); 351 ret = test_ring_dequeue(r, cur_dst, esize[i], 2, api_type); 352 if (ret != 2) 353 goto fail; 354 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2); 355 356 printf("dequeue MAX_BULK objs\n"); 357 ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK, 358 api_type); 359 if (ret != MAX_BULK) 360 goto fail; 361 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK); 362 363 /* check data */ 364 if (memcmp(src, dst, cur_dst - dst)) { 365 rte_hexdump(stdout, "src", src, cur_src - src); 366 rte_hexdump(stdout, "dst", dst, cur_dst - dst); 367 printf("data after dequeue is not the same\n"); 368 goto fail; 369 } 370 371 /* Free memory before test completed */ 372 rte_ring_free(r); 373 rte_free(src); 374 rte_free(dst); 375 r = NULL; 376 src = NULL; 377 dst = NULL; 378 } 379 380 return 0; 381 fail: 382 rte_ring_free(r); 383 rte_free(src); 384 rte_free(dst); 385 return -1; 386 } 387 388 /* 389 * Burst and bulk operations with sp/sc, mp/mc and default (during creation) 390 * Enqueue and dequeue to cover the entire ring length. 391 */ 392 static int 393 test_ring_burst_bulk_tests3(unsigned int api_type) 394 { 395 struct rte_ring *r; 396 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; 397 int ret; 398 unsigned int i, j; 399 400 for (i = 0; i < RTE_DIM(esize); i++) { 401 test_ring_print_test_string("Test standard ring", api_type, 402 esize[i]); 403 404 /* Create the ring */ 405 r = test_ring_create("test_ring_burst_bulk_tests", esize[i], 406 RING_SIZE, SOCKET_ID_ANY, 0); 407 408 /* alloc dummy object pointers */ 409 src = test_ring_calloc(RING_SIZE * 2, esize[i]); 410 if (src == NULL) 411 goto fail; 412 test_ring_mem_init(src, RING_SIZE * 2, esize[i]); 413 cur_src = src; 414 415 /* alloc some room for copied objects */ 416 dst = test_ring_calloc(RING_SIZE * 2, esize[i]); 417 if (dst == NULL) 418 goto fail; 419 cur_dst = dst; 420 421 printf("fill and empty the ring\n"); 422 for (j = 0; j < RING_SIZE / MAX_BULK; j++) { 423 ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK, 424 api_type); 425 if (ret != MAX_BULK) 426 goto fail; 427 cur_src = test_ring_inc_ptr(cur_src, esize[i], 428 MAX_BULK); 429 430 ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK, 431 api_type); 432 if (ret != MAX_BULK) 433 goto fail; 434 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 435 MAX_BULK); 436 } 437 438 /* check data */ 439 if (memcmp(src, dst, cur_dst - dst)) { 440 rte_hexdump(stdout, "src", src, cur_src - src); 441 rte_hexdump(stdout, "dst", dst, cur_dst - dst); 442 printf("data after dequeue is not the same\n"); 443 goto fail; 444 } 445 446 /* Free memory before test completed */ 447 rte_ring_free(r); 448 rte_free(src); 449 rte_free(dst); 450 r = NULL; 451 src = NULL; 452 dst = NULL; 453 } 454 455 return 0; 456 fail: 457 rte_ring_free(r); 458 rte_free(src); 459 rte_free(dst); 460 return -1; 461 } 462 463 /* 464 * Burst and bulk operations with sp/sc, mp/mc and default (during creation) 465 * Enqueue till the ring is full and dequeue till the ring becomes empty. 466 */ 467 static int 468 test_ring_burst_bulk_tests4(unsigned int api_type) 469 { 470 struct rte_ring *r; 471 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; 472 int ret; 473 unsigned int i, j; 474 unsigned int num_elems; 475 476 for (i = 0; i < RTE_DIM(esize); i++) { 477 test_ring_print_test_string("Test standard ring", api_type, 478 esize[i]); 479 480 /* Create the ring */ 481 r = test_ring_create("test_ring_burst_bulk_tests", esize[i], 482 RING_SIZE, SOCKET_ID_ANY, 0); 483 484 /* alloc dummy object pointers */ 485 src = test_ring_calloc(RING_SIZE * 2, esize[i]); 486 if (src == NULL) 487 goto fail; 488 test_ring_mem_init(src, RING_SIZE * 2, esize[i]); 489 cur_src = src; 490 491 /* alloc some room for copied objects */ 492 dst = test_ring_calloc(RING_SIZE * 2, esize[i]); 493 if (dst == NULL) 494 goto fail; 495 cur_dst = dst; 496 497 printf("Test enqueue without enough memory space\n"); 498 for (j = 0; j < (RING_SIZE/MAX_BULK - 1); j++) { 499 ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK, 500 api_type); 501 if (ret != MAX_BULK) 502 goto fail; 503 cur_src = test_ring_inc_ptr(cur_src, esize[i], 504 MAX_BULK); 505 } 506 507 printf("Enqueue 2 objects, free entries = MAX_BULK - 2\n"); 508 ret = test_ring_enqueue(r, cur_src, esize[i], 2, api_type); 509 if (ret != 2) 510 goto fail; 511 cur_src = test_ring_inc_ptr(cur_src, esize[i], 2); 512 513 printf("Enqueue the remaining entries = MAX_BULK - 3\n"); 514 /* Bulk APIs enqueue exact number of elements */ 515 if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK) 516 num_elems = MAX_BULK - 3; 517 else 518 num_elems = MAX_BULK; 519 /* Always one free entry left */ 520 ret = test_ring_enqueue(r, cur_src, esize[i], num_elems, 521 api_type); 522 if (ret != MAX_BULK - 3) 523 goto fail; 524 cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK - 3); 525 526 printf("Test if ring is full\n"); 527 if (rte_ring_full(r) != 1) 528 goto fail; 529 530 printf("Test enqueue for a full entry\n"); 531 ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK, 532 api_type); 533 if (ret != 0) 534 goto fail; 535 536 printf("Test dequeue without enough objects\n"); 537 for (j = 0; j < RING_SIZE / MAX_BULK - 1; j++) { 538 ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK, 539 api_type); 540 if (ret != MAX_BULK) 541 goto fail; 542 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 543 MAX_BULK); 544 } 545 546 /* Available memory space for the exact MAX_BULK entries */ 547 ret = test_ring_dequeue(r, cur_dst, esize[i], 2, api_type); 548 if (ret != 2) 549 goto fail; 550 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2); 551 552 /* Bulk APIs enqueue exact number of elements */ 553 if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK) 554 num_elems = MAX_BULK - 3; 555 else 556 num_elems = MAX_BULK; 557 ret = test_ring_dequeue(r, cur_dst, esize[i], num_elems, 558 api_type); 559 if (ret != MAX_BULK - 3) 560 goto fail; 561 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK - 3); 562 563 printf("Test if ring is empty\n"); 564 /* Check if ring is empty */ 565 if (rte_ring_empty(r) != 1) 566 goto fail; 567 568 /* check data */ 569 if (memcmp(src, dst, cur_dst - dst)) { 570 rte_hexdump(stdout, "src", src, cur_src - src); 571 rte_hexdump(stdout, "dst", dst, cur_dst - dst); 572 printf("data after dequeue is not the same\n"); 573 goto fail; 574 } 575 576 /* Free memory before test completed */ 577 rte_ring_free(r); 578 rte_free(src); 579 rte_free(dst); 580 r = NULL; 581 src = NULL; 582 dst = NULL; 583 } 584 585 return 0; 586 fail: 587 rte_ring_free(r); 588 rte_free(src); 589 rte_free(dst); 590 return -1; 591 } 592 593 /* 594 * Test default, single element, bulk and burst APIs 595 */ 596 static int 597 test_ring_basic_ex(void) 598 { 599 int ret = -1; 600 unsigned int i, j; 601 struct rte_ring *rp = NULL; 602 void *obj = NULL; 603 604 for (i = 0; i < RTE_DIM(esize); i++) { 605 obj = test_ring_calloc(RING_SIZE, esize[i]); 606 if (obj == NULL) { 607 printf("%s: failed to alloc memory\n", __func__); 608 goto fail_test; 609 } 610 611 rp = test_ring_create("test_ring_basic_ex", esize[i], RING_SIZE, 612 SOCKET_ID_ANY, 613 RING_F_SP_ENQ | RING_F_SC_DEQ); 614 if (rp == NULL) { 615 printf("%s: failed to create ring\n", __func__); 616 goto fail_test; 617 } 618 619 if (rte_ring_lookup("test_ring_basic_ex") != rp) { 620 printf("%s: failed to find ring\n", __func__); 621 goto fail_test; 622 } 623 624 if (rte_ring_empty(rp) != 1) { 625 printf("%s: ring is not empty but it should be\n", 626 __func__); 627 goto fail_test; 628 } 629 630 printf("%u ring entries are now free\n", 631 rte_ring_free_count(rp)); 632 633 for (j = 0; j < RING_SIZE; j++) { 634 test_ring_enqueue(rp, obj, esize[i], 1, 635 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); 636 } 637 638 if (rte_ring_full(rp) != 1) { 639 printf("%s: ring is not full but it should be\n", 640 __func__); 641 goto fail_test; 642 } 643 644 for (j = 0; j < RING_SIZE; j++) { 645 test_ring_dequeue(rp, obj, esize[i], 1, 646 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); 647 } 648 649 if (rte_ring_empty(rp) != 1) { 650 printf("%s: ring is not empty but it should be\n", 651 __func__); 652 goto fail_test; 653 } 654 655 /* Following tests use the configured flags to decide 656 * SP/SC or MP/MC. 657 */ 658 /* Covering the ring burst operation */ 659 ret = test_ring_enqueue(rp, obj, esize[i], 2, 660 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST); 661 if (ret != 2) { 662 printf("%s: rte_ring_enqueue_burst fails\n", __func__); 663 goto fail_test; 664 } 665 666 ret = test_ring_dequeue(rp, obj, esize[i], 2, 667 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST); 668 if (ret != 2) { 669 printf("%s: rte_ring_dequeue_burst fails\n", __func__); 670 goto fail_test; 671 } 672 673 /* Covering the ring bulk operation */ 674 ret = test_ring_enqueue(rp, obj, esize[i], 2, 675 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK); 676 if (ret != 2) { 677 printf("%s: rte_ring_enqueue_bulk fails\n", __func__); 678 goto fail_test; 679 } 680 681 ret = test_ring_dequeue(rp, obj, esize[i], 2, 682 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK); 683 if (ret != 2) { 684 printf("%s: rte_ring_dequeue_bulk fails\n", __func__); 685 goto fail_test; 686 } 687 688 rte_ring_free(rp); 689 rte_free(obj); 690 rp = NULL; 691 obj = NULL; 692 } 693 694 return 0; 695 696 fail_test: 697 rte_ring_free(rp); 698 if (obj != NULL) 699 rte_free(obj); 700 701 return -1; 702 } 703 704 /* 705 * Basic test cases with exact size ring. 706 */ 707 static int 708 test_ring_with_exact_size(void) 709 { 710 struct rte_ring *std_r = NULL, *exact_sz_r = NULL; 711 void *obj_orig; 712 void *obj; 713 const unsigned int ring_sz = 16; 714 unsigned int i, j; 715 int ret = -1; 716 717 for (i = 0; i < RTE_DIM(esize); i++) { 718 test_ring_print_test_string("Test exact size ring", 719 TEST_RING_IGNORE_API_TYPE, 720 esize[i]); 721 722 /* alloc object pointers. Allocate one extra object 723 * and create an unaligned address. 724 */ 725 obj_orig = test_ring_calloc(17, esize[i]); 726 if (obj_orig == NULL) 727 goto test_fail; 728 obj = ((char *)obj_orig) + 1; 729 730 std_r = test_ring_create("std", esize[i], ring_sz, 731 rte_socket_id(), 732 RING_F_SP_ENQ | RING_F_SC_DEQ); 733 if (std_r == NULL) { 734 printf("%s: error, can't create std ring\n", __func__); 735 goto test_fail; 736 } 737 exact_sz_r = test_ring_create("exact sz", esize[i], ring_sz, 738 rte_socket_id(), 739 RING_F_SP_ENQ | RING_F_SC_DEQ | 740 RING_F_EXACT_SZ); 741 if (exact_sz_r == NULL) { 742 printf("%s: error, can't create exact size ring\n", 743 __func__); 744 goto test_fail; 745 } 746 747 /* 748 * Check that the exact size ring is bigger than the 749 * standard ring 750 */ 751 if (rte_ring_get_size(std_r) >= rte_ring_get_size(exact_sz_r)) { 752 printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", 753 __func__, 754 rte_ring_get_size(std_r), 755 rte_ring_get_size(exact_sz_r)); 756 goto test_fail; 757 } 758 /* 759 * check that the exact_sz_ring can hold one more element 760 * than the standard ring. (16 vs 15 elements) 761 */ 762 for (j = 0; j < ring_sz - 1; j++) { 763 test_ring_enqueue(std_r, obj, esize[i], 1, 764 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); 765 test_ring_enqueue(exact_sz_r, obj, esize[i], 1, 766 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); 767 } 768 ret = test_ring_enqueue(std_r, obj, esize[i], 1, 769 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); 770 if (ret != -ENOBUFS) { 771 printf("%s: error, unexpected successful enqueue\n", 772 __func__); 773 goto test_fail; 774 } 775 ret = test_ring_enqueue(exact_sz_r, obj, esize[i], 1, 776 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); 777 if (ret == -ENOBUFS) { 778 printf("%s: error, enqueue failed\n", __func__); 779 goto test_fail; 780 } 781 782 /* check that dequeue returns the expected number of elements */ 783 ret = test_ring_dequeue(exact_sz_r, obj, esize[i], ring_sz, 784 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST); 785 if (ret != (int)ring_sz) { 786 printf("%s: error, failed to dequeue expected nb of elements\n", 787 __func__); 788 goto test_fail; 789 } 790 791 /* check that the capacity function returns expected value */ 792 if (rte_ring_get_capacity(exact_sz_r) != ring_sz) { 793 printf("%s: error, incorrect ring capacity reported\n", 794 __func__); 795 goto test_fail; 796 } 797 798 rte_free(obj_orig); 799 rte_ring_free(std_r); 800 rte_ring_free(exact_sz_r); 801 obj_orig = NULL; 802 std_r = NULL; 803 exact_sz_r = NULL; 804 } 805 806 return 0; 807 808 test_fail: 809 rte_free(obj_orig); 810 rte_ring_free(std_r); 811 rte_ring_free(exact_sz_r); 812 return -1; 813 } 814 815 static int 816 test_ring(void) 817 { 818 unsigned int i, j; 819 820 /* Negative test cases */ 821 if (test_ring_negative_tests() < 0) 822 goto test_fail; 823 824 /* Some basic operations */ 825 if (test_ring_basic_ex() < 0) 826 goto test_fail; 827 828 if (test_ring_with_exact_size() < 0) 829 goto test_fail; 830 831 /* Burst and bulk operations with sp/sc, mp/mc and default. 832 * The test cases are split into smaller test cases to 833 * help clang compile faster. 834 */ 835 for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) 836 for (i = TEST_RING_THREAD_DEF; 837 i <= TEST_RING_THREAD_MPMC; i <<= 1) 838 if (test_ring_burst_bulk_tests1(i | j) < 0) 839 goto test_fail; 840 841 for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) 842 for (i = TEST_RING_THREAD_DEF; 843 i <= TEST_RING_THREAD_MPMC; i <<= 1) 844 if (test_ring_burst_bulk_tests2(i | j) < 0) 845 goto test_fail; 846 847 for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) 848 for (i = TEST_RING_THREAD_DEF; 849 i <= TEST_RING_THREAD_MPMC; i <<= 1) 850 if (test_ring_burst_bulk_tests3(i | j) < 0) 851 goto test_fail; 852 853 for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) 854 for (i = TEST_RING_THREAD_DEF; 855 i <= TEST_RING_THREAD_MPMC; i <<= 1) 856 if (test_ring_burst_bulk_tests4(i | j) < 0) 857 goto test_fail; 858 859 /* dump the ring status */ 860 rte_ring_list_dump(stdout); 861 862 return 0; 863 864 test_fail: 865 866 return -1; 867 } 868 869 REGISTER_TEST_COMMAND(ring_autotest, test_ring); 870