fix(yip-io): make io_uring loopback recycle tests robust on default rmem #113

Merged
vxfemboy merged 4 commits from fix/uring-loopback-buffer-flake into main 2026-07-26 05:28:28 +00:00
vxfemboy commented 2026-07-26 02:41:51 +00:00 (Migrated from github.com)

Problem

Two io_uring tests fail deterministically on any box with a default UDP receive buffer:

  • uring_loopback_roundtrip_recycles_recv_buffers
  • uring_in_flight_send_table_reuses_slots_after_completions

Both blasted all datagrams into the socket before draining, then asserted more than 256 (RING_BUFS / SEND_SLOTS) round-trip. That requires the kernel to buffer >256 datagrams at once, but the default net.core.rmem_default (~208 KB) only holds ~230 small datagrams (per-skb truesize overhead). Result on a stock box: got 237, needed >256 → fail. It only passed where rmem was tuned up.

Fix

Interleave send and drain with a bounded in-flight window (64), so the kernel receive buffer never has to hold more than 64 at once. Nothing is dropped, both counts reach total on any box.

The test's intent is preserved: recycling of the fixed pool is still proven by round-tripping far more than the pool size through it, and a genuine leak still stalls at ≤ pool size and fails both asserts.

Verify

  • Each test 10/10 green locally on a box with default rmem_default = 212992.
  • Full cargo test workspace suite passes (pre-commit hook).
  • Bonus: no more stall-spinning — each test drops from ~4.6 s to ~0.2 s.
## Problem Two io_uring tests fail **deterministically** on any box with a default UDP receive buffer: - `uring_loopback_roundtrip_recycles_recv_buffers` - `uring_in_flight_send_table_reuses_slots_after_completions` Both blasted all datagrams into the socket *before* draining, then asserted more than 256 (`RING_BUFS` / `SEND_SLOTS`) round-trip. That requires the kernel to buffer **>256 datagrams at once**, but the default `net.core.rmem_default` (~208 KB) only holds ~230 small datagrams (per-skb truesize overhead). Result on a stock box: `got 237, needed >256` → fail. It only passed where rmem was tuned up. ## Fix Interleave **send and drain** with a bounded in-flight window (64), so the kernel receive buffer never has to hold more than 64 at once. Nothing is dropped, both counts reach `total` on any box. The test's intent is preserved: recycling of the fixed pool is still proven by round-tripping far more than the pool size *through* it, and a genuine leak still stalls at ≤ pool size and fails both asserts. ## Verify - Each test 10/10 green locally on a box with default `rmem_default = 212992`. - Full `cargo test` workspace suite passes (pre-commit hook). - Bonus: no more stall-spinning — each test drops from ~4.6 s to ~0.2 s.
Sign in to join this conversation.
No description provided.