199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * 399a2dd95SBruce Richardson * Copyright (c) 2010-2020 Intel Corporation 499a2dd95SBruce Richardson * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org 599a2dd95SBruce Richardson * All rights reserved. 699a2dd95SBruce Richardson * Derived from FreeBSD's bufring.h 799a2dd95SBruce Richardson * Used as BSD-3 Licensed with permission from Kip Macy. 899a2dd95SBruce Richardson */ 999a2dd95SBruce Richardson 1099a2dd95SBruce Richardson #ifndef _RTE_RING_CORE_H_ 1199a2dd95SBruce Richardson #define _RTE_RING_CORE_H_ 1299a2dd95SBruce Richardson 1399a2dd95SBruce Richardson /** 1499a2dd95SBruce Richardson * @file 157be78d02SJosh Soref * This file contains definition of RTE ring structure itself, 1699a2dd95SBruce Richardson * init flags and some related macros. 1799a2dd95SBruce Richardson * For majority of DPDK entities, it is not recommended to include 1899a2dd95SBruce Richardson * this file directly, use include <rte_ring.h> or <rte_ring_elem.h> 1999a2dd95SBruce Richardson * instead. 2099a2dd95SBruce Richardson */ 2199a2dd95SBruce Richardson 22e9fd1ebfSTyler Retzlaff #include <stdalign.h> 2399a2dd95SBruce Richardson #include <stdio.h> 2499a2dd95SBruce Richardson #include <stdint.h> 2599a2dd95SBruce Richardson #include <string.h> 2699a2dd95SBruce Richardson #include <errno.h> 2799a2dd95SBruce Richardson #include <rte_common.h> 2899a2dd95SBruce Richardson #include <rte_config.h> 2999a2dd95SBruce Richardson #include <rte_memory.h> 3099a2dd95SBruce Richardson #include <rte_lcore.h> 3199a2dd95SBruce Richardson #include <rte_atomic.h> 3299a2dd95SBruce Richardson #include <rte_branch_prediction.h> 3399a2dd95SBruce Richardson #include <rte_memzone.h> 3499a2dd95SBruce Richardson #include <rte_pause.h> 3599a2dd95SBruce Richardson #include <rte_debug.h> 3699a2dd95SBruce Richardson 3799a2dd95SBruce Richardson #define RTE_TAILQ_RING_NAME "RTE_RING" 3899a2dd95SBruce Richardson 3999a2dd95SBruce Richardson /** enqueue/dequeue behavior types */ 4099a2dd95SBruce Richardson enum rte_ring_queue_behavior { 4199a2dd95SBruce Richardson /** Enq/Deq a fixed number of items from a ring */ 4299a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED = 0, 4399a2dd95SBruce Richardson /** Enq/Deq as many items as possible from ring */ 4499a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE 4599a2dd95SBruce Richardson }; 4699a2dd95SBruce Richardson 4799a2dd95SBruce Richardson #define RTE_RING_MZ_PREFIX "RG_" 4899a2dd95SBruce Richardson /** The maximum length of a ring name. */ 4999a2dd95SBruce Richardson #define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \ 5099a2dd95SBruce Richardson sizeof(RTE_RING_MZ_PREFIX) + 1) 5199a2dd95SBruce Richardson 5299a2dd95SBruce Richardson /** prod/cons sync types */ 5399a2dd95SBruce Richardson enum rte_ring_sync_type { 5499a2dd95SBruce Richardson RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */ 5599a2dd95SBruce Richardson RTE_RING_SYNC_ST, /**< single thread only */ 5699a2dd95SBruce Richardson RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */ 5799a2dd95SBruce Richardson RTE_RING_SYNC_MT_HTS, /**< multi-thread head/tail sync */ 5899a2dd95SBruce Richardson }; 5999a2dd95SBruce Richardson 6099a2dd95SBruce Richardson /** 6199a2dd95SBruce Richardson * structures to hold a pair of head/tail values and other metadata. 6299a2dd95SBruce Richardson * Depending on sync_type format of that structure might be different, 6399a2dd95SBruce Richardson * but offset for *sync_type* and *tail* values should remain the same. 6499a2dd95SBruce Richardson */ 6599a2dd95SBruce Richardson struct rte_ring_headtail { 6632faaf30STyler Retzlaff volatile RTE_ATOMIC(uint32_t) head; /**< prod/consumer head. */ 6732faaf30STyler Retzlaff volatile RTE_ATOMIC(uint32_t) tail; /**< prod/consumer tail. */ 6899a2dd95SBruce Richardson union { 6999a2dd95SBruce Richardson /** sync type of prod/cons */ 7099a2dd95SBruce Richardson enum rte_ring_sync_type sync_type; 7199a2dd95SBruce Richardson /** deprecated - True if single prod/cons */ 7299a2dd95SBruce Richardson uint32_t single; 7399a2dd95SBruce Richardson }; 7499a2dd95SBruce Richardson }; 7599a2dd95SBruce Richardson 7699a2dd95SBruce Richardson union __rte_ring_rts_poscnt { 7799a2dd95SBruce Richardson /** raw 8B value to read/write *cnt* and *pos* as one atomic op */ 78e9fd1ebfSTyler Retzlaff alignas(sizeof(uint64_t)) RTE_ATOMIC(uint64_t) raw; 7999a2dd95SBruce Richardson struct { 8099a2dd95SBruce Richardson uint32_t cnt; /**< head/tail reference counter */ 8199a2dd95SBruce Richardson uint32_t pos; /**< head/tail position */ 8299a2dd95SBruce Richardson } val; 8399a2dd95SBruce Richardson }; 8499a2dd95SBruce Richardson 8599a2dd95SBruce Richardson struct rte_ring_rts_headtail { 8699a2dd95SBruce Richardson volatile union __rte_ring_rts_poscnt tail; 8799a2dd95SBruce Richardson enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */ 8899a2dd95SBruce Richardson uint32_t htd_max; /**< max allowed distance between head/tail */ 8999a2dd95SBruce Richardson volatile union __rte_ring_rts_poscnt head; 9099a2dd95SBruce Richardson }; 9199a2dd95SBruce Richardson 9299a2dd95SBruce Richardson union __rte_ring_hts_pos { 9399a2dd95SBruce Richardson /** raw 8B value to read/write *head* and *tail* as one atomic op */ 94e9fd1ebfSTyler Retzlaff alignas(sizeof(uint64_t)) RTE_ATOMIC(uint64_t) raw; 9599a2dd95SBruce Richardson struct { 9632faaf30STyler Retzlaff RTE_ATOMIC(uint32_t) head; /**< head position */ 9732faaf30STyler Retzlaff RTE_ATOMIC(uint32_t) tail; /**< tail position */ 9899a2dd95SBruce Richardson } pos; 9999a2dd95SBruce Richardson }; 10099a2dd95SBruce Richardson 10199a2dd95SBruce Richardson struct rte_ring_hts_headtail { 10299a2dd95SBruce Richardson volatile union __rte_ring_hts_pos ht; 10399a2dd95SBruce Richardson enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */ 10499a2dd95SBruce Richardson }; 10599a2dd95SBruce Richardson 10699a2dd95SBruce Richardson /** 10799a2dd95SBruce Richardson * An RTE ring structure. 10899a2dd95SBruce Richardson * 10999a2dd95SBruce Richardson * The producer and the consumer have a head and a tail index. The particularity 110a2248c87SHaiyue Wang * of these index is that they are not between 0 and size(ring)-1. These indexes 111a2248c87SHaiyue Wang * are between 0 and 2^32 -1, and we mask their value when we access the ring[] 11299a2dd95SBruce Richardson * field. Thanks to this assumption, we can do subtractions between 2 index 11399a2dd95SBruce Richardson * values in a modulo-32bit base: that's why the overflow of the indexes is not 11499a2dd95SBruce Richardson * a problem. 11599a2dd95SBruce Richardson */ 11699a2dd95SBruce Richardson struct rte_ring { 117e9fd1ebfSTyler Retzlaff alignas(RTE_CACHE_LINE_SIZE) char name[RTE_RING_NAMESIZE]; 11899a2dd95SBruce Richardson /**< Name of the ring. */ 11999a2dd95SBruce Richardson int flags; /**< Flags supplied at creation. */ 12099a2dd95SBruce Richardson const struct rte_memzone *memzone; 12199a2dd95SBruce Richardson /**< Memzone, if any, containing the rte_ring */ 12299a2dd95SBruce Richardson uint32_t size; /**< Size of ring. */ 12399a2dd95SBruce Richardson uint32_t mask; /**< Mask (size-1) of ring. */ 12499a2dd95SBruce Richardson uint32_t capacity; /**< Usable size of ring */ 12599a2dd95SBruce Richardson 12665f600c0SMorten Brørup RTE_CACHE_GUARD; 12799a2dd95SBruce Richardson 12899a2dd95SBruce Richardson /** Ring producer status. */ 129*c6552d9aSTyler Retzlaff union __rte_cache_aligned { 13099a2dd95SBruce Richardson struct rte_ring_headtail prod; 13199a2dd95SBruce Richardson struct rte_ring_hts_headtail hts_prod; 13299a2dd95SBruce Richardson struct rte_ring_rts_headtail rts_prod; 133*c6552d9aSTyler Retzlaff }; 13499a2dd95SBruce Richardson 13565f600c0SMorten Brørup RTE_CACHE_GUARD; 13699a2dd95SBruce Richardson 13799a2dd95SBruce Richardson /** Ring consumer status. */ 138*c6552d9aSTyler Retzlaff union __rte_cache_aligned { 13999a2dd95SBruce Richardson struct rte_ring_headtail cons; 14099a2dd95SBruce Richardson struct rte_ring_hts_headtail hts_cons; 14199a2dd95SBruce Richardson struct rte_ring_rts_headtail rts_cons; 142*c6552d9aSTyler Retzlaff }; 14399a2dd95SBruce Richardson 14465f600c0SMorten Brørup RTE_CACHE_GUARD; 14599a2dd95SBruce Richardson }; 14699a2dd95SBruce Richardson 14799a2dd95SBruce Richardson #define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */ 14899a2dd95SBruce Richardson #define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */ 14999a2dd95SBruce Richardson /** 15099a2dd95SBruce Richardson * Ring is to hold exactly requested number of entries. 15199a2dd95SBruce Richardson * Without this flag set, the ring size requested must be a power of 2, and the 15299a2dd95SBruce Richardson * usable space will be that size - 1. With the flag, the requested size will 15399a2dd95SBruce Richardson * be rounded up to the next power of two, but the usable space will be exactly 15499a2dd95SBruce Richardson * that requested. Worst case, if a power-of-2 size is requested, half the 15599a2dd95SBruce Richardson * ring space will be wasted. 15699a2dd95SBruce Richardson */ 15799a2dd95SBruce Richardson #define RING_F_EXACT_SZ 0x0004 15899a2dd95SBruce Richardson #define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */ 15999a2dd95SBruce Richardson 16099a2dd95SBruce Richardson #define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */ 16199a2dd95SBruce Richardson #define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */ 16299a2dd95SBruce Richardson 16399a2dd95SBruce Richardson #define RING_F_MP_HTS_ENQ 0x0020 /**< The default enqueue is "MP HTS". */ 16499a2dd95SBruce Richardson #define RING_F_MC_HTS_DEQ 0x0040 /**< The default dequeue is "MC HTS". */ 16599a2dd95SBruce Richardson 16699a2dd95SBruce Richardson #endif /* _RTE_RING_CORE_H_ */ 167