1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright (c) 2010-2020 Intel Corporation 4 * Copyright (c) 2007-2009 Kip Macy [email protected] 5 * All rights reserved. 6 * Derived from FreeBSD's bufring.h 7 * Used as BSD-3 Licensed with permission from Kip Macy. 8 */ 9 10 #ifndef _RTE_RING_CORE_H_ 11 #define _RTE_RING_CORE_H_ 12 13 /** 14 * @file 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> 19 * instead. 20 */ 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #include <stdio.h> 27 #include <stdint.h> 28 #include <string.h> 29 #include <errno.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> 39 40 #define RTE_TAILQ_RING_NAME "RTE_RING" 41 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 48 }; 49 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) 54 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 */ 61 }; 62 63 /** 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. 67 */ 68 struct rte_ring_headtail { 69 volatile uint32_t head; /**< prod/consumer head. */ 70 volatile uint32_t tail; /**< prod/consumer tail. */ 71 RTE_STD_C11 72 union { 73 /** sync type of prod/cons */ 74 enum rte_ring_sync_type sync_type; 75 /** deprecated - True if single prod/cons */ 76 uint32_t single; 77 }; 78 }; 79 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); 83 struct { 84 uint32_t cnt; /**< head/tail reference counter */ 85 uint32_t pos; /**< head/tail position */ 86 } val; 87 }; 88 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; 94 }; 95 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); 99 struct { 100 uint32_t head; /**< head position */ 101 uint32_t tail; /**< tail position */ 102 } pos; 103 }; 104 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 */ 108 }; 109 110 /** 111 * An RTE ring structure. 112 * 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 118 * a problem. 119 */ 120 struct rte_ring { 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 */ 129 130 char pad0 __rte_cache_aligned; /**< empty cache line */ 131 132 /** Ring producer status. */ 133 RTE_STD_C11 134 union { 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; 139 140 char pad1 __rte_cache_aligned; /**< empty cache line */ 141 142 /** Ring consumer status. */ 143 RTE_STD_C11 144 union { 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; 149 150 char pad2 __rte_cache_aligned; /**< empty cache line */ 151 }; 152 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". */ 155 /** 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. 162 */ 163 #define RING_F_EXACT_SZ 0x0004 164 #define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */ 165 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". */ 168 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". */ 171 172 #ifdef __cplusplus 173 } 174 #endif 175 176 #endif /* _RTE_RING_CORE_H_ */ 177