1 .. SPDX-License-Identifier: BSD-3-Clause
2 Copyright(c) 2010-2014 Intel Corporation.
9 The ring allows the management of queues.
10 Instead of having a linked list of infinite size, the rte_ring has the following properties:
14 * Maximum size is fixed, the objects are stored in a table
16 * Objects can be pointers or elements of multiple of 4 byte size
18 * Lockless implementation
20 * Multi-consumer or single-consumer dequeue
22 * Multi-producer or single-producer enqueue
24 * Bulk dequeue - Dequeues the specified count of objects if successful; otherwise fails
26 * Bulk enqueue - Enqueues the specified count of objects if successful; otherwise fails
28 * Burst dequeue - Dequeue the maximum available objects if the specified count cannot be fulfilled
30 * Burst enqueue - Enqueue the maximum available objects if the specified count cannot be fulfilled
32 The advantages of this data structure over a linked list queue are as follows:
34 * Faster; only requires a single 32 bit Compare-And-Swap instruction instead of several pointer size Compare-And-Swap instructions.
36 * Simpler than a full lockless queue.
38 * Adapted to bulk enqueue/dequeue operations.
39 As objects are stored in a table, a dequeue of several objects will not produce as many cache misses as in a linked queue.
40 Also, a bulk dequeue of many objects does not cost more than a dequeue of a simple object.
46 * Having many rings costs more in terms of memory than a linked list queue. An empty ring contains at least N objects.
48 A simplified representation of a Ring is shown in with consumer and producer head and tail pointers to objects stored in the data structure.
52 .. figure:: img/ring1.*
57 References for Ring Implementation in FreeBSD*
58 ----------------------------------------------
60 The following code was added in FreeBSD 8.0, and is used in some network device drivers (at least in Intel drivers):
62 * `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&view=markup>`_
64 * `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&view=markup>`_
66 Lockless Ring Buffer in Linux*
67 ------------------------------
69 The following is a link describing the `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_.
77 A ring is identified by a unique name.
78 It is not possible to create two rings with the same name (rte_ring_create() returns NULL if this is attempted).
83 Use cases for the Ring library include:
85 * Communication between applications in the DPDK
87 * Used by memory pool allocator
89 Anatomy of a Ring Buffer
90 ------------------------
92 This section explains how a ring buffer operates.
93 The ring structure is composed of two head and tail couples; one is used by producers and one is used by the consumers.
94 The figures of the following sections refer to them as prod_head, prod_tail, cons_head and cons_tail.
96 Each figure represents a simplified state of the ring, which is a circular buffer.
97 The content of the function local variables is represented on the top of the figure,
98 and the content of ring structure is represented on the bottom of the figure.
100 Single Producer Enqueue
101 ~~~~~~~~~~~~~~~~~~~~~~~
103 This section explains what occurs when a producer adds an object to the ring.
104 In this example, only the producer head and tail (prod_head and prod_tail) are modified,
105 and there is only one producer.
107 The initial state is to have a prod_head and prod_tail pointing at the same location.
112 First, *ring->prod_head* and ring->cons_tail are copied in local variables.
113 The prod_next local variable points to the next element of the table, or several elements after in case of bulk enqueue.
115 If there is not enough room in the ring (this is detected by checking cons_tail), it returns an error.
118 .. _figure_ring-enqueue1:
120 .. figure:: img/ring-enqueue1.*
128 The second step is to modify *ring->prod_head* in ring structure to point to the same location as prod_next.
130 The added object is copied in the ring (obj4).
133 .. _figure_ring-enqueue2:
135 .. figure:: img/ring-enqueue2.*
143 Once the object is added in the ring, ring->prod_tail in the ring structure is modified to point to the same location as *ring->prod_head*.
144 The enqueue operation is finished.
147 .. _figure_ring-enqueue3:
149 .. figure:: img/ring-enqueue3.*
154 Single Consumer Dequeue
155 ~~~~~~~~~~~~~~~~~~~~~~~
157 This section explains what occurs when a consumer dequeues an object from the ring.
158 In this example, only the consumer head and tail (cons_head and cons_tail) are modified and there is only one consumer.
160 The initial state is to have a cons_head and cons_tail pointing at the same location.
165 First, ring->cons_head and ring->prod_tail are copied in local variables.
166 The cons_next local variable points to the next element of the table, or several elements after in the case of bulk dequeue.
168 If there are not enough objects in the ring (this is detected by checking prod_tail), it returns an error.
171 .. _figure_ring-dequeue1:
173 .. figure:: img/ring-dequeue1.*
181 The second step is to modify ring->cons_head in the ring structure to point to the same location as cons_next.
183 The dequeued object (obj1) is copied in the pointer given by the user.
186 .. _figure_ring-dequeue2:
188 .. figure:: img/ring-dequeue2.*
196 Finally, ring->cons_tail in the ring structure is modified to point to the same location as ring->cons_head.
197 The dequeue operation is finished.
200 .. _figure_ring-dequeue3:
202 .. figure:: img/ring-dequeue3.*
207 Multiple Producers Enqueue
208 ~~~~~~~~~~~~~~~~~~~~~~~~~~
210 This section explains what occurs when two producers concurrently add an object to the ring.
211 In this example, only the producer head and tail (prod_head and prod_tail) are modified.
213 The initial state is to have a prod_head and prod_tail pointing at the same location.
215 Multiple Producers Enqueue First Step
216 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
218 On both cores, *ring->prod_head* and ring->cons_tail are copied in local variables.
219 The prod_next local variable points to the next element of the table,
220 or several elements after in the case of bulk enqueue.
222 If there is not enough room in the ring (this is detected by checking cons_tail), it returns an error.
225 .. _figure_ring-mp-enqueue1:
227 .. figure:: img/ring-mp-enqueue1.*
229 Multiple producer enqueue first step
232 Multiple Producers Enqueue Second Step
233 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
235 The second step is to modify ring->prod_head in the ring structure to point to the same location as prod_next.
236 This operation is done using a Compare And Swap (CAS) instruction, which does the following operations atomically:
238 * If ring->prod_head is different to local variable prod_head,
239 the CAS operation fails, and the code restarts at first step.
241 * Otherwise, ring->prod_head is set to local prod_next,
242 the CAS operation is successful, and processing continues.
244 In the figure, the operation succeeded on core 1, and step one restarted on core 2.
247 .. _figure_ring-mp-enqueue2:
249 .. figure:: img/ring-mp-enqueue2.*
251 Multiple producer enqueue second step
254 Multiple Producers Enqueue Third Step
255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
257 The CAS operation is retried on core 2 with success.
259 The core 1 updates one element of the ring(obj4), and the core 2 updates another one (obj5).
262 .. _figure_ring-mp-enqueue3:
264 .. figure:: img/ring-mp-enqueue3.*
266 Multiple producer enqueue third step
269 Multiple Producers Enqueue Fourth Step
270 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
272 Each core now wants to update ring->prod_tail.
273 A core can only update it if ring->prod_tail is equal to the prod_head local variable.
274 This is only true on core 1. The operation is finished on core 1.
277 .. _figure_ring-mp-enqueue4:
279 .. figure:: img/ring-mp-enqueue4.*
281 Multiple producer enqueue fourth step
284 Multiple Producers Enqueue Last Step
285 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
287 Once ring->prod_tail is updated by core 1, core 2 is allowed to update it too.
288 The operation is also finished on core 2.
291 .. _figure_ring-mp-enqueue5:
293 .. figure:: img/ring-mp-enqueue5.*
295 Multiple producer enqueue last step
298 Modulo 32-bit Indexes
299 ~~~~~~~~~~~~~~~~~~~~~
301 In the preceding figures, the prod_head, prod_tail, cons_head and cons_tail indexes are represented by arrows.
302 In the actual implementation, these values are not between 0 and size(ring)-1 as would be assumed.
303 The indexes are between 0 and 2^32 -1, and we mask their value when we access the object table (the ring itself).
304 32-bit modulo also implies that operations on indexes (such as, add/subtract) will automatically do 2^32 modulo
305 if the result overflows the 32-bit number range.
307 The following are two examples that help to explain how indexes are used in a ring.
311 To simplify the explanation, operations with modulo 16-bit are used instead of modulo 32-bit.
312 In addition, the four indexes are defined as unsigned 16-bit integers,
313 as opposed to unsigned 32-bit integers in the more realistic case.
316 .. _figure_ring-modulo1:
318 .. figure:: img/ring-modulo1.*
320 Modulo 32-bit indexes - Example 1
323 This ring contains 11000 entries.
326 .. _figure_ring-modulo2:
328 .. figure:: img/ring-modulo2.*
330 Modulo 32-bit indexes - Example 2
333 This ring contains 12536 entries.
337 For ease of understanding, we use modulo 65536 operations in the above examples.
338 In real execution cases, this is redundant for low efficiency, but is done automatically when the result overflows.
340 The code always maintains a distance between producer and consumer between 0 and size(ring)-1.
341 Thanks to this property, we can do subtractions between 2 index values in a modulo-32bit base:
342 that's why the overflow of the indexes is not a problem.
344 At any time, entries and free_entries are between 0 and size(ring)-1,
345 even if only the first term of subtraction has overflowed:
349 uint32_t entries = (prod_tail - cons_head);
350 uint32_t free_entries = (mask + cons_tail -prod_head);
352 Producer/consumer synchronization modes
353 ---------------------------------------
355 rte_ring supports different synchronization modes for producers and consumers.
356 These modes can be specified at ring creation/init time via ``flags``
358 That should help users to configure ring in the most suitable way for his
359 specific usage scenarios.
360 Currently supported modes:
362 .. _Ring_Library_MPMC_Mode:
367 Multi-producer (/multi-consumer) mode. This is a default enqueue (/dequeue)
368 mode for the ring. In this mode multiple threads can enqueue (/dequeue)
369 objects to (/from) the ring. For 'classic' DPDK deployments (with one thread
370 per core) this is usually the most suitable and fastest synchronization mode.
371 As a well known limitation - it can perform quite pure on some overcommitted
374 .. _Ring_Library_SPSC_Mode:
378 Single-producer (/single-consumer) mode. In this mode only one thread at a time
379 is allowed to enqueue (/dequeue) objects to (/from) the ring.
381 .. _Ring_Library_MT_RTS_Mode:
386 Multi-producer (/multi-consumer) with Relaxed Tail Sync (RTS) mode.
387 The main difference from the original MP/MC algorithm is that
388 tail value is increased not by every thread that finished enqueue/dequeue,
389 but only by the last one.
390 That allows threads to avoid spinning on ring tail value,
391 leaving actual tail value change to the last thread at a given instance.
392 That technique helps to avoid the Lock-Waiter-Preemption (LWP) problem on tail
393 update and improves average enqueue/dequeue times on overcommitted systems.
394 To achieve that RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation:
395 one for head update, second for tail update.
396 In comparison the original MP/MC algorithm requires one 32-bit CAS
397 for head update and waiting/spinning on tail value.
399 .. _Ring_Library_MT_HTS_Mode:
404 Multi-producer (/multi-consumer) with Head/Tail Sync (HTS) mode.
405 In that mode enqueue/dequeue operation is fully serialized:
406 at any given moment only one enqueue/dequeue operation can proceed.
407 This is achieved by allowing a thread to proceed with changing ``head.value``
408 only when ``head.value == tail.value``.
409 Both head and tail values are updated atomically (as one 64-bit value).
410 To achieve that 64-bit CAS is used by head update routine.
411 That technique also avoids the Lock-Waiter-Preemption (LWP) problem on tail
412 update and helps to improve ring enqueue/dequeue behavior in overcommitted
413 scenarios. Another advantage of fully serialized producer/consumer -
414 it provides the ability to implement MT safe peek API for rte_ring.
419 For ring with serialized producer/consumer (HTS sync mode) it is possible
420 to split public enqueue/dequeue API into two phases:
422 * enqueue/dequeue start
424 * enqueue/dequeue finish
426 That allows user to inspect objects in the ring without removing them
427 from it (aka MT safe peek) and reserve space for the objects in the ring
428 before actual enqueue.
429 Note that this API is available only for two sync modes:
431 * Single Producer/Single Consumer (SP/SC)
433 * Multi-producer/Multi-consumer with Head/Tail Sync (HTS)
435 It is a user responsibility to create/init ring with appropriate sync modes
436 selected. As an example of usage:
440 /* read 1 elem from the ring: */
441 uint32_t n = rte_ring_dequeue_bulk_start(ring, &obj, 1, NULL);
444 if (object_examine(obj) == KEEP)
445 /* decided to keep it in the ring. */
446 rte_ring_dequeue_finish(ring, 0);
448 /* decided to remove it from the ring. */
449 rte_ring_dequeue_finish(ring, n);
452 Note that between ``_start_`` and ``_finish_`` none other thread can proceed
453 with enqueue(/dequeue) operation till ``_finish_`` completes.
455 Ring Peek Zero Copy API
456 -----------------------
458 Along with the advantages of the peek APIs, zero copy APIs provide the ability
459 to copy the data to the ring memory directly without the need for temporary
460 storage (for ex: array of mbufs on the stack).
462 These APIs make it possible to split public enqueue/dequeue API into 3 phases:
464 * enqueue/dequeue start
466 * copy data to/from the ring
468 * enqueue/dequeue finish
470 Note that this API is available only for two sync modes:
472 * Single Producer/Single Consumer (SP/SC)
474 * Multi-producer/Multi-consumer with Head/Tail Sync (HTS)
476 It is a user responsibility to create/init ring with appropriate sync modes.
477 Following is an example of usage:
481 /* Reserve space on the ring */
482 n = rte_ring_enqueue_zc_burst_start(r, 32, &zcd, NULL);
483 /* Pkt I/O core polls packets from the NIC */
485 nb_rx = rte_eth_rx_burst(portid, queueid, zcd->ptr1, zcd->n1);
486 if (nb_rx == zcd->n1 && n != zcd->n1)
487 nb_rx += rte_eth_rx_burst(portid, queueid, zcd->ptr2,
489 /* Provide packets to the packet processing cores */
490 rte_ring_enqueue_zc_finish(r, nb_rx);
493 Note that between ``_start_`` and ``_finish_`` no other thread can proceed
494 with enqueue(/dequeue) operation till ``_finish_`` completes.
499 * `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&view=markup>`_ (version 8)
501 * `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&view=markup>`_ (version 8)
503 * `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_