Single-thread data loop (Phase A): DataPlane + epoll PollDriver, lock removal #6

Merged
vxfemboy merged 8 commits from io-uring-busy-poll into main 2026-07-01 03:40:02 +00:00
vxfemboy commented 2026-07-01 03:35:48 +00:00 (Migrated from github.com)

Phase A of the io_uring busy-poll milestone (spec + plan for both phases included; Phase B — the io_uring driver — follows on a later branch).

Replaces yipd's two-thread Arc<Mutex> data plane with a single-threaded event loop:

  • DataPlane (bin/yipd/src/dataplane.rs) — all packet logic (seal/FEC/frame; deframe/decode/open; control-handler; ARQ; feedback tick) as a mutex-free, I/O-free struct, unit-tested end to end (round-trip, control/ARQ, forged-packet rejection).
  • PollDriver (crates/yip-io/src/poll.rs) — a single-threaded epoll loop over the UDP + TUN fds driving a Dispatch trait; drop-tolerant on transient UDP send errors; unsafe confined to yip-io with SAFETY comments.
  • tunnel.rs::run(): ~637 → ~93 lines, no threads, no Arc/Mutex, no .join(). yipd stays #![forbid(unsafe_code)].

Measured (release, netns, no netem): tunnel RTT ~0.51 → ~0.36 ms (lock/handoff removal — the latency north-star); clean-link single-stream throughput holds within variance (~419 vs ~457 Mbit/s; the small single-core ceiling is the accepted trade, with multi-queue as the deferred scaling lever). No wire change — all three netns tests (ping, ping-under-loss, arq-integrity 129 retransmits) pass on the single-threaded daemon.

Reviewed per-task (Task 3's epoll rewrite got a full opus review that caught + fixed a send-error drop-tolerance regression the netns gate misses).

🤖 Generated with Claude Code

**Phase A of the io_uring busy-poll milestone** (spec + plan for both phases included; Phase B — the io_uring driver — follows on a later branch). Replaces yipd's two-thread `Arc<Mutex>` data plane with a single-threaded event loop: - **`DataPlane`** (`bin/yipd/src/dataplane.rs`) — all packet logic (seal/FEC/frame; deframe/decode/open; control-handler; ARQ; feedback tick) as a **mutex-free, I/O-free** struct, unit-tested end to end (round-trip, control/ARQ, forged-packet rejection). - **`PollDriver`** (`crates/yip-io/src/poll.rs`) — a single-threaded `epoll` loop over the UDP + TUN fds driving a `Dispatch` trait; drop-tolerant on transient UDP send errors; `unsafe` confined to yip-io with SAFETY comments. - `tunnel.rs::run()`: **~637 → ~93 lines**, no threads, no `Arc`/`Mutex`, no `.join()`. yipd stays `#![forbid(unsafe_code)]`. **Measured (release, netns, no netem):** tunnel RTT **~0.51 → ~0.36 ms** (lock/handoff removal — the latency north-star); clean-link single-stream throughput holds within variance (~419 vs ~457 Mbit/s; the small single-core ceiling is the accepted trade, with multi-queue as the deferred scaling lever). **No wire change** — all three netns tests (ping, ping-under-loss, arq-integrity 129 retransmits) pass on the single-threaded daemon. Reviewed per-task (Task 3's epoll rewrite got a full opus review that caught + fixed a send-error drop-tolerance regression the netns gate misses). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No description provided.