Skip to content

docs(fast_io): adaptive io_uring buffer-pool sizing audit + telemetry (#1834, #2045)#3499

Merged
oferchen merged 2 commits into
masterfrom
docs/iouring-adaptive-buffer-sizing
May 1, 2026
Merged

docs(fast_io): adaptive io_uring buffer-pool sizing audit + telemetry (#1834, #2045)#3499
oferchen merged 2 commits into
masterfrom
docs/iouring-adaptive-buffer-sizing

Conversation

@oferchen
Copy link
Copy Markdown
Owner

@oferchen oferchen commented May 1, 2026

Summary

  • New audit document at docs/audits/io-uring-adaptive-buffer-sizing.md
    covering EMA-driven adaptive sizing for the io_uring registered buffer
    pool, addressing tasks Scan for placeholder markers on the first line #1834 and Align cross-compile matrix with build_daemon metadata #2045.
  • Phase 1 telemetry: RegisteredBufferGroup now carries total_acquires
    and total_misses AtomicU64 counters bumped inside checkout(),
    plus a RegisteredBufferStats snapshot accessor with a miss_rate()
    helper. The stub module mirrors the API so non-Linux targets compile.
  • Phase 2 (the actual AdaptiveBufferSizer + resize driver) is
    deliberately scoped out; the audit doc fixes the design contract so
    the follow-up is mechanical.

Audit highlights

The doc cites concrete file:line locations for every claim:

  • Current sizing parameters: IoUringConfig defaults
    (crates/fast_io/src/io_uring/config.rs:330-342), for_large_files
    (config.rs:347-358), for_small_files (config.rs:362-373).
  • Pool entry point: RegisteredBufferGroup::new
    (crates/fast_io/src/io_uring/registered_buffers.rs:204-296),
    try_new (registered_buffers.rs:303-305).
  • Hot-path call sites:
    crates/fast_io/src/io_uring/file_writer.rs:215-246,
    file_writer.rs:282-308,
    crates/fast_io/src/io_uring/file_reader.rs:158-184.
  • Existing EMA prior art:
    crates/engine/src/local_copy/buffer_pool/throughput.rs:80-246
    (ThroughputTracker, alpha=0.1, WARMUP_SAMPLES=8).
  • Existing telemetry pattern:
    crates/engine/src/local_copy/buffer_pool/pool.rs:783-797,849-859
    (BufferPoolStats, OC_RSYNC_BUFFER_POOL_STATS=1).

Proposed EMA parameters: alpha=0.2, WARMUP_SAMPLES=8, sample window
of 256 acquires, MIN_BUFFERS=2, MAX_BUFFERS=min(64, kernel_cap),
GROW_THRESHOLD=10%, SHRINK_THRESHOLD=0.5%, geometric 2x grow,
linear 0.75x shrink, 4x SAMPLE_WINDOW cooldown for hysteresis.

Telemetry cost

fetch_add(1, Relaxed) on x86_64 is lock xadd (~5 ns uncontended); on
aarch64 is LDADD (similar). Two extra fetch_add per checkout is
sub-percent overhead even at sustained line-rate, and the pool is
single-threaded per ring in practice so cache-line contention is not a
concern.

Test plan

  • cargo fmt --all -- --check
  • cargo check -p fast_io --all-features --tests
  • Five new unit tests in crates/fast_io/src/io_uring/registered_buffers.rs:
    • stats_initially_zero
    • stats_count_successful_checkouts
    • stats_count_misses_on_exhaustion
    • stats_not_decremented_on_return
    • stats_miss_rate_zero_when_no_acquires
    • stats_miss_rate_all_misses
  • CI: fmt+clippy, nextest (stable), Windows, macOS, Linux musl

oferchen added 2 commits May 1, 2026 11:08
)

Add an audit doc designing EMA-driven adaptive sizing for the io_uring
registered buffer pool, plus the lightweight telemetry counters that
the design depends on.

The audit (docs/audits/io-uring-adaptive-buffer-sizing.md) covers:

- Where the current sizing constants live (IoUringConfig defaults,
  for_large_files, for_small_files) and how they reach the pool.
- Where to measure miss rate without a syscall on the hot path.
- Proposed EMA design: alpha=0.2, WARMUP_SAMPLES=8, geometric grow /
  linear shrink, hysteresis cooldown, MIN/MAX clamps.
- Integration points: Phase 1 (telemetry) lands now; Phase 2
  (AdaptiveBufferSizer + resize driver) follows.
- Risks: registered-buffer reallocation cost, RLIMIT_MEMLOCK, the
  1024-buffer kernel cap, Drop ordering, in-flight SQEs, SQPOLL,
  per-checkout fetch_add overhead.

Telemetry (Phase 1):

- RegisteredBufferGroup carries total_acquires / total_misses
  AtomicU64 counters bumped inside checkout(). Cost is two Relaxed
  fetch_add per call; sub-percent at line rate.
- A new RegisteredBufferStats snapshot type with miss_rate(), modeled
  on BufferPoolStats in the engine.
- RegisteredBufferGroup::stats() accessor.
- The stub module mirrors the API so adaptive-sizing logic compiles
  on non-Linux targets.
- Five new unit tests cover the zero state, hit path, miss path,
  return-does-not-decrement invariant, and the helper math.

Phase 2 (the actual AdaptiveBufferSizer + resize cycle) is intentionally
not in this PR. The doc is the contract.
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 1, 2026
@oferchen oferchen merged commit 0c7ca46 into master May 1, 2026
14 of 21 checks passed
@oferchen oferchen deleted the docs/iouring-adaptive-buffer-sizing branch May 1, 2026 21:09
oferchen added a commit that referenced this pull request May 5, 2026
) (#3499)

Add an audit doc designing EMA-driven adaptive sizing for the io_uring
registered buffer pool, plus the lightweight telemetry counters that
the design depends on.

The audit (docs/audits/io-uring-adaptive-buffer-sizing.md) covers:

- Where the current sizing constants live (IoUringConfig defaults,
  for_large_files, for_small_files) and how they reach the pool.
- Where to measure miss rate without a syscall on the hot path.
- Proposed EMA design: alpha=0.2, WARMUP_SAMPLES=8, geometric grow /
  linear shrink, hysteresis cooldown, MIN/MAX clamps.
- Integration points: Phase 1 (telemetry) lands now; Phase 2
  (AdaptiveBufferSizer + resize driver) follows.
- Risks: registered-buffer reallocation cost, RLIMIT_MEMLOCK, the
  1024-buffer kernel cap, Drop ordering, in-flight SQEs, SQPOLL,
  per-checkout fetch_add overhead.

Telemetry (Phase 1):

- RegisteredBufferGroup carries total_acquires / total_misses
  AtomicU64 counters bumped inside checkout(). Cost is two Relaxed
  fetch_add per call; sub-percent at line rate.
- A new RegisteredBufferStats snapshot type with miss_rate(), modeled
  on BufferPoolStats in the engine.
- RegisteredBufferGroup::stats() accessor.
- The stub module mirrors the API so adaptive-sizing logic compiles
  on non-Linux targets.
- Five new unit tests cover the zero state, hit path, miss path,
  return-does-not-decrement invariant, and the helper math.

Phase 2 (the actual AdaptiveBufferSizer + resize cycle) is intentionally
not in this PR. The doc is the contract.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant