oxidecomputer / oxidecomputer/propolis

block/file: probably(?) want an aio backend

Open
#1,042 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

local storage storage
Dominant language
Rust
Stars
270
Forks
42
Avg merge
4d 5h
Merged PRs (30d)
6

Description

the existing file backend in block/file.rs gets us to pretty thrilling throughput (iops/bandwidth) figures (given enough workers threads), but is really pushing against the system to get that throughput. given files/devices/raw zvols that support async I/O, we can probably get much better throughput without needing several hundred threads by "just" doing async I/O from propolis. port_associate(3C) talks about exactly what we might want to do in Bind AIO transaction to a specific port.

the math

we have a whole bunch of Propolis threads whose only purpose is to consume stack space, go into the kernel, wait, come back, and maybe sleep. the context switching from all this ends up on the order of 10% of total CPU time (or closer to 20% of non-idle CPU time). each I/O ends up at biowait() in the kernel (twice!), which is especially egregious for writes that complete in single-digit microseconds to the hardware. we're just offering up millions of opportunities to context switch too eagerly.

a different problem is that to plumb all the throughput hardware might support, we may need a truly astounding number of threads. with some relatively conservative figures, assume a disk can support 2M reads/sec at 100 microseconds per read. that gets you 200 seconds per second of waiting, and if we have one I/O per thread, that implies at least 200 threads per disk. context switching gets even worse.

then there's the number of queues. we can tune the number of NVMe queues up, and that's great, but even at 64 queues that's ~4 threads constantly fighting over each SQ/CQ state lock. not great.

so, the math doesn't look good for getting much better with synchronous I/O!

Contributor guide

No contributing guide indexed for this repository

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 reading block/file.rs and the illumos port_associate(3C) documentation referenced in the issue. The issue describes a possible asynchronous I/O backend but names no tests, implementation entry point beyond block/file.rs, or acceptance criteria, so the completion boundary needs to be established before work begins.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, operating-systems, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.