1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2024 Huawei Technologies Co., Ltd 3 */ 4 5 #ifndef _RTE_SORING_H_ 6 #define _RTE_SORING_H_ 7 8 /** 9 * @file 10 * This file contains definition of DPDK soring (Staged Ordered Ring) 11 * public API. 12 * Brief description: 13 * enqueue/dequeue works the same as for conventional rte_ring: 14 * any rte_ring sync types can be used, etc. 15 * Plus there could be multiple 'stages'. 16 * For each stage there is an acquire (start) and release (finish) operation. 17 * after some elems are 'acquired' - user can safely assume having 18 * exclusive possession of these elems till 'release' for them is done. 19 * Note that right now user has to release exactly the same number of elems 20 * acquired before. 21 * After 'release', elems can be 'acquired' by next stage and/or dequeued 22 * (in case of last stage). 23 * Extra debugging might be enabled with RTE_SORING_DEBUG macro. 24 */ 25 26 #include <rte_ring.h> 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /** upper 2 bits are used for status */ 33 #define RTE_SORING_ST_BIT 30 34 35 /** max possible number of elements in the soring */ 36 #define RTE_SORING_ELEM_MAX (RTE_BIT32(RTE_SORING_ST_BIT) - 1) 37 38 struct rte_soring_param { 39 /** expected name of the soring */ 40 const char *name; 41 /** number of elements in the soring */ 42 uint32_t elems; 43 /** size of elements in the soring, must be a multiple of 4 */ 44 uint32_t elem_size; 45 /** 46 * size of metadata for each elem, must be a multiple of 4. 47 * This parameter defines a size of supplementary and optional 48 * array of metadata associated with each object in the soring. 49 * While element size is configurable (see 'elem_size' parameter above), 50 * so user can specify it big enough to hold both object and its 51 * metadata together, for performance reasons it might be plausible 52 * to access them as separate arrays. 53 * Common usage scenario when such separation helps: 54 * enqueue() - writes to objects array 55 * acquire() - reads from objects array 56 * release() - writes to metadata array (as an example: return code) 57 * dequeue() - reads both objects and metadata array 58 */ 59 uint32_t meta_size; 60 /** number of stages in the soring */ 61 uint32_t stages; 62 /** sync type for producer */ 63 enum rte_ring_sync_type prod_synt; 64 /** sync type for consumer */ 65 enum rte_ring_sync_type cons_synt; 66 }; 67 68 struct rte_soring; 69 70 /** 71 * @warning 72 * @b EXPERIMENTAL: this API may change without prior notice. 73 * 74 * Calculate the memory size needed for a soring 75 * 76 * This function returns the number of bytes needed for a soring, given 77 * the expected parameters for it. This value is the sum of the size of 78 * the internal metadata and the size of the memory needed by the 79 * actual soring elements and their metadata. The value is aligned to a cache 80 * line size. 81 * 82 * @param prm 83 * Pointer to the structure that contains soring creation parameters. 84 * @return 85 * - The memory size needed for the soring on success. 86 * - -EINVAL if provided parameter values are invalid. 87 */ 88 __rte_experimental 89 ssize_t 90 rte_soring_get_memsize(const struct rte_soring_param *prm); 91 92 /** 93 * @warning 94 * @b EXPERIMENTAL: this API may change without prior notice. 95 * 96 * Initialize a soring structure. 97 * 98 * Initialize a soring structure in memory pointed by "r". 99 * The size of the memory area must be large enough to store the soring 100 * internal structures plus the objects and metadata tables. 101 * It is strongly advised to use @ref rte_soring_get_memsize() to get the 102 * appropriate size. 103 * 104 * @param r 105 * Pointer to the soring structure. 106 * @param prm 107 * Pointer to the structure that contains soring creation parameters. 108 * @return 109 * - 0 on success, or a negative error code. 110 */ 111 __rte_experimental 112 int 113 rte_soring_init(struct rte_soring *r, const struct rte_soring_param *prm); 114 115 /** 116 * @warning 117 * @b EXPERIMENTAL: this API may change without prior notice. 118 * 119 * Return the total number of filled entries in a soring. 120 * 121 * @param r 122 * A pointer to the soring structure. 123 * @return 124 * The number of entries in the soring. 125 */ 126 __rte_experimental 127 unsigned int 128 rte_soring_count(const struct rte_soring *r); 129 130 /** 131 * @warning 132 * @b EXPERIMENTAL: this API may change without prior notice. 133 * 134 * Return the total number of unfilled entries in a soring. 135 * 136 * @param r 137 * A pointer to the soring structure. 138 * @return 139 * The number of free entries in the soring. 140 */ 141 __rte_experimental 142 unsigned int 143 rte_soring_free_count(const struct rte_soring *r); 144 145 /** 146 * @warning 147 * @b EXPERIMENTAL: this API may change without prior notice. 148 * 149 * Dump the status of the soring 150 * 151 * @param f 152 * A pointer to a file for output 153 * @param r 154 * Pointer to the soring structure. 155 */ 156 __rte_experimental 157 void 158 rte_soring_dump(FILE *f, const struct rte_soring *r); 159 160 /** 161 * @warning 162 * @b EXPERIMENTAL: this API may change without prior notice. 163 * 164 * Enqueue several objects on the soring. 165 * Enqueues exactly requested number of objects or none. 166 * 167 * @param r 168 * A pointer to the soring structure. 169 * @param objs 170 * A pointer to an array of objects to enqueue. 171 * Size of objects to enqueue must be the same value as 'elem_size' parameter 172 * used while creating the soring. Otherwise the results are undefined. 173 * @param n 174 * The number of objects to add in the soring from the 'objs'. 175 * @param free_space 176 * if non-NULL, returns the amount of space in the soring after the 177 * enqueue operation has finished. 178 * @return 179 * - Actual number of objects enqueued, either 0 or n. 180 */ 181 __rte_experimental 182 uint32_t 183 rte_soring_enqueue_bulk(struct rte_soring *r, const void *objs, 184 uint32_t n, uint32_t *free_space); 185 186 /** 187 * @warning 188 * @b EXPERIMENTAL: this API may change without prior notice. 189 * 190 * Enqueue several objects plus metadata on the soring. 191 * Enqueues exactly requested number of objects or none. 192 * 193 * @param r 194 * A pointer to the soring structure. 195 * @param objs 196 * A pointer to an array of objects to enqueue. 197 * Size of objects to enqueue must be the same value as 'elem_size' parameter 198 * used while creating the soring. Otherwise the results are undefined. 199 * @param meta 200 * A pointer to an array of metadata values for each object to enqueue. 201 * Note that if user not using object metadata values, then this parameter 202 * can be NULL. 203 * Size of elements in this array must be the same value as 'meta_size' 204 * parameter used while creating the soring. If user created the soring with 205 * 'meta_size' value equals zero, then 'meta' parameter should be NULL. 206 * Otherwise the results are undefined. 207 * @param n 208 * The number of objects to add in the soring from the 'objs'. 209 * @param free_space 210 * if non-NULL, returns the amount of space in the soring after the 211 * enqueue operation has finished. 212 * @return 213 * - Actual number of objects enqueued, either 0 or n. 214 */ 215 __rte_experimental 216 uint32_t 217 rte_soring_enqueux_bulk(struct rte_soring *r, const void *objs, 218 const void *meta, uint32_t n, uint32_t *free_space); 219 220 /** 221 * @warning 222 * @b EXPERIMENTAL: this API may change without prior notice. 223 * 224 * Enqueue several objects on the soring. 225 * Enqueues up to requested number of objects. 226 * 227 * @param r 228 * A pointer to the soring structure. 229 * @param objs 230 * A pointer to an array of objects to enqueue. 231 * Size of objects to enqueue must be the same value as 'elem_size' parameter 232 * used while creating the soring. Otherwise the results are undefined. 233 * @param n 234 * The number of objects to add in the soring from the 'objs'. 235 * @param free_space 236 * if non-NULL, returns the amount of space in the soring after the 237 * enqueue operation has finished. 238 * @return 239 * - Actual number of objects enqueued. 240 */ 241 __rte_experimental 242 uint32_t 243 rte_soring_enqueue_burst(struct rte_soring *r, const void *objs, 244 uint32_t n, uint32_t *free_space); 245 246 /** 247 * @warning 248 * @b EXPERIMENTAL: this API may change without prior notice. 249 * 250 * Enqueue several objects plus metadata on the soring. 251 * Enqueues up to requested number of objects. 252 * 253 * @param r 254 * A pointer to the soring structure. 255 * @param objs 256 * A pointer to an array of objects to enqueue. 257 * Size of objects to enqueue must be the same value as 'elem_size' parameter 258 * used while creating the soring. Otherwise the results are undefined. 259 * @param meta 260 * A pointer to an array of metadata values for each object to enqueue. 261 * Note that if user not using object metadata values, then this parameter 262 * can be NULL. 263 * Size of elements in this array must be the same value as 'meta_size' 264 * parameter used while creating the soring. If user created the soring with 265 * 'meta_size' value equals zero, then 'meta' parameter should be NULL. 266 * Otherwise the results are undefined. 267 * @param n 268 * The number of objects to add in the soring from the 'objs'. 269 * @param free_space 270 * if non-NULL, returns the amount of space in the soring after the 271 * enqueue operation has finished. 272 * @return 273 * - Actual number of objects enqueued. 274 */ 275 __rte_experimental 276 uint32_t 277 rte_soring_enqueux_burst(struct rte_soring *r, const void *objs, 278 const void *meta, uint32_t n, uint32_t *free_space); 279 280 /** 281 * @warning 282 * @b EXPERIMENTAL: this API may change without prior notice. 283 * 284 * Dequeue several objects from the soring. 285 * Dequeues exactly requested number of objects or none. 286 * 287 * @param r 288 * A pointer to the soring structure. 289 * @param objs 290 * A pointer to an array of objects to dequeue. 291 * Size of objects to enqueue must be the same value as 'elem_size' parameter 292 * used while creating the soring. Otherwise the results are undefined. 293 * @param num 294 * The number of objects to dequeue from the soring into the objs. 295 * @param available 296 * If non-NULL, returns the number of remaining soring entries after the 297 * dequeue has finished. 298 * @return 299 * - Actual number of objects dequeued, either 0 or 'num'. 300 */ 301 __rte_experimental 302 uint32_t 303 rte_soring_dequeue_bulk(struct rte_soring *r, void *objs, 304 uint32_t num, uint32_t *available); 305 306 /** 307 * @warning 308 * @b EXPERIMENTAL: this API may change without prior notice. 309 * 310 * Dequeue several objects plus metadata from the soring. 311 * Dequeues exactly requested number of objects or none. 312 * 313 * @param r 314 * A pointer to the soring structure. 315 * @param objs 316 * A pointer to an array of objects to dequeue. 317 * Size of objects to enqueue must be the same value as 'elem_size' parameter 318 * used while creating the soring. Otherwise the results are undefined. 319 * @param meta 320 * A pointer to array of metadata values for each object to dequeue. 321 * Note that if user not using object metadata values, then this parameter 322 * can be NULL. 323 * Size of elements in this array must be the same value as 'meta_size' 324 * parameter used while creating the soring. If user created the soring with 325 * 'meta_size' value equals zero, then 'meta' parameter should be NULL. 326 * Otherwise the results are undefined. 327 * @param num 328 * The number of objects to dequeue from the soring into the objs. 329 * @param available 330 * If non-NULL, returns the number of remaining soring entries after the 331 * dequeue has finished. 332 * @return 333 * - Actual number of objects dequeued, either 0 or 'num'. 334 */ 335 __rte_experimental 336 uint32_t 337 rte_soring_dequeux_bulk(struct rte_soring *r, void *objs, void *meta, 338 uint32_t num, uint32_t *available); 339 340 /** 341 * @warning 342 * @b EXPERIMENTAL: this API may change without prior notice. 343 * 344 * Dequeue several objects from the soring. 345 * Dequeues up to requested number of objects. 346 * 347 * @param r 348 * A pointer to the soring structure. 349 * @param objs 350 * A pointer to an array of objects to dequeue. 351 * Size of objects to enqueue must be the same value as 'elem_size' parameter 352 * used while creating the soring. Otherwise the results are undefined. 353 * @param num 354 * The number of objects to dequeue from the soring into the objs. 355 * @param available 356 * If non-NULL, returns the number of remaining soring entries after the 357 * dequeue has finished. 358 * @return 359 * - Actual number of objects dequeued. 360 */ 361 __rte_experimental 362 uint32_t 363 rte_soring_dequeue_burst(struct rte_soring *r, void *objs, 364 uint32_t num, uint32_t *available); 365 366 /** 367 * @warning 368 * @b EXPERIMENTAL: this API may change without prior notice. 369 * 370 * Dequeue several objects plus metadata from the soring. 371 * Dequeues up to requested number of objects. 372 * 373 * @param r 374 * A pointer to the soring structure. 375 * @param objs 376 * A pointer to an array of objects to dequeue. 377 * Size of objects to enqueue must be the same value as 'elem_size' parameter 378 * used while creating the soring. Otherwise the results are undefined. 379 * @param meta 380 * A pointer to array of metadata values for each object to dequeue. 381 * Note that if user not using object metadata values, then this parameter 382 * can be NULL. 383 * Size of elements in this array must be the same value as 'meta_size' 384 * parameter used while creating the soring. If user created the soring with 385 * 'meta_size' value equals zero, then 'meta' parameter should be NULL. 386 * Otherwise the results are undefined. 387 * @param num 388 * The number of objects to dequeue from the soring into the objs. 389 * @param available 390 * If non-NULL, returns the number of remaining soring entries after the 391 * dequeue has finished. 392 * @return 393 * - Actual number of objects dequeued. 394 */ 395 __rte_experimental 396 uint32_t 397 rte_soring_dequeux_burst(struct rte_soring *r, void *objs, void *meta, 398 uint32_t num, uint32_t *available); 399 400 /** 401 * @warning 402 * @b EXPERIMENTAL: this API may change without prior notice. 403 * 404 * Acquire several objects from the soring for given stage. 405 * Acquires exactly requested number of objects or none. 406 * 407 * @param r 408 * A pointer to the soring structure. 409 * @param objs 410 * A pointer to an array of objects to acquire. 411 * Size of objects must be the same value as 'elem_size' parameter 412 * used while creating the soring. Otherwise the results are undefined. 413 * @param stage 414 * Stage to acquire objects for. 415 * @param num 416 * The number of objects to acquire. 417 * @param ftoken 418 * Pointer to the opaque 'token' value used by release() op. 419 * User has to store this value somewhere, and later provide to the 420 * release(). 421 * @param available 422 * If non-NULL, returns the number of remaining soring entries for given stage 423 * after the acquire has finished. 424 * @return 425 * - Actual number of objects acquired, either 0 or 'num'. 426 */ 427 __rte_experimental 428 uint32_t 429 rte_soring_acquire_bulk(struct rte_soring *r, void *objs, 430 uint32_t stage, uint32_t num, uint32_t *ftoken, uint32_t *available); 431 432 /** 433 * @warning 434 * @b EXPERIMENTAL: this API may change without prior notice. 435 * 436 * Acquire several objects plus metadata from the soring for given stage. 437 * Acquires exactly requested number of objects or none. 438 * 439 * @param r 440 * A pointer to the soring structure. 441 * @param objs 442 * A pointer to an array of objects to acquire. 443 * Size of objects must be the same value as 'elem_size' parameter 444 * used while creating the soring. Otherwise the results are undefined. 445 * @param meta 446 * A pointer to an array of metadata values for each for each acquired object. 447 * Note that if user not using object metadata values, then this parameter 448 * can be NULL. 449 * Size of elements in this array must be the same value as 'meta_size' 450 * parameter used while creating the soring. If user created the soring with 451 * 'meta_size' value equals zero, then 'meta' parameter should be NULL. 452 * Otherwise the results are undefined. 453 * @param stage 454 * Stage to acquire objects for. 455 * @param num 456 * The number of objects to acquire. 457 * @param ftoken 458 * Pointer to the opaque 'token' value used by release() op. 459 * User has to store this value somewhere, and later provide to the 460 * release(). 461 * @param available 462 * If non-NULL, returns the number of remaining soring entries for given stage 463 * after the acquire has finished. 464 * @return 465 * - Actual number of objects acquired, either 0 or 'num'. 466 */ 467 __rte_experimental 468 uint32_t 469 rte_soring_acquirx_bulk(struct rte_soring *r, void *objs, void *meta, 470 uint32_t stage, uint32_t num, uint32_t *ftoken, uint32_t *available); 471 472 /** 473 * @warning 474 * @b EXPERIMENTAL: this API may change without prior notice. 475 * 476 * Acquire several objects from the soring for given stage. 477 * Acquires up to requested number of objects. 478 * 479 * @param r 480 * A pointer to the soring structure. 481 * @param objs 482 * A pointer to an array of objects to acquire. 483 * Size of objects must be the same value as 'elem_size' parameter 484 * used while creating the soring. Otherwise the results are undefined. 485 * @param stage 486 * Stage to acquire objects for. 487 * @param num 488 * The number of objects to acquire. 489 * @param ftoken 490 * Pointer to the opaque 'token' value used by release() op. 491 * User has to store this value somewhere, and later provide to the 492 * release(). 493 * @param available 494 * If non-NULL, returns the number of remaining soring entries for given stage 495 * after the acquire has finished. 496 * @return 497 * - Actual number of objects acquired. 498 */ 499 __rte_experimental 500 uint32_t 501 rte_soring_acquire_burst(struct rte_soring *r, void *objs, 502 uint32_t stage, uint32_t num, uint32_t *ftoken, uint32_t *available); 503 504 /** 505 * @warning 506 * @b EXPERIMENTAL: this API may change without prior notice. 507 * 508 * Acquire several objects plus metadata from the soring for given stage. 509 * Acquires up to requested number of objects. 510 * 511 * @param r 512 * A pointer to the soring structure. 513 * @param objs 514 * A pointer to an array of objects to acquire. 515 * Size of objects must be the same value as 'elem_size' parameter 516 * used while creating the soring. Otherwise the results are undefined. 517 * @param meta 518 * A pointer to an array of metadata values for each for each acquired object. 519 * Note that if user not using object metadata values, then this parameter 520 * can be NULL. 521 * Size of elements in this array must be the same value as 'meta_size' 522 * parameter used while creating the soring. If user created the soring with 523 * 'meta_size' value equals zero, then 'meta' parameter should be NULL. 524 * Otherwise the results are undefined. 525 * @param stage 526 * Stage to acquire objects for. 527 * @param num 528 * The number of objects to acquire. 529 * @param ftoken 530 * Pointer to the opaque 'token' value used by release() op. 531 * User has to store this value somewhere, and later provide to the 532 * release(). 533 * @param available 534 * If non-NULL, returns the number of remaining soring entries for given stage 535 * after the acquire has finished. 536 * @return 537 * - Actual number of objects acquired. 538 */ 539 __rte_experimental 540 uint32_t 541 rte_soring_acquirx_burst(struct rte_soring *r, void *objs, void *meta, 542 uint32_t stage, uint32_t num, uint32_t *ftoken, uint32_t *available); 543 544 /** 545 * @warning 546 * @b EXPERIMENTAL: this API may change without prior notice. 547 * 548 * Release several objects for given stage back to the soring. 549 * Note that it means these objects become available for next stage or 550 * dequeue. 551 * 552 * @param r 553 * A pointer to the soring structure. 554 * @param objs 555 * A pointer to an array of objects to release. 556 * Note that unless user needs to overwrite soring objects this parameter 557 * can be NULL. 558 * Size of objects must be the same value as 'elem_size' parameter 559 * used while creating the soring. Otherwise the results are undefined. 560 * @param stage 561 * Current stage. 562 * @param n 563 * The number of objects to release. 564 * Has to be the same value as returned by acquire() op. 565 * @param ftoken 566 * Opaque 'token' value obtained from acquire() op. 567 */ 568 __rte_experimental 569 void 570 rte_soring_release(struct rte_soring *r, const void *objs, 571 uint32_t stage, uint32_t n, uint32_t ftoken); 572 573 /** 574 * @warning 575 * @b EXPERIMENTAL: this API may change without prior notice. 576 * 577 * Release several objects plus metadata for given stage back to the soring. 578 * Note that it means these objects become available for next stage or 579 * dequeue. 580 * 581 * @param r 582 * A pointer to the soring structure. 583 * @param objs 584 * A pointer to an array of objects to release. 585 * Note that unless user needs to overwrite soring objects this parameter 586 * can be NULL. 587 * Size of objects must be the same value as 'elem_size' parameter 588 * used while creating the soring. Otherwise the results are undefined. 589 * @param meta 590 * A pointer to an array of metadata values for each object to release. 591 * Note that if user not using object metadata values, then this parameter 592 * can be NULL. 593 * Size of elements in this array must be the same value as 'meta_size' 594 * parameter used while creating the soring. If user created the soring with 595 * 'meta_size' value equals zero, then meta parameter should be NULL. 596 * Otherwise the results are undefined. 597 * @param stage 598 * Current stage. 599 * @param n 600 * The number of objects to release. 601 * Has to be the same value as returned by acquire() op. 602 * @param ftoken 603 * Opaque 'token' value obtained from acquire() op. 604 */ 605 __rte_experimental 606 void 607 rte_soring_releasx(struct rte_soring *r, const void *objs, 608 const void *meta, uint32_t stage, uint32_t n, uint32_t ftoken); 609 610 #ifdef __cplusplus 611 } 612 #endif 613 614 #endif /* _RTE_SORING_H_ */ 615