xref: /dpdk/lib/ring/rte_soring.h (revision b5458e2cc48349b314c7354e4ddfd2100bd55c29)
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