Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How to reuse io_uring_buf_ring after a failed/incomplete send #1441

Unanswered
stonebrakert6 asked this question in Q&A
Discussion options

TLDR:
Question: What is the status of io_uring_buf_ring's head in case io_uring_prep_send_bundle fails? Can I assume that head will be set to 0 in case of error?

Full read:
I am using ring with the following flags IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN , a ring will only be used by a single thread.

Use-case:

  1. Maintain a pre-initialized pool of io_uring_buf_ring buffer-rings. I use buf_ring to "serialize" send data.
  2. When a socket wants to send something, I Get a buffer-ring from the above pool
  3. Add data(i.e buffers) in the buffer-ring. Buffers are always added to tail, while kernel code updates the head.
  4. Then do the work i.e io_uring_prep_send_bundle, io_uring_submit etc.
  5. On successful send I can Put the buffer-ring back to the pool for reuse with a different send. Because I know that head == tail?
  6. But what happens if the send was only partial/fails? e.g I wanted to send 4MB data, but after sending 2 MB, the peer sent RST.

In this case if I try to reuse the buffer-ring for some other send i.e add buffers to it(which would always be added at tail), it might send some additional garbage(because when I added these buffers, head != tail).
Questions:

  1. Is this understanding correct? Feel free to correct me if my understanding about usage is incorrect.
  2. Technically I can do the following on send failure
    1. tail = io_uring_buf_ring_head
    2. Put buf-ring back to the pool

But that is a system call, is this the best we can do?

Can't the kernel code set head = 0 on failure(I don't know if it already does that or not)? And so we can call io_uring_buf_ring_init(which just sets tail to 0) and we're done?

Reference:
1431 and I don't think the following reply by Jens holds good for my use-case?

If whatever send(s) you have using the ring are not active, then you can manipulate the ring entries as you see fit.

You must be logged in to vote

Replies: 1 comment 1 reply

Comment options

Please let me know if my usage is incorrect or not natural/idiomatic.

You must be logged in to vote
1 reply
Comment options

FWIW it seems to me that buffer rings are more useful for multishot read/recv than for send. I did some benchmarks and vectorized send seems to have equivalent performance to send_bundle. It is of course much simpler to set up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /