0. 前言
我们知道,PCIe 或 CXL 等协议自带流控(Flow Control)机制,UCIe 在协议层采用 PCIe 或 CXL 协议时,PCIe 或 CXL 流控信息已经蕴含在了 Flit DLLP 中。单就 UCIe 协议而言,其也有流控机制,且 Mainband 和 Sideband 两方独立做流控。
关于 Mainband 流控,UCIe Spec 中提到的不多,仅在第一章介绍 UCIe Retimer 时提到了 UCIe Die 给 UCIe Retimer 发送数据时要做基于信用量(Credit)的流控,反过来 UCIe Retimer 给 UCIe Die 发送数据时在 Adapter 层面无需流控,UCIe Retimer 与 Retimer 之间可选择性地做流控。此处我们不做过多介绍。
关于 Sideband 流控,是 UCIe Die/Retimer 必须做的,UCIe Spec 中也在 Sideband 章节中对 Sideband 流控进行了小篇幅解释。读罢 Spec,我对 Sideband 流控仍存有较多疑问,这里我写一下个人见解,各位对 Sideband 流控解读有不同见解的,我们可以做进一步讨论。
1. Sideband Flow Control
前文 UCIe Sideband 介绍 中提到 UCIe FDI、RDI 接口及 UCIe Link 上均可以传输 Sideband 包,相对应地,Sideband 数据包在 FDI、RDI 及 UCIe Link 接口上进行传输时独立进行基于 Credit 的流控。
PCIe 流控中,根据 VC 、事务类型(P/NP/CPL)及 Header/Data 分了多种 Credit,但在 UCIe Sideband 流控中,所有类型的 Sideband Packet 共享同一种 Credit。虽然有些 Sideband Packet 是不带 Data 的,携带 Data 的 Packet 中 Data 也有 32bit 及 64bit 之分,但在 Sideband 流控中,不论是否携带 Data、不论 Data 位宽多少(目前只有 32、64bit 两种啊),同一个 Sideband Header 消耗的就是一笔 Credit,即 每一笔 Credit 对应 64bit Header w/wo Data。
谁给谁发 Credit 的问题
在 PCIe 协议中,Flow Control Credit 是 Flow Control Buffer 的存储单元,由 Rx 通报给 Tx。继续这个逻辑,UCIe Credit 是 Sideband Packet Rx 通报给 Sideband Tx。
1.1 FDI/RDI Sideband Flow Control
PCIe Flow Control 是一种点到点(P2P)的流控,通过在 PCIe Link 两端数据链路层间发送 DLLP 实现流控。对于 UCIe Local Die Sideband 而言,其 Flow Control 更为精细,是一种层到层(L2L)的流控,每一个 FDI、RDI 的收发环路独立进行流控,共有 4 个 Credit Loop:
协议层 Tx -> Adapter Rx;
Adapter Tx -> 协议层 Rx;
Adapter Tx -> PHY Rx;
PHY Tx -> Adapter Rx。
对于发送端,Tx 向 Rx 发送 寄存器访问请求或 Message 类型的 Sideband 包之前,必须先检查 Rx 是否还有 Credit 余量。对于接收端,其在处理完相关 Sideband Packet 之后,及时释放 Credit 出来。Completion 是不占用 Credit 的,发送 Completion 之前无需确认 Rx Credit 情况,Rx 收到 Completion 后应无条件立即执行。
1.1.1 流控初始化?
在 PCIe 流控中,数据链路层 Link Up 之前会发送 FC_Init 类型的 DLLP 进行流控初始化,但在 UCIe Spec 中,没看到 FC_Init ,只含糊提到 Rx Credit 数量跟设计时间参数有关,最大 Credit 数量 32。笔者理解,FDI、RDI 上的 Sideband 流控是一种 Local Die 内的流控,复杂程度远不及 PCIe 流控,Local Die 内层与层之间无需通报支持的最大 Credit。
1.1.2 Credit 更新 ?
在 PCIe 流控中,数据传输过程中数据链路层周期性发送 Update_FC DLLP 来更新 Credit,但在 UCIe FDI/RDI Sideband 流控中,显然没看到这种类似的 DLLP 或 Sideband Message。想必也不太可能通过 DLLP 更新 Credit——我 Sideband 的事,需要你 Mainband DLLP 来掺和?
比较接近的,UCIe FDI/RDI 接口上有流控相关的 lp_cfg_crd/pl_cfg_crd 信号,位宽 1bit。笔者认为,这里的 lp_cfg_crd 及 pl_cfg_crd 作用类似于 buffer_full,Rx 实时告知 Tx 自身的 Flow Control Buffer 状态。Tx 也无需关心具体的 Rx Credit 余量,只要没满,就能继续发。
注意
在寄存器访问请求及 Completion 类型的 Sideband Packet Header 中,有一个流控相关的字段 Cr,这里的 Cr 不是给 FDI/RDI 流控用的,是给端到端(E2E)流控用的。
RDI、FDI 接口的 pl_retimer_crd 和 lp_remiter_crd 跟 Sideband Credit 没关系,这是 Mainband 流控用的。
1.2 UCIe Link Sideband Flow Control
UCIe Link 上的流控是一种 E2E 的流控。FDI、RDI 接口上有 Sideband 流控专用的信号,UCIe Link 接口上没有了,那 UCIe Link 上的 Sideband 是如何完成流控的?目前看有以下两种选择:
Sideband Msg {NOP.Crd}。Spec 说这是一种显式的反馈 Credit 的方式,能够向链路对端释放具体数目的 Credit。
Sideband Packet Header 中的 Crd。上文提到了,这里的 Crd 仅用于 E2E 的 Sideband 流控(PCIe 是 P2P 流控)。这个 Crd 也不是所有 Sideband Packet 都有的,只有寄存器访问请求及 Completion 才有,Msg 及 MsgD 都没有。笔者理解,Crd 这 1bit 跟 FDI/RDI 接口上的 *_cfg_crd 作用是相同的。
1.2.1 死锁避免
UCIe Link Sideband 流控一大关键是 避免死锁。为了避免死锁,对于 Adapter Mailbox 发出的寄存器访问请求,支持的 Outstanding 数量最大为 4,在物理层及 Adapter 中一次至少应能容纳 4 个这种请求。如果 UCIe 实际能支持 N 个请求,其可以通过 {NOP.Crd} 向对端额外释放 (N-4) 个 Credit。
对于 Message 类型的 Sideband Packet,除了 Vendor 自定义的 Message,一方面所有 Msg/MsgD 都应一路下发且不能阻塞后来的 Sideband Packet,另一方面链路管理类的 Message 不能 Outstanding 发送,必须收到 Rsp 之后才能发送下一步,从而避免死锁。对于一些 Vendor 自定义的 Message,定义 Message 的同时也必须定义其 Outstanding 能力,在 Rx 留有足够的空间来接收这些 Message,以免阻塞住后续 Message。
2. 参考 & 友链
UCIe Spec r1.0, Chapter 6
UCIe Sideband 介绍
UCIe协议详解(Sideband)
PCIe扫盲——Flow Control基础(一)
PCIe扫盲——Flow Control基础(二)