libuv / libuv/libuv

linux: use io_uring for network i/o

Open
#4,044 7 comments 18 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

rfc
Dominant language
C
Stars
27.2k
Forks
3.9k
Avg merge
2d 16h
Merged PRs (30d)
17

Description

This is an invitation to brainstorm. :-)

There is currently a mismatch between io_uring's and libuv's I/O model that stops libuv from achieving maximal performance if it were to use io_uring for network i/o, particularly when it comes to receiving incoming connections and packets.

https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023 describes best practices that can be summarized as:

  1. keep multiple i/o requests enqueued (mismatch: libuv's "firehose" approach to incoming connections/data)

  2. let io_uring manage buffers (mismatch: libuv punts memory management to the user)

I've been thinking about what needs to change and this is what I came up with so far:

  1. add request-based apis for reading data and accepting connections, like int uv_stream_read(uv_read_t* req, uv_stream_t* handle, uv_buf_t* bufs, size_t nbufs, unsigned flags, uv_stream_read_cb cb) where uv_stream_read_cb is void (*)(uv_read_t* req, ssize_t nread, uv_buf_t* bufs)

  2. add a memory pool api that tells libuv it can allocate this much memory for buffers. Strawman proposal: uv_loop_configure(loop, UV_LOOP_SET_BUFFER_POOL_SIZE, 8<<20) with 0 meaning "pick a suitable default"

  3. introduce a flag that tells uv_stream_read() to ignore bufs and interpret nbufs as "bytes to read into buffer pool" (kind of ugly, suggestions welcome)

  4. introduce a new int uv_release_buffers(loop, bufs, nbufs) (maybe s/loop/handle/?) that tells libuv it's okay to reuse those buffer pool slices again. Alternatively: reclaim the memory automatically when uv_stream_read_cb returns but that means users may have to copy, or that they hold on longer to the buffers than is needed (inefficient if they queue up new requests in the callback)

Libuv-on-Windows is internally already request-based so should be relatively easy to adapt.

Suggestions for improvements very welcome!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing libuv's current stream read and connection-accept behavior, then compare it with the io_uring networking practices linked in the issue. The proposed entry points are uv_stream_read(), uv_loop_configure(), and uv_release_buffers(); no files or tests are named. Done is not defined because this remains an open API and architecture brainstorming discussion.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
networking, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
18/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.