xref: /dpdk/lib/ring/rte_ring_core.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
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