Skip to content

Bump bundled libuv to ≥1.49 so io_uring isn't silently on by default #752

Description

@hixichen

Problem

uvloop vendors libuv 1.48.0 (vendor/libuv submodule SHA e9f29cb9… → tag v1.48.0, 2024-02-07). On kernels ≥ 5.10.186 that libuv turns on io_uring by default — an IORING_SETUP_SQPOLL ring for async file ops and an IORING_OP_EPOLL_CTL batching ring for epoll_ctl. Nothing in the stack opts in:

app → uvloop.run() → uvloop → bundled libuv 1.48 → io_uring_enter

Observed via an eBPF tracepoint on io_uring_setup/io_uring_enter: uvloop-driven processes issue those syscalls during normal startup, before any app file I/O.

Why

io_uring bypasses the syscall boundary seccomp filters on. Ops inside the ring (openat, read, write, connect) aren't individual syscalls — seccomp can only allow/deny io_uring_enter wholesale, not the ops inside. So if you relax the profile to silence the inevitable EPERM noise, you punch a hole through the whole seccomp profile. The default Kubernetes RuntimeDefault profile denies io_uring_setup (#426), which is correct — but means uvloop-driven processes noisily fail into libuv's epoll+threadpool fallback on every loop init.

libuv already agreed: v1.49.0 disabled SQPOLL io_uring by default (#4492). The gap isn't libuv — it's consumers still bundling 1.48.

uvloop is the layer that controls io_uring exposure for most of the Python ecosystem (via uvicorn[standard] → uvloop). Today that choice is "io_uring on by default, suppressed only by seccomp."

Proposal

  1. Bump vendor/libuv to ≥ 1.49.0. Consistent with prior uvloop libuv bumps (v0.15.0, v0.14.0, etc.). Removes the SQPOLL ring from the default footprint.
  2. Document the io_uring behavior + the UV_USE_IO_URING=0 escape hatch in the README. (Note: the env var fully gates io_uring in 1.48; in 1.49+ the IORING_OP_EPOLL_CTL batching ring is no longer gated by it — verify against whatever version you ship.)
  3. Optionally expose a uvloop-level switch (UVLOOP_USE_IO_URING=0) so apps don't have to reach into libuv's env var.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions