Skip to content

Repository files navigation

FastWake

A production runtime — and faithful reproduction — of
"FastWake: Revisiting Host Network Stack for Interrupt-mode RDMA" (APNet 2023)

Get started · Use it · Reproduce · All docs · Real NIC


RDMA forces a choice: polling gives ~1.6 µs latency but burns a whole core per thread; interrupt mode lets many threads share a core but adds 6–10 µs of wakeup latency. Applications with more threads than cores (databases, web servers, KV stores) are stuck paying the interrupt tax.

FastWake removes the trade-off. It gives thread-per-connection applications polling-class latency while sharing cores, via two mechanisms from the paper:

  1. Per-core dispatcher — one thread per core polls every connection's completion queue and does a sub-microsecond user-level context switch to whichever connection has work. (libfastwake runtime)
  2. Fast interrupt delivery — for power-capped cores, keep interrupts but pin each CQ's interrupt to the core running its thread (CQ-to-EQ remapping on mlx5, IRQ affinity elsewhere) and shorten the kernel wakeup path.

This repo is both a usable library you can build real apps on and a complete, measured reproduction of the paper's figures. It runs on Soft-RoCE (rdma_rxe) with no special hardware, and on real RDMA NICs (ConnectX-5, etc.) with the same code.

            with FastWake (this repo, Soft-RoCE x86, 16 conns sharing 1 core)
  polling RDMA        1.34 µs   ████████████
  FastWake dispatcher 1.57 µs   ██████████████          ← polling-class, shared core
  interrupt same-core 2.40 µs   ██████████████████████
  context switch      0.07 µs   █  (user-level switch_to: 6 ns)

Install

New to RDMA, or want a guided zero-to-running walkthrough (bring up a device, run the example, write your first app)? See docs/GETTING_STARTED.md. Hitting an error? docs/TROUBLESHOOTING.md.

sudo apt-get install -y build-essential libibverbs-dev librdmacm-dev \
                        ibverbs-providers rdma-core ibverbs-utils perftest \
                        python3-matplotlib
git clone https://github.com/bojieli/FastWake && cd FastWake
make                       # libfastwake + benchmarks + examples + tools + shim
sudo make install          # -> /usr/local: lib, headers, pkg-config, fastwaked, fw-*
make kernel                # optional: switch_to/hibernate kernel module
sudo make -C kernel load   # optional: load /dev/fastwake

Verify a deployment:

fastwaked status      # RDMA devices, /dev/fastwake, affinity capabilities
fastwaked selftest    # user-level switch_to + loopback RDMA ping-pong

Use it in your application

libfastwake turns the per-core dispatcher into a small runtime. Write each connection as a normal blocking task; the runtime polls all CQs and fast-switches between tasks so every one gets polling-class latency while sharing the core:

#include <fastwake/fastwake.h>

// one cooperative task per connection — written in plain synchronous style
void serve(void *arg) {
    struct conn *c = arg;
    struct ibv_wc wc;
    for (;;) {
        fw_cq_wait(c->cq, &wc);     // yields the core to peers while idle
        handle_request(c, &wc);     // post reply, repost recv, ...
    }
}

int main(void) {
    fw_runtime *rt = fw_runtime_create(/*core=*/2);
    for (int i = 0; i < n_conns; i++)
        fw_runtime_spawn(rt, serve, &conns[i], 0);
    fw_runtime_run(rt);             // dispatcher loop: poll all CQs, switch on a CQE
}
cc app.c $(pkg-config --cflags --libs fastwake) -o app

A complete, runnable example is in examples/ — an RDMA echo RPC server (fw-echo-server) that serves many connections from one core, and its client. The fastwaked tool and the LD_PRELOAD shim (for unmodified, dynamically-linked event-mode apps; demonstrated by tests/shim_story.sh on fw-rdma-lat) round out the system.

See the full API in include/fastwake/runtime.h.

Reproduce the paper

bash repro/reproduce.sh        # build → Soft-RoCE → measure → render all figures

This regenerates every figure into results/ (data figures 1, 6, 7, 8, 9 and architecture diagrams 2–5). For a real two-host RDMA run:

CLIENT_HOST=<server-ip> DEV=mlx5_0 GID=3 bash repro/reproduce.sh

Headline results (Soft-RoCE, x86 — measured here)

This repo Paper (x86)
Polling RDMA 1.34 µs 1.6 µs
FastWake dispatcher (16 conns/core) 1.57 µs 2.0 µs
Interrupt RDMA (same core) 2.40 µs 5.7 µs
Context switch (user switch_to) 0.006 µs 0.32 µs
FastWake IPC vs pipe/semaphore 6 ns vs ~0.9 µs 0.39 vs 3–4 µs

The central result reproduces: the dispatcher matches polling latency (1.57 vs 1.34 µs) while 16 connections share one core, and beats interrupt mode at every QP count and core count (Figures 7, 8). Soft-RoCE's interrupt-mode absolute numbers are lower than the paper's because there is no hardware interrupt (~1.5 µs of PCIe/EQE delivery); the ordering and the dispatcher win are exactly as reported. Full discussion + every figure in docs/RESULTS.md.

How it works

Component What Where
libfastwake runtime per-core dispatcher (Approach 1) lib/runtime.c, include/fastwake/runtime.h
User-level switch_to callee-saved-only context switch, x86_64 + aarch64, ~6 ns lib/switch.S, lib/fiber.c
Fast interrupt delivery interrupt core affinity, CQ-to-EQ remap (mlx5) bench/interrupt_server.c, lib/affinity.c
Kernel primitives switch_to/hibernate/wake_up_process via /dev/fastwake kernel/fastwake.c
libibverbs shim route unmodified, dynamically-linked event-mode apps through FastWake shim/shim.c
RC helper tiny connection setup, rxe + mlx5 lib/rdma.c

Deeper: docs/DESIGN.md (paper→code map, the assembly switch, the kernel module, fidelity notes) · docs/REAL_NIC.md (ConnectX setup, DEVX CQ-to-EQ remap, IRQ pinning) · docs/REPRODUCTION.md (every command).

Fidelity (clean-room, honest)

Written from the paper text, not the authors' code. Two things differ on a stock kernel and are documented in docs/DESIGN.md: the paper patches the scheduler so switch_to bypasses it (~0.3 µs) — a loadable module cannot, so cross-process /dev/fastwake switch_to goes through schedule() (~1.3 µs), while the 6 ns user-level fiber switch is the faithful realization that the dispatcher actually uses; and the paper adds syscalls where we use a /dev/fastwake ioctl ABI. ARM and cross-NUMA figures are shown as paper reference (no such hardware here); the code cross-compiles and passes its tests under aarch64.

Production readiness

libfastwake is built for real deployments, not just the figures:

  • Builds with or without mlx5. libibverbs is always linked; libmlx5 is auto-detected for the real-NIC CQ-to-EQ remap path and falls back to portable IRQ-affinity steering when absent (MLX5=0 to force-disable). Runs on Soft-RoCE and real NICs from the same code.
  • Idle policies for power. FW_IDLE_BUSY (lowest latency), FW_IDLE_YIELD (share the core), FW_IDLE_SLEEP (give the core back / save power) — see docs/API.md and docs/DEPLOYMENT.md.
  • Real connection management + failure recovery. fw_cm (<fastwake/cm.h>) is an rdma_cm connection layer — standard connect/accept, peer-disconnect & QP-error detection, and reconnect — tested incl. peer-crash recovery (tests/test_cm.c). examples/cm_echo.c (fw-cm-echo) shows the full production stack: an rdma_cm acceptor feeding the dispatcher runtime, with a client that times out gracefully on a dead peer. The minimal fw_conn helper remains for benchmarks.
  • Runs on aarch64. make arm-check cross-compiles and runs the ARM context switch + scheduler under qemu-user (CI job arm64) — the hand-written assembly is executed, not just compiled.
  • Observability. Per-runtime metrics (fw_runtime_get_metrics: switches, idle ratio, live tasks) and a leveled logger (FW_LOG_LEVEL); fastwaked status surfaces both.
  • Tested, with coverage and user stories. make test runs the full unit + integration suite (fibers, runtime, IPC, affinity, logging, stats, RC helper, rdma_cm failure-injection, the kernel ioctl paths, a soak) plus user-story scenarios (failure isolation, connection churn, and the shim). make test-asan re-runs them under AddressSanitizer + UBSan and make arm-check under qemu-aarch64. make coverage reports ~78% line / ~85% function coverage of the library (gcov/lcov). This testing has already caught and fixed real bugs (an aligned_alloc UB, a switch_to security gap, and a shim wrong-ABI-version segfault). CI also builds with MLX5=0 RDMACM=0.
  • Versioned ABI. Shared object soname libfastwake.so.1; FASTWAKE_VERSION_* macros and a pkg-config fastwake module.

Production docs: API.md · DEPLOYMENT.md · SECURITY.md · LIMITATIONS.md. Man pages: fastwaked(1), fw_runtime_create(3).

License

MIT — see LICENSE. Paper: Bojie Li, Zihao Xiang, Xiaoliang Wang, Han Ruan, Jingbin Zhou, Kun Tan. FastWake: Revisiting Host Network Stack for Interrupt-mode RDMA. APNet 2023.

About

Production runtime + clean-room reproduction of FastWake: Revisiting Host Network Stack for Interrupt-mode RDMA (APNet 2023)

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages