1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2010-2020 Intel Corporation
4 * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
6 * Derived from FreeBSD's bufring.h
7 * Used as BSD-3 Licensed with permission from Kip Macy.
10 #ifndef _RTE_RING_CORE_H_
11 #define _RTE_RING_CORE_H_
15 * This file contains definition of RTE ring structure itself,
16 * init flags and some related macros.
17 * For majority of DPDK entities, it is not recommended to include
18 * this file directly, use include <rte_ring.h> or <rte_ring_elem.h>
30 #include <rte_common.h>
31 #include <rte_config.h>
32 #include <rte_memory.h>
33 #include <rte_lcore.h>
34 #include <rte_atomic.h>
35 #include <rte_branch_prediction.h>
36 #include <rte_memzone.h>
37 #include <rte_pause.h>
38 #include <rte_debug.h>
40 #define RTE_TAILQ_RING_NAME "RTE_RING"
42 /** enqueue/dequeue behavior types */
43 enum rte_ring_queue_behavior {
44 /** Enq/Deq a fixed number of items from a ring */
45 RTE_RING_QUEUE_FIXED = 0,
46 /** Enq/Deq as many items as possible from ring */
47 RTE_RING_QUEUE_VARIABLE
50 #define RTE_RING_MZ_PREFIX "RG_"
51 /** The maximum length of a ring name. */
52 #define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
53 sizeof(RTE_RING_MZ_PREFIX) + 1)
55 /** prod/cons sync types */
56 enum rte_ring_sync_type {
57 RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
58 RTE_RING_SYNC_ST, /**< single thread only */
59 RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
60 RTE_RING_SYNC_MT_HTS, /**< multi-thread head/tail sync */
64 * structures to hold a pair of head/tail values and other metadata.
65 * Depending on sync_type format of that structure might be different,
66 * but offset for *sync_type* and *tail* values should remain the same.
68 struct rte_ring_headtail {
69 volatile uint32_t head; /**< prod/consumer head. */
70 volatile uint32_t tail; /**< prod/consumer tail. */
73 /** sync type of prod/cons */
74 enum rte_ring_sync_type sync_type;
75 /** deprecated - True if single prod/cons */
80 union __rte_ring_rts_poscnt {
81 /** raw 8B value to read/write *cnt* and *pos* as one atomic op */
82 uint64_t raw __rte_aligned(8);
84 uint32_t cnt; /**< head/tail reference counter */
85 uint32_t pos; /**< head/tail position */
89 struct rte_ring_rts_headtail {
90 volatile union __rte_ring_rts_poscnt tail;
91 enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
92 uint32_t htd_max; /**< max allowed distance between head/tail */
93 volatile union __rte_ring_rts_poscnt head;
96 union __rte_ring_hts_pos {
97 /** raw 8B value to read/write *head* and *tail* as one atomic op */
98 uint64_t raw __rte_aligned(8);
100 uint32_t head; /**< head position */
101 uint32_t tail; /**< tail position */
105 struct rte_ring_hts_headtail {
106 volatile union __rte_ring_hts_pos ht;
107 enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
111 * An RTE ring structure.
113 * The producer and the consumer have a head and a tail index. The particularity
114 * of these index is that they are not between 0 and size(ring). These indexes
115 * are between 0 and 2^32, and we mask their value when we access the ring[]
116 * field. Thanks to this assumption, we can do subtractions between 2 index
117 * values in a modulo-32bit base: that's why the overflow of the indexes is not
121 char name[RTE_RING_NAMESIZE] __rte_cache_aligned;
122 /**< Name of the ring. */
123 int flags; /**< Flags supplied at creation. */
124 const struct rte_memzone *memzone;
125 /**< Memzone, if any, containing the rte_ring */
126 uint32_t size; /**< Size of ring. */
127 uint32_t mask; /**< Mask (size-1) of ring. */
128 uint32_t capacity; /**< Usable size of ring */
130 char pad0 __rte_cache_aligned; /**< empty cache line */
132 /** Ring producer status. */
135 struct rte_ring_headtail prod;
136 struct rte_ring_hts_headtail hts_prod;
137 struct rte_ring_rts_headtail rts_prod;
138 } __rte_cache_aligned;
140 char pad1 __rte_cache_aligned; /**< empty cache line */
142 /** Ring consumer status. */
145 struct rte_ring_headtail cons;
146 struct rte_ring_hts_headtail hts_cons;
147 struct rte_ring_rts_headtail rts_cons;
148 } __rte_cache_aligned;
150 char pad2 __rte_cache_aligned; /**< empty cache line */
153 #define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
154 #define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
156 * Ring is to hold exactly requested number of entries.
157 * Without this flag set, the ring size requested must be a power of 2, and the
158 * usable space will be that size - 1. With the flag, the requested size will
159 * be rounded up to the next power of two, but the usable space will be exactly
160 * that requested. Worst case, if a power-of-2 size is requested, half the
161 * ring space will be wasted.
163 #define RING_F_EXACT_SZ 0x0004
164 #define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
166 #define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */
167 #define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */
169 #define RING_F_MP_HTS_ENQ 0x0020 /**< The default enqueue is "MP HTS". */
170 #define RING_F_MC_HTS_DEQ 0x0040 /**< The default dequeue is "MC HTS". */
176 #endif /* _RTE_RING_CORE_H_ */