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