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