1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016-2017 Intel Corporation 3 * Copyright(c) 2019 Arm Limited 4 */ 5 6 /** 7 * @file 8 * RTE Event Ring 9 * 10 * This provides a ring implementation for passing rte_event structures 11 * from one core to another. 12 */ 13 14 #ifndef _RTE_EVENT_RING_ 15 #define _RTE_EVENT_RING_ 16 17 #include <stdint.h> 18 19 #include <rte_common.h> 20 #include <rte_memory.h> 21 #include <rte_malloc.h> 22 #include <rte_ring.h> 23 #include <rte_ring_elem.h> 24 #include "rte_eventdev.h" 25 26 #define RTE_TAILQ_EVENT_RING_NAME "RTE_EVENT_RING" 27 28 /** 29 * Generic ring structure for passing rte_event objects from core to core. 30 * 31 * Based on the primitives given in the rte_ring library. Designed to be 32 * used inside software eventdev implementations and by applications 33 * directly as needed. 34 */ 35 struct rte_event_ring { 36 struct rte_ring r; 37 }; 38 39 /** 40 * Returns the number of events in the ring 41 * 42 * @param r 43 * pointer to the event ring 44 * @return 45 * the number of events in the ring 46 */ 47 static __rte_always_inline unsigned int 48 rte_event_ring_count(const struct rte_event_ring *r) 49 { 50 return rte_ring_count(&r->r); 51 } 52 53 /** 54 * Returns the amount of free space in the ring 55 * 56 * @param r 57 * pointer to the event ring 58 * @return 59 * the number of free slots in the ring, i.e. the number of events that 60 * can be successfully enqueued before dequeue must be called 61 */ 62 static __rte_always_inline unsigned int 63 rte_event_ring_free_count(const struct rte_event_ring *r) 64 { 65 return rte_ring_free_count(&r->r); 66 } 67 68 /** 69 * Enqueue a set of events onto a ring 70 * 71 * Note: this API enqueues by copying the events themselves onto the ring, 72 * rather than just placing a pointer to each event onto the ring. This 73 * means that statically-allocated events can safely be enqueued by this 74 * API. 75 * 76 * @param r 77 * pointer to the event ring 78 * @param events 79 * pointer to an array of struct rte_event objects 80 * @param n 81 * number of events in the array to enqueue 82 * @param free_space 83 * if non-null, is updated to indicate the amount of free space in the 84 * ring once the enqueue has completed. 85 * @return 86 * the number of elements, n', enqueued to the ring, 0 <= n' <= n 87 */ 88 static __rte_always_inline unsigned int 89 rte_event_ring_enqueue_burst(struct rte_event_ring *r, 90 const struct rte_event *events, 91 unsigned int n, uint16_t *free_space) 92 { 93 unsigned int num; 94 uint32_t space; 95 96 num = rte_ring_enqueue_burst_elem(&r->r, events, 97 sizeof(struct rte_event), n, 98 &space); 99 100 if (free_space != NULL) 101 *free_space = space; 102 103 return num; 104 } 105 106 /** 107 * Dequeue a set of events from a ring 108 * 109 * Note: this API does not work with pointers to events, rather it copies 110 * the events themselves to the destination ``events`` buffer. 111 * 112 * @param r 113 * pointer to the event ring 114 * @param events 115 * pointer to an array to hold the struct rte_event objects 116 * @param n 117 * number of events that can be held in the ``events`` array 118 * @param available 119 * if non-null, is updated to indicate the number of events remaining in 120 * the ring once the dequeue has completed 121 * @return 122 * the number of elements, n', dequeued from the ring, 0 <= n' <= n 123 */ 124 static __rte_always_inline unsigned int 125 rte_event_ring_dequeue_burst(struct rte_event_ring *r, 126 struct rte_event *events, 127 unsigned int n, uint16_t *available) 128 { 129 unsigned int num; 130 uint32_t remaining; 131 132 num = rte_ring_dequeue_burst_elem(&r->r, events, 133 sizeof(struct rte_event), n, 134 &remaining); 135 136 if (available != NULL) 137 *available = remaining; 138 139 return num; 140 } 141 142 /* 143 * Initializes an already-allocated ring structure 144 * 145 * @param r 146 * pointer to the ring memory to be initialized 147 * @param name 148 * name to be given to the ring 149 * @param count 150 * the number of elements to be stored in the ring. If the flag 151 * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 152 * usable space in the ring will be ``count - 1`` entries. If the flag 153 * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 154 * limit - 1, and the usable space will be exactly that requested. 155 * @param flags 156 * An OR of the following: 157 * - RING_F_SP_ENQ: If this flag is set, the default behavior when 158 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 159 * is "single-producer". Otherwise, it is "multi-producers". 160 * - RING_F_SC_DEQ: If this flag is set, the default behavior when 161 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 162 * is "single-consumer". Otherwise, it is "multi-consumers". 163 * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to 164 * be taken as the exact usable size of the ring, and as such does not 165 * need to be a power of 2. The underlying ring memory should be a 166 * power-of-2 size greater than the count value. 167 * @return 168 * 0 on success, or a negative value on error. 169 */ 170 int 171 rte_event_ring_init(struct rte_event_ring *r, const char *name, 172 unsigned int count, unsigned int flags); 173 174 /* 175 * Create an event ring structure 176 * 177 * This function allocates memory and initializes an event ring inside that 178 * memory. 179 * 180 * @param name 181 * name to be given to the ring 182 * @param count 183 * the number of elements to be stored in the ring. If the flag 184 * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 185 * usable space in the ring will be ``count - 1`` entries. If the flag 186 * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 187 * limit - 1, and the usable space will be exactly that requested. 188 * @param socket_id 189 * The *socket_id* argument is the socket identifier in case of 190 * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA 191 * constraint for the reserved zone. 192 * @param flags 193 * An OR of the following: 194 * - RING_F_SP_ENQ: If this flag is set, the default behavior when 195 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 196 * is "single-producer". Otherwise, it is "multi-producers". 197 * - RING_F_SC_DEQ: If this flag is set, the default behavior when 198 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 199 * is "single-consumer". Otherwise, it is "multi-consumers". 200 * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to 201 * be taken as the exact usable size of the ring, and as such does not 202 * need to be a power of 2. The underlying ring memory should be a 203 * power-of-2 size greater than the count value. 204 * @return 205 * On success, the pointer to the new allocated ring. NULL on error with 206 * rte_errno set appropriately. Possible errno values include: 207 * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 208 * - E_RTE_SECONDARY - function was called from a secondary process instance 209 * - EINVAL - count provided is not a power of 2 210 * - ENOSPC - the maximum number of memzones has already been allocated 211 * - EEXIST - a memzone with the same name already exists 212 * - ENOMEM - no appropriate memory area found in which to create memzone 213 */ 214 struct rte_event_ring * 215 rte_event_ring_create(const char *name, unsigned int count, int socket_id, 216 unsigned int flags); 217 218 /** 219 * Search for an event ring based on its name 220 * 221 * @param name 222 * The name of the ring. 223 * @return 224 * The pointer to the ring matching the name, or NULL if not found, 225 * with rte_errno set appropriately. Possible rte_errno values include: 226 * - ENOENT - required entry not available to return. 227 */ 228 struct rte_event_ring * 229 rte_event_ring_lookup(const char *name); 230 231 /** 232 * De-allocate all memory used by the ring. 233 * 234 * @param r 235 * Ring to free 236 */ 237 void 238 rte_event_ring_free(struct rte_event_ring *r); 239 240 /** 241 * Return the size of the event ring. 242 * 243 * @param r 244 * A pointer to the ring structure. 245 * @return 246 * The size of the data store used by the ring. 247 * NOTE: this is not the same as the usable space in the ring. To query that 248 * use ``rte_ring_get_capacity()``. 249 */ 250 static inline unsigned int 251 rte_event_ring_get_size(const struct rte_event_ring *r) 252 { 253 return rte_ring_get_size(&r->r); 254 } 255 256 /** 257 * Return the number of elements which can be stored in the event ring. 258 * 259 * @param r 260 * A pointer to the ring structure. 261 * @return 262 * The usable size of the ring. 263 */ 264 static inline unsigned int 265 rte_event_ring_get_capacity(const struct rte_event_ring *r) 266 { 267 return rte_ring_get_capacity(&r->r); 268 } 269 #endif 270