199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2016-2017 Intel Corporation 399a2dd95SBruce Richardson * Copyright(c) 2019 Arm Limited 499a2dd95SBruce Richardson */ 599a2dd95SBruce Richardson 699a2dd95SBruce Richardson /** 799a2dd95SBruce Richardson * @file 899a2dd95SBruce Richardson * RTE Event Ring 999a2dd95SBruce Richardson * 1099a2dd95SBruce Richardson * This provides a ring implementation for passing rte_event structures 1199a2dd95SBruce Richardson * from one core to another. 1299a2dd95SBruce Richardson */ 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson #ifndef _RTE_EVENT_RING_ 1599a2dd95SBruce Richardson #define _RTE_EVENT_RING_ 1699a2dd95SBruce Richardson 1799a2dd95SBruce Richardson #include <stdint.h> 1899a2dd95SBruce Richardson 1999a2dd95SBruce Richardson #include <rte_common.h> 2099a2dd95SBruce Richardson #include <rte_ring.h> 2199a2dd95SBruce Richardson #include <rte_ring_elem.h> 2299a2dd95SBruce Richardson #include "rte_eventdev.h" 2399a2dd95SBruce Richardson 24*719834a6SMattias Rönnblom #ifdef __cplusplus 25*719834a6SMattias Rönnblom extern "C" { 26*719834a6SMattias Rönnblom #endif 27*719834a6SMattias Rönnblom 2899a2dd95SBruce Richardson #define RTE_TAILQ_EVENT_RING_NAME "RTE_EVENT_RING" 2999a2dd95SBruce Richardson 3099a2dd95SBruce Richardson /** 3199a2dd95SBruce Richardson * Generic ring structure for passing rte_event objects from core to core. 3299a2dd95SBruce Richardson * 3399a2dd95SBruce Richardson * Based on the primitives given in the rte_ring library. Designed to be 3499a2dd95SBruce Richardson * used inside software eventdev implementations and by applications 3599a2dd95SBruce Richardson * directly as needed. 3699a2dd95SBruce Richardson */ 3799a2dd95SBruce Richardson struct rte_event_ring { 3899a2dd95SBruce Richardson struct rte_ring r; 3999a2dd95SBruce Richardson }; 4099a2dd95SBruce Richardson 4199a2dd95SBruce Richardson /** 4299a2dd95SBruce Richardson * Returns the number of events in the ring 4399a2dd95SBruce Richardson * 4499a2dd95SBruce Richardson * @param r 4599a2dd95SBruce Richardson * pointer to the event ring 4699a2dd95SBruce Richardson * @return 4799a2dd95SBruce Richardson * the number of events in the ring 4899a2dd95SBruce Richardson */ 4999a2dd95SBruce Richardson static __rte_always_inline unsigned int 5099a2dd95SBruce Richardson rte_event_ring_count(const struct rte_event_ring *r) 5199a2dd95SBruce Richardson { 5299a2dd95SBruce Richardson return rte_ring_count(&r->r); 5399a2dd95SBruce Richardson } 5499a2dd95SBruce Richardson 5599a2dd95SBruce Richardson /** 5699a2dd95SBruce Richardson * Returns the amount of free space in the ring 5799a2dd95SBruce Richardson * 5899a2dd95SBruce Richardson * @param r 5999a2dd95SBruce Richardson * pointer to the event ring 6099a2dd95SBruce Richardson * @return 6199a2dd95SBruce Richardson * the number of free slots in the ring, i.e. the number of events that 6299a2dd95SBruce Richardson * can be successfully enqueued before dequeue must be called 6399a2dd95SBruce Richardson */ 6499a2dd95SBruce Richardson static __rte_always_inline unsigned int 6599a2dd95SBruce Richardson rte_event_ring_free_count(const struct rte_event_ring *r) 6699a2dd95SBruce Richardson { 6799a2dd95SBruce Richardson return rte_ring_free_count(&r->r); 6899a2dd95SBruce Richardson } 6999a2dd95SBruce Richardson 707edf09eaSMattias Rönnblom 717edf09eaSMattias Rönnblom /** 727edf09eaSMattias Rönnblom * Enqueue several objects on a ring. 737edf09eaSMattias Rönnblom * 747edf09eaSMattias Rönnblom * This function calls the multi-producer or the single-producer 757edf09eaSMattias Rönnblom * version depending on the default behavior that was specified at 767edf09eaSMattias Rönnblom * ring creation time (see flags). 777edf09eaSMattias Rönnblom * 787edf09eaSMattias Rönnblom * @param r 797edf09eaSMattias Rönnblom * pointer to the event ring 807edf09eaSMattias Rönnblom * @param events 817edf09eaSMattias Rönnblom * pointer to an array of struct rte_event objects 827edf09eaSMattias Rönnblom * @param n 837edf09eaSMattias Rönnblom * The number of events in the array to enqueue 847edf09eaSMattias Rönnblom * @param free_space 857edf09eaSMattias Rönnblom * if non-NULL, returns the amount of space in the ring after the 867edf09eaSMattias Rönnblom * enqueue operation has completed 877edf09eaSMattias Rönnblom * @return 887edf09eaSMattias Rönnblom * the number of objects enqueued, either 0 or n 897edf09eaSMattias Rönnblom */ 907edf09eaSMattias Rönnblom static __rte_always_inline unsigned int 917edf09eaSMattias Rönnblom rte_event_ring_enqueue_bulk(struct rte_event_ring *r, 927edf09eaSMattias Rönnblom const struct rte_event *events, 937edf09eaSMattias Rönnblom unsigned int n, uint16_t *free_space) 947edf09eaSMattias Rönnblom { 957edf09eaSMattias Rönnblom unsigned int num; 967edf09eaSMattias Rönnblom uint32_t space; 977edf09eaSMattias Rönnblom 987edf09eaSMattias Rönnblom num = rte_ring_enqueue_bulk_elem(&r->r, events, 997edf09eaSMattias Rönnblom sizeof(struct rte_event), n, 1007edf09eaSMattias Rönnblom &space); 1017edf09eaSMattias Rönnblom 1027edf09eaSMattias Rönnblom if (free_space != NULL) 1037edf09eaSMattias Rönnblom *free_space = space; 1047edf09eaSMattias Rönnblom 1057edf09eaSMattias Rönnblom return num; 1067edf09eaSMattias Rönnblom } 1077edf09eaSMattias Rönnblom 1087edf09eaSMattias Rönnblom /** 1097edf09eaSMattias Rönnblom * Dequeue a set of events from a ring 1107edf09eaSMattias Rönnblom * 1117edf09eaSMattias Rönnblom * Note: this API does not work with pointers to events, rather it copies 1127edf09eaSMattias Rönnblom * the events themselves to the destination ``events`` buffer. 1137edf09eaSMattias Rönnblom * 1147edf09eaSMattias Rönnblom * @param r 1157edf09eaSMattias Rönnblom * pointer to the event ring 1167edf09eaSMattias Rönnblom * @param events 1177edf09eaSMattias Rönnblom * pointer to an array to hold the struct rte_event objects 1187edf09eaSMattias Rönnblom * @param n 1197edf09eaSMattias Rönnblom * number of events that can be held in the ``events`` array 1207edf09eaSMattias Rönnblom * @param available 1217edf09eaSMattias Rönnblom * if non-null, is updated to indicate the number of events remaining in 1227edf09eaSMattias Rönnblom * the ring once the dequeue has completed 1237edf09eaSMattias Rönnblom * @return 1247edf09eaSMattias Rönnblom * the number of objects dequeued, either 0 or n 1257edf09eaSMattias Rönnblom */ 1267edf09eaSMattias Rönnblom static __rte_always_inline unsigned int 1277edf09eaSMattias Rönnblom rte_event_ring_dequeue_bulk(struct rte_event_ring *r, 1287edf09eaSMattias Rönnblom struct rte_event *events, 1297edf09eaSMattias Rönnblom unsigned int n, uint16_t *available) 1307edf09eaSMattias Rönnblom { 1317edf09eaSMattias Rönnblom unsigned int num; 1327edf09eaSMattias Rönnblom uint32_t remaining; 1337edf09eaSMattias Rönnblom 1347edf09eaSMattias Rönnblom num = rte_ring_dequeue_bulk_elem(&r->r, events, 1357edf09eaSMattias Rönnblom sizeof(struct rte_event), n, 1367edf09eaSMattias Rönnblom &remaining); 1377edf09eaSMattias Rönnblom 1387edf09eaSMattias Rönnblom if (available != NULL) 1397edf09eaSMattias Rönnblom *available = remaining; 1407edf09eaSMattias Rönnblom 1417edf09eaSMattias Rönnblom return num; 1427edf09eaSMattias Rönnblom } 1437edf09eaSMattias Rönnblom 14499a2dd95SBruce Richardson /** 14599a2dd95SBruce Richardson * Enqueue a set of events onto a ring 14699a2dd95SBruce Richardson * 14799a2dd95SBruce Richardson * Note: this API enqueues by copying the events themselves onto the ring, 14899a2dd95SBruce Richardson * rather than just placing a pointer to each event onto the ring. This 14999a2dd95SBruce Richardson * means that statically-allocated events can safely be enqueued by this 15099a2dd95SBruce Richardson * API. 15199a2dd95SBruce Richardson * 15299a2dd95SBruce Richardson * @param r 15399a2dd95SBruce Richardson * pointer to the event ring 15499a2dd95SBruce Richardson * @param events 15599a2dd95SBruce Richardson * pointer to an array of struct rte_event objects 15699a2dd95SBruce Richardson * @param n 15799a2dd95SBruce Richardson * number of events in the array to enqueue 15899a2dd95SBruce Richardson * @param free_space 15999a2dd95SBruce Richardson * if non-null, is updated to indicate the amount of free space in the 16099a2dd95SBruce Richardson * ring once the enqueue has completed. 16199a2dd95SBruce Richardson * @return 16299a2dd95SBruce Richardson * the number of elements, n', enqueued to the ring, 0 <= n' <= n 16399a2dd95SBruce Richardson */ 16499a2dd95SBruce Richardson static __rte_always_inline unsigned int 16599a2dd95SBruce Richardson rte_event_ring_enqueue_burst(struct rte_event_ring *r, 16699a2dd95SBruce Richardson const struct rte_event *events, 16799a2dd95SBruce Richardson unsigned int n, uint16_t *free_space) 16899a2dd95SBruce Richardson { 16999a2dd95SBruce Richardson unsigned int num; 17099a2dd95SBruce Richardson uint32_t space; 17199a2dd95SBruce Richardson 17299a2dd95SBruce Richardson num = rte_ring_enqueue_burst_elem(&r->r, events, 17399a2dd95SBruce Richardson sizeof(struct rte_event), n, 17499a2dd95SBruce Richardson &space); 17599a2dd95SBruce Richardson 17699a2dd95SBruce Richardson if (free_space != NULL) 17799a2dd95SBruce Richardson *free_space = space; 17899a2dd95SBruce Richardson 17999a2dd95SBruce Richardson return num; 18099a2dd95SBruce Richardson } 18199a2dd95SBruce Richardson 18299a2dd95SBruce Richardson /** 18399a2dd95SBruce Richardson * Dequeue a set of events from a ring 18499a2dd95SBruce Richardson * 18599a2dd95SBruce Richardson * Note: this API does not work with pointers to events, rather it copies 18699a2dd95SBruce Richardson * the events themselves to the destination ``events`` buffer. 18799a2dd95SBruce Richardson * 18899a2dd95SBruce Richardson * @param r 18999a2dd95SBruce Richardson * pointer to the event ring 19099a2dd95SBruce Richardson * @param events 19199a2dd95SBruce Richardson * pointer to an array to hold the struct rte_event objects 19299a2dd95SBruce Richardson * @param n 19399a2dd95SBruce Richardson * number of events that can be held in the ``events`` array 19499a2dd95SBruce Richardson * @param available 19599a2dd95SBruce Richardson * if non-null, is updated to indicate the number of events remaining in 19699a2dd95SBruce Richardson * the ring once the dequeue has completed 19799a2dd95SBruce Richardson * @return 19899a2dd95SBruce Richardson * the number of elements, n', dequeued from the ring, 0 <= n' <= n 19999a2dd95SBruce Richardson */ 20099a2dd95SBruce Richardson static __rte_always_inline unsigned int 20199a2dd95SBruce Richardson rte_event_ring_dequeue_burst(struct rte_event_ring *r, 20299a2dd95SBruce Richardson struct rte_event *events, 20399a2dd95SBruce Richardson unsigned int n, uint16_t *available) 20499a2dd95SBruce Richardson { 20599a2dd95SBruce Richardson unsigned int num; 20699a2dd95SBruce Richardson uint32_t remaining; 20799a2dd95SBruce Richardson 20899a2dd95SBruce Richardson num = rte_ring_dequeue_burst_elem(&r->r, events, 20999a2dd95SBruce Richardson sizeof(struct rte_event), n, 21099a2dd95SBruce Richardson &remaining); 21199a2dd95SBruce Richardson 21299a2dd95SBruce Richardson if (available != NULL) 21399a2dd95SBruce Richardson *available = remaining; 21499a2dd95SBruce Richardson 21599a2dd95SBruce Richardson return num; 21699a2dd95SBruce Richardson } 21799a2dd95SBruce Richardson 21899a2dd95SBruce Richardson /* 21999a2dd95SBruce Richardson * Initializes an already-allocated ring structure 22099a2dd95SBruce Richardson * 22199a2dd95SBruce Richardson * @param r 22299a2dd95SBruce Richardson * pointer to the ring memory to be initialized 22399a2dd95SBruce Richardson * @param name 22499a2dd95SBruce Richardson * name to be given to the ring 22599a2dd95SBruce Richardson * @param count 22699a2dd95SBruce Richardson * the number of elements to be stored in the ring. If the flag 22799a2dd95SBruce Richardson * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 22899a2dd95SBruce Richardson * usable space in the ring will be ``count - 1`` entries. If the flag 22999a2dd95SBruce Richardson * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 23099a2dd95SBruce Richardson * limit - 1, and the usable space will be exactly that requested. 23199a2dd95SBruce Richardson * @param flags 23299a2dd95SBruce Richardson * An OR of the following: 23399a2dd95SBruce Richardson * - RING_F_SP_ENQ: If this flag is set, the default behavior when 23499a2dd95SBruce Richardson * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 23599a2dd95SBruce Richardson * is "single-producer". Otherwise, it is "multi-producers". 23699a2dd95SBruce Richardson * - RING_F_SC_DEQ: If this flag is set, the default behavior when 23799a2dd95SBruce Richardson * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 23899a2dd95SBruce Richardson * is "single-consumer". Otherwise, it is "multi-consumers". 23999a2dd95SBruce Richardson * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to 24099a2dd95SBruce Richardson * be taken as the exact usable size of the ring, and as such does not 24199a2dd95SBruce Richardson * need to be a power of 2. The underlying ring memory should be a 24299a2dd95SBruce Richardson * power-of-2 size greater than the count value. 24399a2dd95SBruce Richardson * @return 24499a2dd95SBruce Richardson * 0 on success, or a negative value on error. 24599a2dd95SBruce Richardson */ 24699a2dd95SBruce Richardson int 24799a2dd95SBruce Richardson rte_event_ring_init(struct rte_event_ring *r, const char *name, 24899a2dd95SBruce Richardson unsigned int count, unsigned int flags); 24999a2dd95SBruce Richardson 25099a2dd95SBruce Richardson /* 25199a2dd95SBruce Richardson * Create an event ring structure 25299a2dd95SBruce Richardson * 25399a2dd95SBruce Richardson * This function allocates memory and initializes an event ring inside that 25499a2dd95SBruce Richardson * memory. 25599a2dd95SBruce Richardson * 25699a2dd95SBruce Richardson * @param name 25799a2dd95SBruce Richardson * name to be given to the ring 25899a2dd95SBruce Richardson * @param count 25999a2dd95SBruce Richardson * the number of elements to be stored in the ring. If the flag 26099a2dd95SBruce Richardson * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 26199a2dd95SBruce Richardson * usable space in the ring will be ``count - 1`` entries. If the flag 26299a2dd95SBruce Richardson * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 26399a2dd95SBruce Richardson * limit - 1, and the usable space will be exactly that requested. 26499a2dd95SBruce Richardson * @param socket_id 26599a2dd95SBruce Richardson * The *socket_id* argument is the socket identifier in case of 26699a2dd95SBruce Richardson * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA 26799a2dd95SBruce Richardson * constraint for the reserved zone. 26899a2dd95SBruce Richardson * @param flags 26999a2dd95SBruce Richardson * An OR of the following: 27099a2dd95SBruce Richardson * - RING_F_SP_ENQ: If this flag is set, the default behavior when 27199a2dd95SBruce Richardson * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 27299a2dd95SBruce Richardson * is "single-producer". Otherwise, it is "multi-producers". 27399a2dd95SBruce Richardson * - RING_F_SC_DEQ: If this flag is set, the default behavior when 27499a2dd95SBruce Richardson * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 27599a2dd95SBruce Richardson * is "single-consumer". Otherwise, it is "multi-consumers". 27699a2dd95SBruce Richardson * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to 27799a2dd95SBruce Richardson * be taken as the exact usable size of the ring, and as such does not 27899a2dd95SBruce Richardson * need to be a power of 2. The underlying ring memory should be a 27999a2dd95SBruce Richardson * power-of-2 size greater than the count value. 28099a2dd95SBruce Richardson * @return 28199a2dd95SBruce Richardson * On success, the pointer to the new allocated ring. NULL on error with 28299a2dd95SBruce Richardson * rte_errno set appropriately. Possible errno values include: 28399a2dd95SBruce Richardson * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 28499a2dd95SBruce Richardson * - E_RTE_SECONDARY - function was called from a secondary process instance 28599a2dd95SBruce Richardson * - EINVAL - count provided is not a power of 2 28699a2dd95SBruce Richardson * - ENOSPC - the maximum number of memzones has already been allocated 28799a2dd95SBruce Richardson * - EEXIST - a memzone with the same name already exists 28899a2dd95SBruce Richardson * - ENOMEM - no appropriate memory area found in which to create memzone 28999a2dd95SBruce Richardson */ 29099a2dd95SBruce Richardson struct rte_event_ring * 29199a2dd95SBruce Richardson rte_event_ring_create(const char *name, unsigned int count, int socket_id, 29299a2dd95SBruce Richardson unsigned int flags); 29399a2dd95SBruce Richardson 29499a2dd95SBruce Richardson /** 29599a2dd95SBruce Richardson * Search for an event ring based on its name 29699a2dd95SBruce Richardson * 29799a2dd95SBruce Richardson * @param name 29899a2dd95SBruce Richardson * The name of the ring. 29999a2dd95SBruce Richardson * @return 30099a2dd95SBruce Richardson * The pointer to the ring matching the name, or NULL if not found, 30199a2dd95SBruce Richardson * with rte_errno set appropriately. Possible rte_errno values include: 30299a2dd95SBruce Richardson * - ENOENT - required entry not available to return. 30399a2dd95SBruce Richardson */ 30499a2dd95SBruce Richardson struct rte_event_ring * 30599a2dd95SBruce Richardson rte_event_ring_lookup(const char *name); 30699a2dd95SBruce Richardson 30799a2dd95SBruce Richardson /** 30899a2dd95SBruce Richardson * De-allocate all memory used by the ring. 30999a2dd95SBruce Richardson * 31099a2dd95SBruce Richardson * @param r 311448e01f1SStephen Hemminger * Pointer to ring to created with rte_event_ring_create(). 312448e01f1SStephen Hemminger * If r is NULL, no operation is performed. 31399a2dd95SBruce Richardson */ 31499a2dd95SBruce Richardson void 31599a2dd95SBruce Richardson rte_event_ring_free(struct rte_event_ring *r); 31699a2dd95SBruce Richardson 31799a2dd95SBruce Richardson /** 31899a2dd95SBruce Richardson * Return the size of the event ring. 31999a2dd95SBruce Richardson * 32099a2dd95SBruce Richardson * @param r 32199a2dd95SBruce Richardson * A pointer to the ring structure. 32299a2dd95SBruce Richardson * @return 32399a2dd95SBruce Richardson * The size of the data store used by the ring. 32499a2dd95SBruce Richardson * NOTE: this is not the same as the usable space in the ring. To query that 32599a2dd95SBruce Richardson * use ``rte_ring_get_capacity()``. 32699a2dd95SBruce Richardson */ 32799a2dd95SBruce Richardson static inline unsigned int 32899a2dd95SBruce Richardson rte_event_ring_get_size(const struct rte_event_ring *r) 32999a2dd95SBruce Richardson { 33099a2dd95SBruce Richardson return rte_ring_get_size(&r->r); 33199a2dd95SBruce Richardson } 33299a2dd95SBruce Richardson 33399a2dd95SBruce Richardson /** 33499a2dd95SBruce Richardson * Return the number of elements which can be stored in the event ring. 33599a2dd95SBruce Richardson * 33699a2dd95SBruce Richardson * @param r 33799a2dd95SBruce Richardson * A pointer to the ring structure. 33899a2dd95SBruce Richardson * @return 33999a2dd95SBruce Richardson * The usable size of the ring. 34099a2dd95SBruce Richardson */ 34199a2dd95SBruce Richardson static inline unsigned int 34299a2dd95SBruce Richardson rte_event_ring_get_capacity(const struct rte_event_ring *r) 34399a2dd95SBruce Richardson { 34499a2dd95SBruce Richardson return rte_ring_get_capacity(&r->r); 34599a2dd95SBruce Richardson } 3462c552933SBrian Dooley 3472c552933SBrian Dooley #ifdef __cplusplus 3482c552933SBrian Dooley } 3492c552933SBrian Dooley #endif 3502c552933SBrian Dooley 35199a2dd95SBruce Richardson #endif 352