How do people generally approach lifetimes of allocations #964
-
The way I see it theres two lifetimes associated with liburing:
The former seems pretty easy, we just free on I found this whilst going through the docs, which gives me some confidence:
However if the ring has SQ_POLL enabled is it possible that these calls are never made? I guess theres another question there which is: Is |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Most requests will follow the guarantee that any meta data structures (like the iovec for a read/write, for example) must remain stable until submission has been done. This means until io_uring_submit() returns. For SQPOLL, it's not possible for the application to know when the request has been consumed by the kernel thread, so for that case, data structures need to remain stable until the CQE for the given request has been posted. Basically liburing caches the SQ ring tail, preventing SQPOLL or just the kernel in general from seeing request that have been prepared with a sequence of io_uring_get_sqe() + io_uring_prep_foo(sqe). Once io_uring_submit() is called, it calls __io_uring_sq_flush() which takes care of making prepared SQEs visible in the SQ ring for the kernel to consume. |
Beta Was this translation helpful? Give feedback.
-
I handle all the lifetimes in io_uring by heap-allocating some sort of per-operation state. This is kept alive by single-threaded reference counted pointers. The SQE <-> CQE pair has one half of the ownership and then the actual application code written by the developer participates in the other half. To this end, everything is guaranteed to be kept alive and gives the user a nice sound interface. It gets a bit trickier for the multishot ops but in general, I can't complain. |
Beta Was this translation helpful? Give feedback.
Most requests will follow the guarantee that any meta data structures (like the iovec for a read/write, for example) must remain stable until submission has been done. This means until io_uring_submit() returns. For SQPOLL, it's not possible for the application to know when the request has been consumed by the kernel thread, so for that case, data structures need to remain stable until the CQE for the given request has been posted.
Basically liburing caches the SQ ring tail, preventing SQPOLL or just the kernel in general from seeing request that have been prepared with a sequence of io_uring_get_sqe() + io_uring_prep_foo(sqe). Once io_uring_submit() is called, it calls __io_uring_sq_flus…