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:
- 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. (
libfastwakeruntime) - 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)
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/fastwakeVerify a deployment:
fastwaked status # RDMA devices, /dev/fastwake, affinity capabilities
fastwaked selftest # user-level switch_to + loopback RDMA ping-ponglibfastwake 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 appA 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.
bash repro/reproduce.sh # build → Soft-RoCE → measure → render all figuresThis 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| 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.
| 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).
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.
libfastwake is built for real deployments, not just the figures:
- Builds with or without mlx5. libibverbs is always linked;
libmlx5is auto-detected for the real-NIC CQ-to-EQ remap path and falls back to portable IRQ-affinity steering when absent (MLX5=0to 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 anrdma_cmconnection 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: anrdma_cmacceptor feeding the dispatcher runtime, with a client that times out gracefully on a dead peer. The minimalfw_connhelper remains for benchmarks. - Runs on aarch64.
make arm-checkcross-compiles and runs the ARM context switch + scheduler under qemu-user (CI jobarm64) — 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 statussurfaces both. - Tested, with coverage and user stories.
make testruns 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-asanre-runs them under AddressSanitizer + UBSan andmake arm-checkunder qemu-aarch64.make coveragereports ~78% line / ~85% function coverage of the library (gcov/lcov). This testing has already caught and fixed real bugs (analigned_allocUB, aswitch_tosecurity gap, and a shim wrong-ABI-version segfault). CI also builds withMLX5=0 RDMACM=0. - Versioned ABI. Shared object soname
libfastwake.so.1;FASTWAKE_VERSION_*macros and a pkg-configfastwakemodule.
Production docs: API.md ·
DEPLOYMENT.md ·
SECURITY.md ·
LIMITATIONS.md. Man pages: fastwaked(1),
fw_runtime_create(3).
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.

