商用RoCEv2网卡基于目前以太网络设施部署,需要 PFC 来实现无损网络结构,基于优先级的流控制(PFC)引起了网络可伸缩性问题。 PFC 带来了诸如离线阻塞、拥塞扩散、偶尔死锁和大规模集群中的 PFC 风暴等问题 。因此,数据中心运营商倾向于将 PFC 配置限制在较小的网络范围内(例如,中等规模的集群)。
RoCEv2网卡通过特殊处理明显改善网络状况,方案有两种:1)引入额外内存开销的方案;2)扩展IB协议的选择性重传方案。
通过引入额外内存开销的方案
核心思想是:通过引入额外内存消耗的解决乱序问题、降低网络中负载以及选择性重传read response丢失的报文请求,可以一定程度上提高了网络伸缩性,但还需PFC协助尽可能减少丢包。
响应端
思路很简单,假定逻辑有非常大的缓存空间,将请求端所有包接收下来,对于乱序包则重排处理,对于丢包则等对端超时重传或主动NAK。
①一个数据包到达响应端,包的PSN与预期ePSN一致,则表示是正常顺序包,将由逻辑正常处理:对于send,先从RQ中取RWQE解析地址,再将数据写到host ddr;对于write/read,检查合法性无误则写入host ddr。
②数据包的PSN与预期ePSN不一致,则认为是乱序包,乱序包整包送入到QP的重排缓存区,进入OOO模式(乱序重排模式),由ePSN - PSN 计算出offset置位bitmap。
③当bitmap 0bit非0时,将通过data ptr指针找到乱序重排缓冲区0bit对应的整包,取到OOO模块解析处理,对于send,先从RQ中取RWQE解析地址,再将数据写到host ddr;对于write/read,检查合法性无误则写入host ddr。最后bitmap右移1bit,data ptr指向下一个packet。
④当bitmap全0时,退出OOO模式。
Reorder Buffer需要内存比较大,一般放在HOST DDR上,也就是说,对于乱序包,先送到HOST DDR重排缓存空间等待排队就绪,然后RNIC再从HOST DDR中读下来解析处理,最后送到HOST DDR真正的用户内存空间。相比乱序直接NAK让请求端重传的做法,这种方案只牺牲响应端部分PCIe带宽便可减小网络上压力,一定程度上提高了网络伸缩性。该方案QPC需要存放乱序维护结构,增加了sram消耗,此外,乱序重排BUF也需要占用host较大内存。
上述只能解决出现乱序报文问题,对于丢包则无太大益处。对于丢包,可直接等待请求端超时重传(时间较长),也可由响应端主动回复NAK触发重传。可选方案,以一定算法监测bitmap中空洞,当空洞较长时间未填补或后续bit位连续多个置位后,认为该空洞对应报文已丢失,主动触发NAK重传。
请求端
send & write & read
对于超时请求,正常重发;对于NAK请求,正常重发。
read response
请求端收到的read response可能乱序或丢包。
①收到read response PSN与预期ePSN一致,则认为是顺序包,将由正常传输逻辑处理送到HOST DDR。
②收到read response PSN与预期ePSN不一致,则认为发生了乱序或丢包,将进入SR(选择性重传)模式。接收的数据将正常送入用户HOST DDR中,同时由ePSN - PSN 计算出offset置位bitmap。
③当bitmap 0bit非0时,将整个bitmap右移,直到0bit为0。以一定算法监测bitmap中空洞,当空洞较长时间未填补或后续bit位连续多个置位后,认为该空洞对应报文已丢失,主动重传部分read请求。例如,请求端发起一个长度为7个pmtu的read请求报文,响应端接收请求回复7个pmtu报文,但是网络中丢失了0、4、6号报文,则请求端可以分别发送1个pmtu的read报文请求0、4、6号位置数据,从而选择性重传部分read请求,以便减少网络上负载,一定程度上提高了网络伸缩性。
由于是请求端主动发起的请求,所以只需要给活跃的QP的QPC中分配read response维护结构即可,对sram消耗增加不大。
扩展IB协议的选择性重传方案
核心思想:通过扩展IB协议,指示响应端准确的将任意包放入用户内存中,解决因乱序、丢包导致响应端无法立即处理报文问题;通过扩展IB协议,指示请求端需要重传哪些请求,精确重传丢失报文,去掉无效报文,保障了网络伸缩性。
当乱序或丢包发生,响应端接收报文无法正确处理,要么乱序重排,要么NAK重传,将极大影响吞吐率。通过扩展IB协议,在请求报文中额外附加信息告诉响应端怎么处理报文,实现报文就地重排上送用户内存中。
注意:发送端与请求端是在不同场景下不同称呼而已,同理接收端与响应端也是。
send
对于send报文,接收端接收到预期之外PSN报文将不知如何处理,如下图。
发送端发送了3个send报文,报文在网络中丢失了PSN0,接收端预期接收PSN0的报文,但却先接收到了PSN1的报文,此时接收端无法立即处理PSN1报文,因为接收端不知道PSN0的报文类型,不能准确使用RWQE(QP RQ中资源),只能将PSN1报文丢弃或放入缓存中等待乱序重排。
通过扩展IB协议,发送端在BTH之后附加SSN、PSN_OFFSET、RWQEN,那么接收端就可以准确处理任何send报文。
- 发送方发送了4个包给对面;
- 数据包在网络中丢失了3个;
- 接收端只接受到PSN4的数据包;
- 接收端根据包中扩展内容可以知道这个包需要使用RWQE1且数据偏移一个PMTU,接收端将数据放入用户内存;
- 接收端将乱序报文PSN与预期ePSN送给软件,由软件跟踪丢包信息。
可选的丢包恢复措施:
- 接收端软件择机触发硬件回复NAK(PSN 0)并附加指示信息指示对端重传哪些报文,例如丢包的bitmap信息0x0003,指示发送端精确重传丢失报文。
- 接收端等待ACK超时主动重传所有请求。
write
对于write报文,响应端接收到预期之外PSN报文将不知如何处,如下图。
请求端发送了3个报文,报文在网络中丢失了PSN0,接收端预期接收PSN0的报文,但却先接收到了PSN1的报文,此时接收端无法立即处理PSN1报文,因为write last中没有addr、key、len等信息。
通过扩展IB协议,请求端在BTH之后附加每个write需要写的目的addr、key、len、PSN_OFFSET,那么接收端就可以准确处理任何write报文。
- 请求端发送了4个包给对面;
- 数据包在网络中丢失了3个;
- 响应端只接受到PSN4的数据包;
- 响应端根据包中扩展内容查询MTT表项将数据写入用户内存;
- 响应端将乱序报文PSN与预期ePSN送给软件,由软件跟踪丢包信息。
可选的丢包恢复措施:
- 接收端软件择机触发硬件回复NAK(PSN 0)并附加指示信息指示对端重传哪些报文,例如丢包的bitmap信息0x0003,指示发送端精确重传丢失报文。
- 接收端等待ACK超时主动重传所有请求。
read
通过扩展IB协议,请求端在请求报文中添加本端数据存放的laddr、lkey、len等元数据信息,响应端回复read response中附加元数据信息返回给请求端。
对于read请求报文丢失,由请求端超时重发或响应端主动NAK请求端重发均可。
对于read response报文,由于response中携带有本地的laddr、lkey、llen、PSN_OFFSET等信息,可以任意接受乱序报文并准确将数据写入本端用户内存,此外由软件维护乱序response bitmap,以便决定选择性重传更小粒度read请求,如下图所示。
- 请求端发送read请求(IB协议本身包含对端raddr、rkey、len,扩展包含本端数据存放的laddr、lkey);
- 响应端接收请求根据rkey查询MTT,再从raddr开始读取len数据;
- 响应端组装read response报文,并附加请求端送来的元数据(laddr、lkey)以及len和PSN OFFSET;
- read response在网络中丢失了PSN1报文;
- 请求端接收到PSN0报文,根据扩展信息查询MTT并写入数据到用户内存;
- 请求接收到PSN2报文,发现与预取ePSN不一致,则进入丢包恢复流程,将报文元数据送给软件,但数据将写入用户内存中;
- 请求端软件以一定算法扫描bitmap空洞,择机选择性重传更小粒度read请求。
read response中携带PSN OFFSET是为了在丢包时好让软件跟踪bitmap。
注意:正常情况下,请求端本端会维护read未完成报文元数据PSN、 MSN、 PSN_OFFSET 之间的映射,所以响应端任意回复(乱序)报文也能正确放入本端用户内存中。那么为什么还要在read请求报文中添加本端数据存放的laddr、lkey、len等元数据信息呢?下面文章中揭晓。