init: DPDK → DPU learning blog (VitePress)
- VitePress static site for rendering all markdown documents - Auto-discovers .md files from dpdk-roadmap-v3 and dpdk-study-kb - Features: full-text search, dark mode, responsive design - Pages: roadmap, notes (Phase 0-3), product docs, knowledge base Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Executable
+104
@@ -0,0 +1,104 @@
|
||||
# Phase 0 · Day 2: 内核中断 + 网络收包路径
|
||||
|
||||
---
|
||||
|
||||
## 一、你的系统数据
|
||||
|
||||
```
|
||||
IRQ 56 (ens160-rxtx-0): CPU0:1329万 CPU1:191万 CPU2:112万 CPU3:676万
|
||||
IRQ 57 (ens160-rxtx-1): CPU0:11万 CPU1:33万 CPU2:36万 CPU3:38万
|
||||
IRQ 58 (ens160-rxtx-2): CPU0:19万 CPU1:37万 CPU2:43万 CPU3:42万
|
||||
IRQ 59 (ens160-rxtx-3): CPU0:30万 CPU1:39万 CPU2:52万 CPU3:52万
|
||||
IRQ 60 (ens160-event): 全 0 (事件队列, 未使用)
|
||||
|
||||
NET_RX 软中断: CPU0:1339万 CPU1:436万 CPU2:381万 CPU3:791万
|
||||
ksoftirqd: 每个 CPU 一个 (PID 16/24/30/36)
|
||||
```
|
||||
|
||||
- 4 个 MSI-X 向量 → 4 个 RX 队列 → 4 个 CPU 并行收包
|
||||
- IRQ 56 在 CPU0 上触发了 1329 万次(主流量),CPU1-3 只触发了少量——IRQ affinity 配置不均
|
||||
|
||||
## 二、收包 6 道关卡
|
||||
|
||||
```
|
||||
关卡1: 硬件中断
|
||||
网卡 DMA 写 RX ring → MSI-X 中断 → APIC → CPU → IDT → irq_handler
|
||||
此时在硬中断上下文,所有中断被屏蔽
|
||||
|
||||
关卡2: NAPI 调度
|
||||
irq_handler → napi_schedule → 关网卡中断 + 触发 NET_RX_SOFTIRQ → 返回
|
||||
源码: net/core/dev.c ____napi_schedule (line 4551)
|
||||
|
||||
关卡3: ksoftirqd
|
||||
ksoftirqd 被唤醒 → __do_softirq → net_rx_action → 遍历 poll_list
|
||||
源码: kernel/softirq.c + net/core/dev.c
|
||||
|
||||
关卡4: 驱动 poll → netif_receive_skb
|
||||
从 RX descriptor ring 取包 → alloc_skb → memcpy → netif_receive_skb(skb)
|
||||
源码: net/core/dev.c netif_receive_skb (line 5899)
|
||||
|
||||
关卡5: 协议分发 (L2→L3)
|
||||
__netif_receive_skb_core → skb->protocol → 查 ptype_base 哈希表 → ip_rcv()
|
||||
源码: net/core/dev.c __netif_receive_skb_core (line 5434)
|
||||
net/ipv4/ip_input.c ip_rcv (line 560)
|
||||
协议注册: net/ipv4/af_inet.c dev_add_pack (line 2065)
|
||||
|
||||
关卡6: TCP 收包 (L3→L4→socket)
|
||||
ip_rcv → NF_HOOK → ip_local_deliver → tcp_v4_rcv
|
||||
→ __inet_lookup_established → tcp_rcv_established (fast path!)
|
||||
→ tcp_queue_rcv → sk_data_ready → wake_up → epoll 返回
|
||||
源码: net/ipv4/tcp_ipv4.c (line 1999)
|
||||
net/ipv4/tcp_input.c tcp_rcv_established
|
||||
```
|
||||
|
||||
## 三、DPDK 为什么快
|
||||
|
||||
| 内核步骤 | 耗时 | DPDK |
|
||||
|---------|------|------|
|
||||
| MSI-X → IDT → handler | ~3us | PMD 轮询, 无中断 |
|
||||
| napi_schedule + ksoftirqd 调度 | ~5us | PMD 线程永不睡眠 |
|
||||
| alloc_skb (slab 锁) | ~1us | mbuf 从 per-lcore cache 弹出 |
|
||||
| memcpy DMA→skb | ~2us | DMA 直接写 mbuf, 零拷贝 |
|
||||
| ptype_base 查找 | ~0.3us | 应用自己解析协议 |
|
||||
| Netfilter HOOK | ~5us | 不需要 |
|
||||
| ehash 查 socket | ~1us | rte_hash_lookup |
|
||||
| copy_to_user | ~3us | 零拷贝 |
|
||||
| **总计** | **~20us** | **~1us** |
|
||||
|
||||
## 四、实战踩坑
|
||||
|
||||
### 坑 1: 中断全绑 CPU0
|
||||
- **现象**: top 看 CPU0 si=99%, 其他 CPU 空闲
|
||||
- **根因**: smp_affinity 默认只开 CPU0
|
||||
- **定位**: `cat /proc/irq/56/smp_affinity`
|
||||
- **修复**: `echo ff > /proc/irq/56/smp_affinity`
|
||||
|
||||
### 坑 2: NAPI budget 耗尽
|
||||
- **现象**: 100G 线速达不到,`ethtool -S` 看 rx_missed 增长
|
||||
- **根因**: net_rx_action 默认一次最多 300 包,收不够就返回
|
||||
- **定位**: `cat /proc/net/softnet_stat`, 第三列 = "times queue full"
|
||||
- **修复**: 增大 net.core.netdev_budget,或换 DPDK
|
||||
|
||||
### 坑 3: ksoftirqd 被抢占
|
||||
- **现象**: 收包延迟 P99 抖动严重
|
||||
- **根因**: ksoftirqd 不是实时线程,被磁盘 I/O 抢占
|
||||
- **定位**: `perf sched latency`
|
||||
- **修复**: `chrt -f 1 $(pidof ksoftirqd/0)` 或换 DPDK PMD
|
||||
|
||||
### 坑 4: Netfilter 静默丢包
|
||||
- **现象**: tcpdump 能看到包,应用收不到
|
||||
- **根因**: Docker/k8s 自动注入 iptables drop 规则
|
||||
- **定位**: `iptables -L -v -n`, 看每条规则的计数器
|
||||
|
||||
### 坑 5: TCP backlog 满
|
||||
- **现象**: 客户端 connect 超时
|
||||
- **根因**: accept queue=128, 第 129 个 SYN 被内核静默丢弃
|
||||
- **定位**: `netstat -s | grep overflow`
|
||||
- **修复**: `echo 4096 > /proc/sys/net/core/somaxconn`
|
||||
|
||||
## 五、检验标准
|
||||
- [ ] 能画中断→NAPI→ksoftirqd→poll→netif_receive_skb→ip_rcv→tcp_v4_rcv 完整调用链
|
||||
- [ ] 能解释 NAPI 为什么要关中断、用软中断
|
||||
- [ ] 能说 ptype_base 的作用
|
||||
- [ ] 能列 DPDK 比内核快 ≥5 个原因
|
||||
- [ ] 能在 /proc/interrupts 和 /proc/softirqs 找到你的网卡
|
||||
Reference in New Issue
Block a user