1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2010-2014 Intel Corporation. 3 4.. _Ring_Library: 5 6Ring Library 7============ 8 9The ring allows the management of queues. 10Instead of having a linked list of infinite size, the rte_ring has the following properties: 11 12* FIFO 13 14* Maximum size is fixed, the objects are stored in a table 15 16* Objects can be pointers or elements of multiple of 4 byte size 17 18* Lockless implementation 19 20* Multi-consumer or single-consumer dequeue 21 22* Multi-producer or single-producer enqueue 23 24* Bulk dequeue - Dequeues the specified count of objects if successful; otherwise fails 25 26* Bulk enqueue - Enqueues the specified count of objects if successful; otherwise fails 27 28* Burst dequeue - Dequeue the maximum available objects if the specified count cannot be fulfilled 29 30* Burst enqueue - Enqueue the maximum available objects if the specified count cannot be fulfilled 31 32The advantages of this data structure over a linked list queue are as follows: 33 34* Faster; only requires a single 32 bit Compare-And-Swap instruction instead of several pointer size Compare-And-Swap instructions. 35 36* Simpler than a full lockless queue. 37 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. 41 42The disadvantages: 43 44* Size is fixed 45 46* Having many rings costs more in terms of memory than a linked list queue. An empty ring contains at least N objects. 47 48A simplified representation of a Ring is shown in with consumer and producer head and tail pointers to objects stored in the data structure. 49 50.. _figure_ring1: 51 52.. figure:: img/ring1.* 53 54 Ring Structure 55 56 57References for Ring Implementation in FreeBSD* 58---------------------------------------------- 59 60The following code was added in FreeBSD 8.0, and is used in some network device drivers (at least in Intel drivers): 61 62 * `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&view=markup>`_ 63 64 * `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&view=markup>`_ 65 66Lockless Ring Buffer in Linux* 67------------------------------ 68 69The following is a link describing the `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_. 70 71Additional Features 72------------------- 73 74Name 75~~~~ 76 77A ring is identified by a unique name. 78It is not possible to create two rings with the same name (rte_ring_create() returns NULL if this is attempted). 79 80Use Cases 81--------- 82 83Use cases for the Ring library include: 84 85 * Communication between applications in the DPDK 86 87 * Used by memory pool allocator 88 89Anatomy of a Ring Buffer 90------------------------ 91 92This section explains how a ring buffer operates. 93The ring structure is composed of two head and tail couples; one is used by producers and one is used by the consumers. 94The figures of the following sections refer to them as prod_head, prod_tail, cons_head and cons_tail. 95 96Each figure represents a simplified state of the ring, which is a circular buffer. 97The content of the function local variables is represented on the top of the figure, 98and the content of ring structure is represented on the bottom of the figure. 99 100Single Producer Enqueue 101~~~~~~~~~~~~~~~~~~~~~~~ 102 103This section explains what occurs when a producer adds an object to the ring. 104In this example, only the producer head and tail (prod_head and prod_tail) are modified, 105and there is only one producer. 106 107The initial state is to have a prod_head and prod_tail pointing at the same location. 108 109Enqueue First Step 110^^^^^^^^^^^^^^^^^^ 111 112First, *ring->prod_head* and ring->cons_tail are copied in local variables. 113The prod_next local variable points to the next element of the table, or several elements after in case of bulk enqueue. 114 115If there is not enough room in the ring (this is detected by checking cons_tail), it returns an error. 116 117 118.. _figure_ring-enqueue1: 119 120.. figure:: img/ring-enqueue1.* 121 122 Enqueue first step 123 124 125Enqueue Second Step 126^^^^^^^^^^^^^^^^^^^ 127 128The second step is to modify *ring->prod_head* in ring structure to point to the same location as prod_next. 129 130The added object is copied in the ring (obj4). 131 132 133.. _figure_ring-enqueue2: 134 135.. figure:: img/ring-enqueue2.* 136 137 Enqueue second step 138 139 140Enqueue Last Step 141^^^^^^^^^^^^^^^^^ 142 143Once 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*. 144The enqueue operation is finished. 145 146 147.. _figure_ring-enqueue3: 148 149.. figure:: img/ring-enqueue3.* 150 151 Enqueue last step 152 153 154Single Consumer Dequeue 155~~~~~~~~~~~~~~~~~~~~~~~ 156 157This section explains what occurs when a consumer dequeues an object from the ring. 158In this example, only the consumer head and tail (cons_head and cons_tail) are modified and there is only one consumer. 159 160The initial state is to have a cons_head and cons_tail pointing at the same location. 161 162Dequeue First Step 163^^^^^^^^^^^^^^^^^^ 164 165First, ring->cons_head and ring->prod_tail are copied in local variables. 166The cons_next local variable points to the next element of the table, or several elements after in the case of bulk dequeue. 167 168If there are not enough objects in the ring (this is detected by checking prod_tail), it returns an error. 169 170 171.. _figure_ring-dequeue1: 172 173.. figure:: img/ring-dequeue1.* 174 175 Dequeue last step 176 177 178Dequeue Second Step 179^^^^^^^^^^^^^^^^^^^ 180 181The second step is to modify ring->cons_head in the ring structure to point to the same location as cons_next. 182 183The dequeued object (obj1) is copied in the pointer given by the user. 184 185 186.. _figure_ring-dequeue2: 187 188.. figure:: img/ring-dequeue2.* 189 190 Dequeue second step 191 192 193Dequeue Last Step 194^^^^^^^^^^^^^^^^^ 195 196Finally, ring->cons_tail in the ring structure is modified to point to the same location as ring->cons_head. 197The dequeue operation is finished. 198 199 200.. _figure_ring-dequeue3: 201 202.. figure:: img/ring-dequeue3.* 203 204 Dequeue last step 205 206 207Multiple Producers Enqueue 208~~~~~~~~~~~~~~~~~~~~~~~~~~ 209 210This section explains what occurs when two producers concurrently add an object to the ring. 211In this example, only the producer head and tail (prod_head and prod_tail) are modified. 212 213The initial state is to have a prod_head and prod_tail pointing at the same location. 214 215Multiple Producers Enqueue First Step 216^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 217 218On both cores, *ring->prod_head* and ring->cons_tail are copied in local variables. 219The prod_next local variable points to the next element of the table, 220or several elements after in the case of bulk enqueue. 221 222If there is not enough room in the ring (this is detected by checking cons_tail), it returns an error. 223 224 225.. _figure_ring-mp-enqueue1: 226 227.. figure:: img/ring-mp-enqueue1.* 228 229 Multiple producer enqueue first step 230 231 232Multiple Producers Enqueue Second Step 233^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 234 235The second step is to modify ring->prod_head in the ring structure to point to the same location as prod_next. 236This operation is done using a Compare And Swap (CAS) instruction, which does the following operations atomically: 237 238* If ring->prod_head is different to local variable prod_head, 239 the CAS operation fails, and the code restarts at first step. 240 241* Otherwise, ring->prod_head is set to local prod_next, 242 the CAS operation is successful, and processing continues. 243 244In the figure, the operation succeeded on core 1, and step one restarted on core 2. 245 246 247.. _figure_ring-mp-enqueue2: 248 249.. figure:: img/ring-mp-enqueue2.* 250 251 Multiple producer enqueue second step 252 253 254Multiple Producers Enqueue Third Step 255^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 256 257The CAS operation is retried on core 2 with success. 258 259The core 1 updates one element of the ring(obj4), and the core 2 updates another one (obj5). 260 261 262.. _figure_ring-mp-enqueue3: 263 264.. figure:: img/ring-mp-enqueue3.* 265 266 Multiple producer enqueue third step 267 268 269Multiple Producers Enqueue Fourth Step 270^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 271 272Each core now wants to update ring->prod_tail. 273A core can only update it if ring->prod_tail is equal to the prod_head local variable. 274This is only true on core 1. The operation is finished on core 1. 275 276 277.. _figure_ring-mp-enqueue4: 278 279.. figure:: img/ring-mp-enqueue4.* 280 281 Multiple producer enqueue fourth step 282 283 284Multiple Producers Enqueue Last Step 285^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 286 287Once ring->prod_tail is updated by core 1, core 2 is allowed to update it too. 288The operation is also finished on core 2. 289 290 291.. _figure_ring-mp-enqueue5: 292 293.. figure:: img/ring-mp-enqueue5.* 294 295 Multiple producer enqueue last step 296 297 298Modulo 32-bit Indexes 299~~~~~~~~~~~~~~~~~~~~~ 300 301In the preceding figures, the prod_head, prod_tail, cons_head and cons_tail indexes are represented by arrows. 302In the actual implementation, these values are not between 0 and size(ring)-1 as would be assumed. 303The indexes are between 0 and 2^32 -1, and we mask their value when we access the object table (the ring itself). 30432-bit modulo also implies that operations on indexes (such as, add/subtract) will automatically do 2^32 modulo 305if the result overflows the 32-bit number range. 306 307The following are two examples that help to explain how indexes are used in a ring. 308 309.. note:: 310 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. 314 315 316.. _figure_ring-modulo1: 317 318.. figure:: img/ring-modulo1.* 319 320 Modulo 32-bit indexes - Example 1 321 322 323This ring contains 11000 entries. 324 325 326.. _figure_ring-modulo2: 327 328.. figure:: img/ring-modulo2.* 329 330 Modulo 32-bit indexes - Example 2 331 332 333This ring contains 12536 entries. 334 335.. note:: 336 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. 339 340The code always maintains a distance between producer and consumer between 0 and size(ring)-1. 341Thanks to this property, we can do subtractions between 2 index values in a modulo-32bit base: 342that's why the overflow of the indexes is not a problem. 343 344At any time, entries and free_entries are between 0 and size(ring)-1, 345even if only the first term of subtraction has overflowed: 346 347.. code-block:: c 348 349 uint32_t entries = (prod_tail - cons_head); 350 uint32_t free_entries = (mask + cons_tail -prod_head); 351 352Producer/consumer synchronization modes 353--------------------------------------- 354 355rte_ring supports different synchronization modes for producers and consumers. 356These modes can be specified at ring creation/init time via ``flags`` 357parameter. 358That should help users to configure ring in the most suitable way for his 359specific usage scenarios. 360Currently supported modes: 361 362MP/MC (default one) 363~~~~~~~~~~~~~~~~~~~ 364 365Multi-producer (/multi-consumer) mode. This is a default enqueue (/dequeue) 366mode for the ring. In this mode multiple threads can enqueue (/dequeue) 367objects to (/from) the ring. For 'classic' DPDK deployments (with one thread 368per core) this is usually the most suitable and fastest synchronization mode. 369As a well known limitation - it can perform quite pure on some overcommitted 370scenarios. 371 372SP/SC 373~~~~~ 374Single-producer (/single-consumer) mode. In this mode only one thread at a time 375is allowed to enqueue (/dequeue) objects to (/from) the ring. 376 377MP_RTS/MC_RTS 378~~~~~~~~~~~~~ 379 380Multi-producer (/multi-consumer) with Relaxed Tail Sync (RTS) mode. 381The main difference from the original MP/MC algorithm is that 382tail value is increased not by every thread that finished enqueue/dequeue, 383but only by the last one. 384That allows threads to avoid spinning on ring tail value, 385leaving actual tail value change to the last thread at a given instance. 386That technique helps to avoid the Lock-Waiter-Preemption (LWP) problem on tail 387update and improves average enqueue/dequeue times on overcommitted systems. 388To achieve that RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation: 389one for head update, second for tail update. 390In comparison the original MP/MC algorithm requires one 32-bit CAS 391for head update and waiting/spinning on tail value. 392 393MP_HTS/MC_HTS 394~~~~~~~~~~~~~ 395 396Multi-producer (/multi-consumer) with Head/Tail Sync (HTS) mode. 397In that mode enqueue/dequeue operation is fully serialized: 398at any given moment only one enqueue/dequeue operation can proceed. 399This is achieved by allowing a thread to proceed with changing ``head.value`` 400only when ``head.value == tail.value``. 401Both head and tail values are updated atomically (as one 64-bit value). 402To achieve that 64-bit CAS is used by head update routine. 403That technique also avoids the Lock-Waiter-Preemption (LWP) problem on tail 404update and helps to improve ring enqueue/dequeue behavior in overcommitted 405scenarios. Another advantage of fully serialized producer/consumer - 406it provides the ability to implement MT safe peek API for rte_ring. 407 408Ring Peek API 409------------- 410 411For ring with serialized producer/consumer (HTS sync mode) it is possible 412to split public enqueue/dequeue API into two phases: 413 414* enqueue/dequeue start 415 416* enqueue/dequeue finish 417 418That allows user to inspect objects in the ring without removing them 419from it (aka MT safe peek) and reserve space for the objects in the ring 420before actual enqueue. 421Note that this API is available only for two sync modes: 422 423* Single Producer/Single Consumer (SP/SC) 424 425* Multi-producer/Multi-consumer with Head/Tail Sync (HTS) 426 427It is a user responsibility to create/init ring with appropriate sync modes 428selected. As an example of usage: 429 430.. code-block:: c 431 432 /* read 1 elem from the ring: */ 433 uint32_t n = rte_ring_dequeue_bulk_start(ring, &obj, 1, NULL); 434 if (n != 0) { 435 /* examine object */ 436 if (object_examine(obj) == KEEP) 437 /* decided to keep it in the ring. */ 438 rte_ring_dequeue_finish(ring, 0); 439 else 440 /* decided to remove it from the ring. */ 441 rte_ring_dequeue_finish(ring, n); 442 } 443 444Note that between ``_start_`` and ``_finish_`` none other thread can proceed 445with enqueue(/dequeue) operation till ``_finish_`` completes. 446 447References 448---------- 449 450 * `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) 451 452 * `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) 453 454 * `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_ 455