3

From the paper on io_uring, the submission ring contains indices into a submission array, where the submission event itself is stored. The documentation explains this layer of indirection as follows:

One important difference is that while the CQ ring is directly indexing the shared array of cqes, the submission side has an indirection array between them. Hence the submission side ring buffer is an index into this array, which in turn contains the index into the sqes. This might initially seem odd and confusing, but there's some reasoning behind it. Some applications may embed request units inside internal data structures, and this allows them the flexibility to do so while retaining the ability to submit multiple sqes in one operation. That in turns allows for easier conversion of said applications to the io_uring interface.

But I'm not following what is meant by "applications may embed request units inside internal data structures", nor do I follow the intuition about what the layer of indirection therefore enables.

Can someone explain in other words what this layer of indirection benefits?

1 Answers1

4

I reached out to the author of the paper and got some clarity on this.

The reason there's a layer of indirection is because some applications might want to hold submission event data inside their application specific data structures. By having an array hold the events, the application can effectively take long term ownership of a slot in that array and refer to it from the application itself. Populating it over time. When ready to submit the IO, it can place the index of the event into the ring.

Whereas if the array didn't exist and instead the ring held the events, then the event would have to be copied from the application's structs to the ring during IO submission, since the ring is ordered by event-insertion-time and therefore the application couldn't "reserve" a slot ahead of time for its use. This is a bunch of extra copying that can be avoided with the array.