ISSUE-031 后续重构:RC Link Spec 真值笔记
目的:回答"硬件 spec 对 segment → TYPE1 slot 喂入到底是 polling 还是 event-driven",作为综合阶段(task #7)的 input。
来源:C:/Users/DELL/Documents/项目/PAXI/最新/RCLINK_AFH_SPEC_v2.4.md + 2262 c2c/2262 CDMA spec v2.2.md。
关键 spec 引文
RCLINK §5.10 TYPE1 报文发送仲裁 (P36L10 - P37L27)
P36L11:
上游下发的 TYPE1 数据报文会顺序进入一个队列中,队列中的 slot 有四种状态,分别是 WAIT_GRANT, WAIT_CRD, WAIT_ACK 和 EMPTY。
P37L3-L13 状态机:
| 转换 | 触发事件 |
|---|---|
| EMPTY → WAIT_GRANT | 有上游下发新的数据报文写入队列时 |
| WAIT_GRANT → WAIT_ACK | 对应 slot 报文被仲裁发出时 |
| WAIT_ACK → WAIT_GRANT | 有重传请求时 |
| WAIT_ACK → EMPTY | slot 中的报文被 ack 时 |
| WAIT_GRANT → WAIT_CRD | 报文被控速模块阻塞时 |
| WAIT_CRD → WAIT_GRANT | 控速模块阻塞撤销时 |
P37L24-L27 bank 轮转:
实现方法:每次发出一个报文后,记录发出报文 qpid_msb,检查目前队列中各个 slot 中报文的 qpid[1:0],与 qpid_msb 相同的 slot 对应的 mask 置 1,mask 置 1 的 slot 不参与下一次的发送仲裁;当队列中仅存在其中一个 bank 的报文时,slot 的 mask 不生效。
CBFC 流控 (P31)
P31L7:支持以 VC 为粒度的 CBFC 参数配置(pktovhd / credit_size / credit_limit)
P32L14-L23:反压信号由 RCLINK 的 RX 端 Buffer 水限和上游客户逻辑产生的 FLOW_STOP 信号触发。
CDMA 端注入(2262 CDMA spec v2.2)
没有"earliest_ready"或"分包调度时刻"概念。 spec 描述的是:
- CDMA 单元有 SerDes 物理接口,wire-rate 串行化数据
- 17 个独立线程,每线程独立 cmd queue / send queue / receive queue
- 数据连续推到下游 RC Link,受物理 wire-rate 限制
硬件真值结论(Q1 答案)
硬件 layer 1(物理):连续 wire-rate 推送,无离散调度时刻
- CDMA 输出端是 SerDes,数据连续流出受物理带宽限制
- 没有"polling""唤醒"概念,只有"已在 wire 上""未在 wire 上"两种物理状态
硬件 layer 2(队列接口):push-driven,无 polling
- 上游(CDMA)有数据 → 写入 TYPE1 slot 队列 → slot 状态 EMPTY → WAIT_GRANT
- 反压通过物理信号(FLOW_STOP / CBFC credit)实现,不靠 polling
硬件 layer 3(仲裁):event-driven,绑定物理事件
- WAIT_GRANT slot 存在 → 仲裁器选一发出 → WAIT_ACK
- "每次发出一个报文后" → 推进 bank mask(spec §5.10 P37L24 原文)→ 这是 spec 的硬性要求
- 仲裁周期严格绑定"发送完成"事件,不绑定"仲裁尝试次数"
G5 当前实现的偏离
| Spec 行为 | G5 当前 | 是否违背 |
|---|---|---|
| 上游 push → slot WAIT_GRANT | polling-driven(RcLinkWake 反复唤醒 feed_rc_link 扫 segment_queue 把 earliest_ready ≤ now 的 segment 喂入) | 是(spec 没有 polling) |
| 仲裁 event-driven(发完一帧立即下一轮) | 大体正确 — on_tx_done → try_arbitrate(已 event-driven) | 否 |
| bank/RR 推进"每次发出一个报文后" | 已修(WRR 空扫不推进,ISSUE-031 第 2 修复) | 修复后符合 |
| CBFC credit / 重传 / FLOW_STOP 反压 | 已通过 credit_block / NAK 实现,但 21 拓扑 dormant | 不评 |
核心偏离:G5 用 RcLinkWake 这个仿真器伪事件去模拟硬件 layer 2 的"上游 push",造成 polling 假象。spec 没说要 polling — spec 是说"上游下发 → 写入队列",这是一次性 push 事件。
CDMA 端的"earliest_ready"是什么?
仿真器引入的概念,用来离散化硬件 wire-rate 串行化的连续过程。
| 仿真层 | 含义 |
|---|---|
| 硬件物理 | 数据 t0 开始连续推送,经 wire 后 t0 + bytes/wire_rate 到达 |
| G5 离散化 | 按 MPS 拆 segment,每 segment 在 earliest_ready_ns = submit + idx × MPS/bandwidth 时刻"物理就绪" |
离散化的 spec-correct 实现:每 segment 在 earliest_ready 时刻主动 schedule 一个 SegmentReady 事件,handler 直接喂入下游(mimic 硬件上游 push)。
G5 当前实现:用 RcLinkWake polling 探测 earliest_ready ≤ now。这是仿真器自造的伪 polling 模式,硬件那一侧本来就是 push。
哪些机制必须改 / 可以保留(初步,等业界经验综合)
必须改(违背 spec)
- segment → vc_pending 喂入:RcLinkWake polling → SegmentReady event push
- earliest_ready 调度:create_segments 时 per-segment schedule(或队头变就绪时 schedule)
- ACK 释放后的 pull:on_ack 已经 push-driven 调 try_arbitrate,但还有 free_slot 释放后 pending_queue → segment_queue → vc_pending 这条链需要重新组织
可以保留(spec-correct)
on_tx_done → try_arbitrate链路:已是 event-driven 的"发完一帧立即下一轮",符合 spec §5.10 P37L24- WRR / bank mask 推进:已修(ISSUE-031 第 2 修复),符合"每次发出一个报文后"语义
- CBFC credit 返还 → 重新仲裁:已是 push-driven
- NAK / 重传:已是 event-driven
单独处理(暂缓)
- DCQCN pacing → rate-block 精确 wake(高-2):21 拓扑 dormant,但 incast 场景下需要;待重构主链完成后单独修
- C2C link_load 滑动窗口(高-1):只影响 adaptive 路由(UGAL/flowlet),packet_spray/flowlet_ar 已剔除(ISSUE-030),只剩 UGAL 受影响
- ECN RED PRNG(高-3):21 拓扑 ECN 未触发,dormant
- ACK MERGE / SwitchTick / capacity 快照(中-1/2/3):重构主链后再独立评估
待补:CDMA 端 wire-rate 串行化的 spec 描述
CDMA spec v2.2 / v2.3 没找到"分包 + earliest_ready"的硬件描述,只有"连续 SerDes 推送"。需要进一步确认 G5 的 segment 离散化模型本身是否符合 spec,但这不是 ISSUE-031 的范围,留后续。