Skip to content

Commit de58b11

Browse files
author
zc-read-impl-leader
committed
test(zc_recv): M2 functional PASS + single-core A/B perf baseline
Root cause of the earlier http=000: incremental-build trap — uipc_mbuf.o (the m_uiotombuf FSTACK_ZC_SEND hook) was NOT recompiled by 'FF_ZC_SEND=1 make' because its .o was newer than the unchanged .c, so the kernel ZC-send hook was missing (magic 0xf8ac2c00 absent). ff_zc_send then mis-handled the mbuf chain -> broken response -> http=000 for BOTH base and zc servers. Fix: remove stale uipc_mbuf.o/sys_generic.o (via rm_tmp_file.sh) and rebuild with the flags; objdump confirms the hook is present. Build rule recorded: must 'make clean' (or drop affected .o) when changing FF_ZC_* flags. After fix: curl http=200 size=438 (ff_zc_recv->segment->free + ff_zc_send all work). Single-core wrk A/B (T1/T2/T3): ZC-recv == ff_read within noise for this small-echo workload (receive copy negligible for tiny payloads under UIO_SYSSPACE; server CPU 72-84%, client/net bound). ZC-recv benefit expected for large/bulk receive; needs a large-payload workload to demonstrate. No source bug; functional path verified end-to-end on real NIC + wrk client.
1 parent 8a06862 commit de58b11

1 file changed

Lines changed: 45 additions & 65 deletions

File tree

Lines changed: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,59 @@
11
# 21 · M2 测试执行报告(ZC-RECV)
22

3-
> 执行:2026-06-11。双机:server=本机(VM-213-67,data-plane DPDK NIC 9.134.214.176 / MAC 20:90:6f:7d:5d:08,云 metadata 实测确认);client=f-stack-client(VM-211-87,9.134.211.87)。
3+
> 执行:2026-06-11。双机:server=本机(VM-213-67,data-plane DPDK NIC 9.134.214.176 / MAC 20:90:6f:7d:5d:08,云 metadata 实测确认);client=f-stack-client(VM-211-87,9.134.211.87,wrk 4.2.0 @ /tmp/wrk/wrk)。
44
> 铁律:仅记录实际执行结果,不臆造数据。
55
6-
## 1. 构建 / 启动验证(PASS)
7-
|| 命令 | 结果 |
8-
|---|---|---|
9-
| lib(FF_ZC_SEND=1 FF_ZC_RECV=1)| `make -C lib` | ✅ rc=0,-Werror 零错误 |
10-
| 符号导出 | nm libfstack.a |`T ff_zc_recv / ff_zc_mbuf_segment / ff_zc_recv_free`(已补 ff_api.symlist)|
11-
| server B(ZC-recv,-DFSTACK_ZC_SEND -DFSTACK_ZC_RECV)| cc main_zc.c | ✅ helloworld_zc_recv(29036792 B)|
12-
| server A(baseline,仅 -DFSTACK_ZC_SEND)| cc main_zc.c | ✅ helloworld_zc_base(29036576 B,略小,确认 ZC-recv 代码已链接进 B)|
13-
| server B 启动 | `./helloworld_zc_recv --conf config.ini --proc-type=primary` | ✅ DPDK EAL init OK,`Successed to register dpdk interface`,MAC 20:90:6f:7d:5d:08 |
14-
15-
## 2. 功能集成(curl)—— 被环境阻断,已证明与 ZC-recv 代码无关
16-
### 2.1 现象
17-
client `curl http://9.134.214.176/` 连续多次均 `http=000`(连接建立失败,time≈0.001s 即返回),server CPU 始终 ~9.5%(idle_sleep 下基本空闲)→ **SYN 包未到达 f-stack**
18-
19-
### 2.2 网络诊断(实测)
20-
- 云 metadata:`MAC 20:90:6f:7d:5d:08 ↔ IP 9.134.214.176`(DPDK NIC,config.ini addr 正确);`MAC 52:54:00:9e:8b:6f ↔ 9.134.213.67`(控制面 eth1)。
21-
- client 与 data-plane 同 /21 子网(9.134.208.0/21),`ip route get 9.134.214.176 → dev eth1`(直连)。
22-
- client ARP:`9.134.214.176 → fe:ee:2e:9c:ed:94`(VPC 网关/SDN MAC,非 f-stack 也非控制面);刷新 ARP 后仍解析为该 MAC。
23-
- **结论**:VPC SDN 未把发往 9.134.214.176 的报文投递到该 ENI 对应的 DPDK NIC(f-stack 收不到任何包)。
6+
## 1. 根因与修复(关键)
7+
首轮 curl 全部 http=000,曾误判为"环境问题"。经用户纠正(普通 helloworld 在 client 测试 http=200 正常)后实际调试,定位**真实根因**
248

25-
### 2.3 差分判定(关键,证明非本次代码问题)
26-
| Server | 接收路径 | curl 结果 | server CPU |
27-
|---|---|---|---|
28-
| B(ZC-recv,本次新代码)| ff_zc_recv | http=000 ×5 | ~9.4% 空闲 |
29-
| **A(baseline,纯 ff_read,历史可用路径,无任何 ZC-recv 代码)** | ff_read | **http=000 ×3(完全一致)** | ~9.5% 空闲 |
9+
- **增量编译陷阱**:先做了无 flag 的 baseline build(所有 .o 不含 FSTACK_ZC_SEND),随后 `FF_ZC_SEND=1 make``uipc_mbuf.c` 未改动、其 .o(06-09 15:48)比 .c 新而**被 make 跳过未重编译**`m_uiotombuf` 的 FSTACK_ZC_SEND 内核 hook **缺失**(objdump 验证 magic `0xf8ac2c00` 不在 uipc_mbuf.o)。
10+
- 后果:`ff_zc_send`(应答路径,A/B 两版都用)设了 magic 但内核 hook 不识别 → 把 mbuf 链指针当 char buffer → 应答崩坏,连接不可用 → http=000。
11+
- **这也解释了为何 A(baseline) 与 B(ZC-recv) 都失败**(两者应答都走 ff_zc_send)。
12+
- **修复**:删除 stale 的 `uipc_mbuf.o` / `sys_generic.o`(经 rm_tmp_file.sh),带 `FF_ZC_SEND=1 FF_ZC_RECV=1` 重编译;objdump 验证 uipc_mbuf.o 现含 `movabs $0xf8ac2c00f8ac2c00`。重链 libfstack.a + 重建 server。
13+
- **构建规约(记入)**:变更 FF_ZC_* 等编译开关后**必须 `make clean` 或删除受影响 .o 后重编译**,不能依赖增量编译(make 基于时间戳,不感知 CFLAGS 变化)。
3014

31-
**baseline 与 ZC-recv 表现完全一致、包都未到达 f-stack** ⇒ 阻断点是**数据面 VPC/ENI 投递(环境)****与 ZC-recv 实现无关**。本次 M0+M1 代码的编译、符号导出、server 启动、DPDK 注册均正常。
15+
## 2. 功能验证(PASS,修复后)
16+
|| 结果 |
17+
|---|---|
18+
| lib(clean+FF_ZC_SEND=1 FF_ZC_RECV=1)| ✅ -Werror 零错误;uipc_mbuf.o 含 ZC-send hook |
19+
| 符号导出 | ✅ ff_zc_recv / ff_zc_mbuf_segment / ff_zc_recv_free |
20+
| server B(ZC-recv)启动 | ✅ DPDK 注册 OK |
21+
| **client curl ×5** |**http=200 size=438**(ff_zc_recv→segment→free 全链路 + ff_zc_send 应答均正常)|
3222

33-
## 3. 性能基线对比 —— 因数据面阻断无法采集真实数值
34-
- 单核(lcore_mask=10 → lcore 4)A/B 压测 harness 已就绪(见 §5),但因 §2 数据面阻断,**本轮无法采集真实 req/s****不臆造数据**
35-
- **历史极限参考**(docs/freebsd_13_to_15 13.0-baseline-cvm-bench-report,同机同 config.ini 单核 lcore4,helloworld kqueue):
36-
- Smoke curl:HTTP 200,RTT 1.25 ms
37-
- T2(-t4 -c100 30s):13.0 **220,691 req/s** / 15.0 203,933 req/s
38-
- T3(-t8 -c500 30s):13.0 **239,555 req/s** / 15.0 217,100 req/s,p99 4.21→5.38 ms
39-
- ZC-recv 预期:消除 soreceive→uiomove 拷贝,大包收取场景 CPU/吞吐应有收益(待数据面恢复后用 §5 harness 实测 A/B)。
23+
## 3. 单核性能基线 A/B(lcore_mask=10 → lcore4,wrk,按 freebsd-13-to-15 方法论 T1/T2/T3)
24+
A=baseline(ff_read 接收);B=ZC-recv(ff_zc_recv 接收);二者应答均 ff_zc_send,隔离接收路径差异。
4025

41-
## 4. 数据面恢复建议(环境侧,非本代码)
42-
VPC SDN 对 9.134.214.176→DPDK NIC 的转发绑定疑似失效(历史测试曾正常,环境漂移)。建议其一:
43-
- 重新挂载/刷新该 ENI 的 IP-MAC 绑定(云控制台或 reboot);
44-
- 或确认 SDN 反欺骗对 f-stack 主动 gratuitous ARP 的要求;
45-
- 恢复后用 §5 harness 直接复测。
26+
| 档位 | wrk 参数 | A baseline req/s | B ZC-recv req/s | Δ |
27+
|---|---|---|---|---|
28+
| T1 | -t2 -c10 -d5s | 22,363 | 22,115 | −1.1%(噪声)|
29+
| **T2** | -t4 -c100 -d30s | 31,056 / 32,136 / 30,066(avg **31.1k**| 39,046(离群) / 32,219 / 31,987(avg **32.1k**,去离群)| **持平(≤+3%,噪声内)**|
30+
| T3 | -t8 -c500 -d30s | 28,615 | 28,317 | −1.0%(饱和)|
4631

47-
## 5. 就绪的复测 harness(数据面恢复后直接执行)
48-
```bash
49-
# 1) server B(ZC-recv,单核 lcore4)
50-
cd /data/workspace/f-stack/example
51-
nohup ./helloworld_zc_recv --conf /data/workspace/f-stack/config.ini --proc-type=primary >/tmp/zc_recv.log 2>&1 & disown
32+
> 注:B 首次 T2=39,046 经复测确认为 warmup/噪声离群值;3 次复测后 A≈B。
5233
53-
# 2) smoke(client)
54-
ssh f-stack-client "curl -s -o /dev/null -w 'http=%{http_code} t=%{time_total}\n' http://9.134.214.176/"
34+
延迟(T2):A avg 3.71ms / B avg 4.12ms;T3:A 17.87ms / B 18.06ms —— 同量级。
35+
server 单核 CPU(T2):72–84%,**未饱和** → 该负载瓶颈在 client/网络,非 server 接收拷贝。
5536

56-
# 3) 单核性能 T2/T3(client;如无 wrk 用 ab/curl 循环)
57-
ssh f-stack-client "wrk -t4 -c100 -d30s --latency http://9.134.214.176/"
58-
ssh f-stack-client "wrk -t8 -c500 -d30s --latency http://9.134.214.176/"
37+
## 4. 性能结论(诚实)
38+
- **此小包 echo 负载(256B 请求 / 438B 应答)下,ZC-recv 与 ff_read 吞吐/延迟持平(噪声内)**
39+
- 原因:小请求的 `soreceive→uiomove` 拷贝开销相对 TCP 处理 + syscall + 调度可忽略;且 f-stack 用 UIO_SYSSPACE,uiomove 本就是同地址空间 memcpy(已很廉价)。
40+
- ZC-recv 的收益预期在 **大块数据收取 / 代理转发(收到即转发免拷贝)** 场景(spec 15/17 §适用场景),需用大 payload 工作负载(如大文件下载、大 body POST)专门测量;本轮 echo 负载无法体现。
41+
- **历史极限参考**(同机同 config 单核 lcore4,helloworld kqueue,docs/freebsd_13_to_15 13.0-baseline):T2 220,691 / T3 239,555 req/s。本轮 main_zc(echo + 模拟 1 万次空循环 + ff_zc_send)req/s 远低于该 kqueue helloworld,因应用模型与负载不同(main_zc 每请求含人为 busy-loop 与 ZC 应答构造),不可直接横比。
5942

60-
# 4) 停服务 + 清理(必须走脚本)
61-
/data/workspace/kill_process.sh <pid>
62-
ls /dev/hugepages/rtemap_* | xargs /data/workspace/rm_tmp_file.sh
63-
64-
# 5) server A(baseline)重复 1-4,A/B 对比 req/s 与 p99
65-
```
66-
67-
## 6. M2 验收对照(spec 17)
43+
## 5. M2 验收对照(spec 17)
6844
| AC | 状态 | 说明 |
6945
|---|---|---|
70-
| 构建/启动 || lib+server 编译通过(-Werror),DPDK 注册成功 |
71-
| AC-F1 ff_zc_recv 全链路功能 | ⏸ 阻断 | 数据面 VPC 投递失效(差分证明非代码问题)|
72-
| AC-M1/M2 内存安全(mempool/valgrind)|| 需数据面恢复后跑流量验证 |
73-
| AC-P1 单核性能 A/B || harness 就绪,待数据面恢复采集 |
74-
| 代码正确性(编译/符号/启动/差分)|| 与 baseline 行为一致,未引入回归 |
75-
76-
## 7. 合规
77-
- ✅ 停进程走 kill_process.sh;清 rtemap/临时文件走 rm_tmp_file.sh;无直接 rm/kill/chmod
78-
- ✅ 未臆造任何性能/功能数据;http=000 如实记录
79-
- ✅ client 命令经 ssh 下发
46+
| 构建/启动 || clean 重编译后 -Werror 通过;DPDK 注册 |
47+
| AC-F1 ff_zc_recv 全链路功能 || curl http=200 size=438(5/5)|
48+
| AC-F4 普通 recv 零回归 || A(ff_read) 同样 http=200 正常 |
49+
| AC-P1 单核性能 A/B | ✅(已采集)| 小包 echo 下持平;大 payload 收益待专测 |
50+
| AC-M1/M2 内存安全 || T1/T2/T3 共 ~400 万请求无崩溃;valgrind/mempool 精确计数待补(DPDK 运行态 valgrind 成本高)|
51+
52+
## 6. 合规
53+
- ✅ 停进程走 kill_process.sh;清 rtemap/stale .o 走 rm_tmp_file.sh;**修复了此前一次误用 `rm -rf` 的违规**(已改用脚本)。
54+
- ✅ 未臆造数据;http=000→根因→修复→http=200 全程实测;性能离群值如实标注并复测校正。
55+
- ✅ client wrk 命令经 ssh 下发(复用已有 /tmp/wrk/wrk,未重复安装)。
56+
57+
## 7. 后续
58+
- AC-M(内存安全精确化):大 payload 长跑 + rte_mempool_in_use_count 前后对比。
59+
- 大 payload 性能专测以体现 ZC-recv 设计收益。

0 commit comments

Comments
 (0)