Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Owned Buffers #9

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Owned Buffers #9

wants to merge 3 commits into from

Conversation

supernomad
Copy link
Contributor

This change set is a large very breaking change to the API's. The TL;DR is that this moves libuio to owned buffers for all I/O calls, this means instead of using say a &mut [u8] or a &[u8] you have to use a Vec<u8> this is for both send and receive.

The long story here is that because io_uring is completion based and actually reading/writing to the buffers, the only way to guarantee that all the reads and writes are sound, is to own the actual data. Otherwise its possible for a future and its associated buffer to be dropped while the io_uring kernel threads are interacting with the supplied pointer. Unfortunately as of the latest rust there is no other way in the type system to enforce that the buffers remain live and valid without owning the vector itself inside the io_uring. This ensures that even if the future is dropped the actual buffer will remain valid until after the io_uring is done using it and it can then be safely freed or reused as needed.

However though this is a large change it paves the way for highly efficient memory utilization and the various other optimizations that io_uring brings to the table like the Recv[Msg]Multi I/O operations and provided buffers for automatic buffer selection by the kernel.

This is just the first step along the way, and the ergonomics of this very ingrained API can and will be greatly improved, likely with the addition of new structures and helpers.

This change set is required because io_uring under the hood is
completion based, as opposed to intent based like epoll/kqueue/etc this
means that the io_uring subsystem actually is what is reading/writing to
the buffers specified to calls like recv/send.

Without io_uring owning the buffers in use, there is a possibility that
the future that kicked off the I/O is dropped (including the buffer)
while io_uring is writing/reading to/from it. This would lead to very
very bad things and undefined behavior. Since we currently can't express
the lifetime constraints we really need via the Rust type system. The
only way to guarantee soundness here, is to own the buffers in question
end to end.

With the above said, this isn't all that big of a deal in the end, the
system always returns the buffers in use, and the ergonomics can be
greatly increased with proper helpers. Also this paves the way for
Recv[Msg]Multi setup and provided buffers for further enhancements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant