xref: /dpdk/lib/ring/soring.h (revision b5458e2cc48349b314c7354e4ddfd2100bd55c29)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2024 Huawei Technologies Co., Ltd
3  */
4 
5 #ifndef _SORING_H_
6 #define _SORING_H_
7 
8 /**
9  * @file
10  * This file contains internal structures of DPDK soring: Staged Ordered Ring.
11  * Sort of extension of conventional DPDK ring.
12  * Internal structure:
13  * In addition to 'normal' ring of elems, it also has a ring of states of the
14  * same size. Each state[] corresponds to exactly one elem[].
15  * state[] will be used by acquire/release/dequeue functions to store internal
16  * information and should not be accessed by the user directly.
17  * For actual implementation details, please refer to soring.c
18  */
19 
20 #include <rte_soring.h>
21 
22 /* logging stuff, register our own tag for SORING */
23 #include <rte_log.h>
24 
25 extern int soring_logtype;
26 #define RTE_LOGTYPE_SORING soring_logtype
27 #define SORING_LOG(level, ...) \
28 	RTE_LOG_LINE(level, SORING, "" __VA_ARGS__)
29 
30 /**
31  * SORING internal state for each element
32  */
33 union soring_state {
34 	alignas(sizeof(uint64_t)) RTE_ATOMIC(uint64_t) raw;
35 	struct {
36 		RTE_ATOMIC(uint32_t) ftoken;
37 		RTE_ATOMIC(uint32_t) stnum;
38 	};
39 };
40 
41 /* upper 2 bits are used for status */
42 #define SORING_ST_START		RTE_SHIFT_VAL32(1, RTE_SORING_ST_BIT)
43 #define SORING_ST_FINISH	RTE_SHIFT_VAL32(2, RTE_SORING_ST_BIT)
44 
45 #define SORING_ST_MASK	\
46 	RTE_GENMASK32(sizeof(uint32_t) * CHAR_BIT - 1, RTE_SORING_ST_BIT)
47 
48 #define SORING_FTKN_MAKE(pos, stg)	((pos) + (stg))
49 #define SORING_FTKN_POS(ftk, stg)	((ftk) - (stg))
50 
51 /**
52  * SORING re-uses rte_ring internal structures and implementation
53  * for enqueue/dequeue operations.
54  */
55 struct __rte_ring_headtail {
56 
57 	union __rte_cache_aligned {
58 		struct rte_ring_headtail ht;
59 		struct rte_ring_hts_headtail hts;
60 		struct rte_ring_rts_headtail rts;
61 	};
62 
63 	RTE_CACHE_GUARD;
64 };
65 
66 union soring_stage_tail {
67 	/** raw 8B value to read/write *sync* and *pos* as one atomic op */
68 	alignas(sizeof(uint64_t)) RTE_ATOMIC(uint64_t) raw;
69 	struct {
70 		RTE_ATOMIC(uint32_t) sync;
71 		RTE_ATOMIC(uint32_t) pos;
72 	};
73 };
74 
75 struct soring_stage_headtail {
76 	volatile union soring_stage_tail tail;
77 	enum rte_ring_sync_type unused;  /**< unused */
78 	volatile RTE_ATOMIC(uint32_t) head;
79 };
80 
81 /**
82  * SORING stage head_tail structure is 'compatible' with rte_ring ones.
83  * rte_ring internal functions for moving producer/consumer head
84  * can work transparently with stage head_tail and visa-versa
85  * (no modifications required).
86  */
87 struct soring_stage {
88 
89 	union __rte_cache_aligned {
90 		struct rte_ring_headtail ht;
91 		struct soring_stage_headtail sht;
92 	};
93 
94 	RTE_CACHE_GUARD;
95 };
96 
97 /**
98  * soring internal structure.
99  * As with rte_ring actual elements array supposed to be located directly
100  * after the rte_soring structure.
101  */
102 struct  __rte_cache_aligned rte_soring {
103 	uint32_t size;           /**< Size of ring. */
104 	uint32_t mask;           /**< Mask (size-1) of ring. */
105 	uint32_t capacity;       /**< Usable size of ring */
106 	uint32_t esize;
107 	/**< size of elements in the ring, must be a multiple of 4*/
108 	uint32_t msize;
109 	/**< size of metadata value for each elem, must be a multiple of 4 */
110 
111 	/** Ring stages */
112 	struct soring_stage *stage;
113 	uint32_t nb_stage;
114 
115 	/** Ring of states (one per element) */
116 	union soring_state *state;
117 
118 	/** Pointer to the buffer where metadata values for each elements
119 	 * are stored. This is supplementary and optional information that
120 	 * user can attach to each element of the ring.
121 	 * While it is possible to incorporate this information inside
122 	 * user-defined element, in many cases it is plausible to maintain it
123 	 * as a separate array (mainly for performance reasons).
124 	 */
125 	void *meta;
126 
127 	RTE_CACHE_GUARD;
128 
129 	/** Ring producer status. */
130 	struct __rte_ring_headtail prod;
131 
132 	/** Ring consumer status. */
133 	struct __rte_ring_headtail cons;
134 
135 	char name[RTE_RING_NAMESIZE];  /**< Name of the ring. */
136 };
137 
138 #endif /* _SORING_H_ */
139