SPRUIU1C July 2020 – February 2024 DRA821U , DRA821U-Q1
Ring mode is used when software owns one side of the ring, and hardware or another software owns the other side. This mode allows the software that owns a side of the ring to control that side including accessing the memory directly rather than going through hardware, and software updates the hardware on any changes through the Doorbell registers. These doorbell accesses indicate when software has pushed or popped entries, allowing the entity on the other side of the ring to know when there are elements ready. The ring mode has limitations that the exposed side of the ring is completely under software control, and any atomicity needed must also be performed by software, which is why the exposed side of a ring is usually owned by a single thread of software. This limitation also means that any hardware configuration that would normally access the same ring for both pushes and pops cannot use ring mode as hardware cannot access the exposed side of the ring, such as free queues that are normally read by hardware but could also be pushed by hardware on an error.
When software is popping from the ring, it must guarantee that it never pops more elements through the Doorbell register (RINGACC_DB_j) than what is valid in the Ring Occupancy (RINGACC_OCC_j) register, which holds how many elements are ready for software consumption. There could be some elements which have data written to memory but have not received status back from memory and those are not considered ready to pop yet as the ring status has not fully updated. Therefore, just reading from memory to determine the number of elements to pop is not sufficient. If software attempts to pop more than the RINGACC_OCC_j register value, then the occupancies could go negative resulting in missed down events and spurious interrupts. An optimization for software is to read the RINGACC_OCC_j register less frequently and keep a local copy which guarantees the maximum number of allowed pops. When the software copy of RINGACC_OCC_j reaches 0, or periodically, the software can read the register to refresh the value. This must reduce the frequency of register reads instead of reading the register for every software pop.