Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

XDP、DPDK 与 kernel bypass

一句话

kernel bypass = 让 user-space app 直接看到 NIC ring buffer 而不进内核 TCP/IP stack。从 2000 年代起的 PF_RING/DNA, 到 Intel DPDK, 到 Linux 5.0+ 的 XDP+AF_XDP, 演进路径全是"把更前一段路径前移到用户态, 减少 syscall & IRQ reentry." 这章把三条主路 XDP / DPDK / AF_XDP 做对比, 看清 100 Gbps 服务器的真实 before/after.

1. kernel 网络栈的瓶颈: 1500 ns per packet

经前面章节的 mental model:

kernel TCP/IP 单 packet 处理: ~ 700-1500 ns / CPU

100 Gbps + 1500 MTU ⇒ 8 M pps ⇒ 远超单 CPU 能力. multi-queue NIC 让多 CPU 同时分担, 但每次"过 stack 个"仍是常数. bypass 干的事就是绕过 stack 这一步.

2. DPDK: Intel 2010 出品, 是 kernel bypass 工业事实标准

DPDK = Data Plane Development Kit. 把 NIC driver in user-space 改:

  • 把 NIC mmap 到 user-space;
  • 大页 + 协议 queue;
  • 轮询 thread (poll-mode driver) 自 spin in user-space 不进 IRQ;
  • batch packet 64+ 个每批进 user 处理.
// DPDK 类骨架:
while (true) {
    nb_rx = rte_eth_rx_burst(port_id, queue_id, bufs, 32);
    for (i = 0; i < nb_rx; i++) process_packet(bufs[i]);
    nb_tx = rte_eth_tx_burst(port_id, queue_id, bufs, nb_rx);
}

优势:

  • 平均 latency 1-3 μs / packet (vs 50 μs kernel);
  • 吞吐: 14 Mpps / core 几近线速 + 多 queue.

劣势:

  • CPU 100% busy poll (no sleeping);
  • NIC 整块 isolated 不能再给 kernel 其他 socket 用;
  • driver 在 user-space, 与 native Linux NIC 路径并行不兼容.

部署: HFT / NFV (网络功能虚拟化) / 5G UPF / OVS (Open vSwitch) 大量用 DPDK.

3. XDP + AF_XDP: Linux 5.0+ 内核内置 bypass

XDP 是 eBPF 在 kernel 内入口 XDP hook:

NIC RX → DMA to ring → 内核 driver → XDP hook ran in driver context →
   动作: XDP_DROP, XDP_PASS, XDP_TX, XDP_REDIRECT

XDP 不让 user-space, 它给 eBPF程序在 kernel driver 模型下早期阶段运行. 适合:

  • DDoS 拦截;
  • L4负载均衡 (Cilium LB);
  • 一致分布式 firewall.

与 DPDK 相比: XDP 不让 NIC 脱离 kernel stack, 它在 stack 入口插了 hook. 让 packet 可以直接 in-kernel 跳出 stack 而不上 ret.

AF_XDP: 与 XDP 配合, 把 packet 通过 socket 直接传到 user-space:

// XDP program 把 packet redirect 到 AF_XDP socket
int xdp_prog(struct xdp_md *ctx) {
    return bpf_redirect_map(&xsks_map, 0, XDP_PASS);
}

// user-space 绕过 stack
int sock = socket(AF_XDP, SOCK_RAW, 0);

perf:

  • XDP_DROP: 24 Mpps per CPU
  • AF_XDP round-trip user kernel boundary: ~ 10 Mpps per CPU (具体 latency 1-3 μs)

XDP vs DPDK:

  • XDP 可与 kernel stack 兼容 (按 PASS 也 用);
  • DPDK NIC 独占;
  • XDP 需要 Linux 4.18+;
  • DPDK 工业成熟度早期 higher (NIC vendors 主流), 但 XDP 在 kernel 已实 工程实测 ~ 2024 与 DPDK 持平.

4. Cilium 用 XDP 做的工业级 load balancing

Cilium/eBPF 是 K8s + LB + firewall 一致平台:

  • 来自 EC2 pod 的 packet 入 node, XDP early hook 查 priory ip + port → redirect 到本地 pod socket;
  • 完全 bypass kernel stack;
  • LB ops/s 可以 5-10× kube-proxy.

工程性: 4.18+ kernel 已可用. Cloudflare / GCP / AKS 等是常规.

5. RDMA: 完全旁路 NIC

并非所有 NIC 不是 CPU 上 dispatch. NVIDIA ConnectX + RDMA RoCE v2 让国际 NIC 可:

  • 一端 host user memory 注册 mr;
  • 另一端 user 直接 read / write mr verbs;
  • 旁路 NIC stack 和 TCP/IP.
ibv_post_send(qp, &wr, &bad);  // 直接绕 stack post send → peer host's MR

latency:

TCP via stack        50 μs
DPDK UDP             2-5 μs
RDMA                 1-2 μs
GPUDirect RDMA       <1 μs

GPUDirect RDMA 让 GPU mem to NIC zero copy, 不经 host 内存. 大模型训练 benchmark 互联依赖.

6. SmartNIC: DPU (Data Processing Unit)

NVIDIA BlueField / Intel IPU / AMD Pensando 把 NIC 升级成 SoC:

  • 双 ARM core onboard;
  • FPGA / NPU 加速引擎;
  • 加载 NVMe storage + Linux;
  • 直接处理 VXLAN / TLS / firewall / offload eBPF on NIC.

软件切换范式:

  • 在 host CPU 不算网卡 packet;
  • 在 NIC 内部把传输到 host 的仅 load 实际数据 packet;
  • host CPU 见到的 packet 不是 NIC 物理 raw, 而是 L7 已解析过的 "App 上流事件".

参考架构: DPU = next-gen SmartNIC + 自 VM / ONIC.

7. 多语言

语言kernel bypass
C / C++DPDK, VPP, mmap NIC ring
Rustasync + VPPs lib
Go不太友好的, but DPDK-binding with cgo usable
JavaApache Pulsar 形 等上Solace Onload, 但很难
Python完全不生产 sprint DPDK Python eBPF

DPDK / XDP / RDMA 工程上由 C/C++/新Rust 文化承担. 高级语言 runtime 都不独 bind, 因为 1.他们 OS runtime 要 syscall 接口, 而且没有 determinism guarantee 离 kernel-bypass 太远; 2. 用 wrapper cgo 破环 runtime 性能.

但 ECA 出产 XDP-by-Rust (aya) 现 在是的 Serious 试真 names like Solana.

8. 选择树 (按 latency 要求)

50 ms acceptable     → 通用 TCP/IP + epollioUring
1-10 ms              → kernel + connected to GRO/或 io_uring net Z
<100 μs              → XDP / AF_XDP + custom code in C / Rust
急着 HFT 1 μs        → DPDK + 用户态轮询
急着 7ns/140GB/s       → GPUDirect RDMA on CUDA + ConnectX-7

9. 这章带走的东西

  • kernel stack 默认有 ~700 ns/pkt 限 ⇒ 高 PPS 必 bypass;
  • DPDK = user-space poll mode 早 4-100×;
  • XDP = kernel 内置 bypass hook, eBPF 编程;
  • AF_XDP = XDP 版 user-space socket pass;
  • SmartNIC / DPU level: 移动 syscall 到 NIC chip;
  • DPDK 与 XDP 性能相近, 选型看 e 库 / 兼容 与 较 选择.