本文主要介绍IB协议中与PSN相关的部分。
1 PSN Range
每个Packet都有一个标识符,即为PSN,它是24bit的字段,PSN空间的大小为16M()。
LRH | GRH | BTH | ETH | Data Payload | ICRC | VCRC |
请求方维护Start PSN、Current PSN以及Next PSN,而响应方应维护Expected PSN。
2 Requester QP’s SQ Logic PSN Generation and Verification
2.1 Start PSN Assignment
创建QP时,必须设置的值之一是SQ Logic的Start PSN,它将被插入到SQ Logic生成的第一个请求包中,可以是000000h~FFFFFFh范围内的任意值。
2.1.1 Select a Start PSN Value That Precludes Stale Packets
协议规定Start PSN选择的值应最大限度地减少以前连接的Packet落在有效PSN窗口内的机会。Packet指RQ Logic接收到的请求包,或是SQ Logic接收到的响应早些时候发出请求的响应包。“有效的PSN窗口”指PSN的范围,它的大小不超过8M(),由已确认的PSN范围(重复响应区域)与未确认的区域组成。
创建一个QP时,verb层为它分配一个24位的QPN,有可能较早使用过的QP与刚刚创建并处于设置过程中的新QPN分配了相同的QPN。另外,连接管理的软件可以使用verb调用的Modify QP来重置一直在主动互发消息的本地QP与远端QP。
早期QP的SQ Logic已被分配Start PSN,并且在生命周期内传输了许多请求包,每个请求包包含递增的PSN。随后,这些QP可能被删除(销毁)或重置,然后被重新设置,而它们仍有一些请求包或者还在响应,这些孤立的请求包或Ack包被称为“stale”包。
当一个新QP与一个与之通信的远端QP被创建并使用时,如果其SQ Logic被分配的Start PSN在“stale”包的PSN范围内,那么“stale”包可能被误认为是有效请求或者对新QP发出的请求的有效响应。因此,协议敦促software为新QP的SQ Logic分配一个Start PSN,可以使QP的RQ Logic或SQ Logic可能接收到的“stale”包落在无效区域内(Start PSN之前,或是最近发布的请求包的PSN之后)。
2.1.2 No Protection From Stale Packets
如果Connection Management Software要破坏两个QP之间的连接,然后过早地选择重用两个QP(在“stale”包经过足够长的时间被丢弃在fabric之前),“stale”包可能会达到QP的SQ Logic或RQ Logic,它们将被视为有效的数据包,导致致命的问题。
Connection Management Software有责任在足够长的时间内避免重用QP,以确保不会有过时的数据包达到SQ Logic或RQ Logic,协议将这段时间称为“Time Wait”。
2.2 Requester Packet PSN Generation
发送请求包时,SQ Logic根据以下规则为每个请求包分配一个PSN:
- 第一个请求包的PSN=分配给SQ Logic的Start PSN。
- 随后发出的请求包:①先前发出的不是RDMA Read请求包,Next PSN=Current PSN+1;②先前发出的是RDMA Read请求包,Next PSN=Current PSN(RDMA READ请求包的PSN)+n(期望的响应报文数)。
请求方知道所请求的RDMA READ数据的总长度,也知道PMTU,并且每个响应包(除Last或Only Packet)应填充到完整的PMTU大小,因此请求方可得知期望的响应报文数。
2.3 Ack'd(aka Duplicate) Region
随SQ Logic发出请求包并接收每个请求包的响应,应答区域的上端向上增长。
2.4 Maximum Number of Outstanding Requests
RC QP的SQ Logic在发出下一个请求包之前不会等待相应的响应包被返回,它将持续发送请求包,最终将开始接收相应响应包流。SQ Logic允许在开始接收响应包之前传输的未确认请求包(所有类型的Send、RDMA Write、RDMA Read和Atomic请求)的最大数量为8M()。基于以下特征的最坏特征:
- 请求方QP的SQ Logic发起RDMA Write或Send操作,将2GB的message写入CA的本地内存。
- 在源端口和目的端口之间传输的数据包的Payload大小不能大于PMTU。
- 假设PMTU为256-byte,2GB message传输包含8388608个请求包(用于Send或RDMA Write),或8388608个RDMA Read响应包。
- 请求方QP的SQ Logic开始传输请求包。
- 如果请求方已经传输了与该消息相关的8388608个请求包,并未收到该message的任何Ack,那么应停止继续发送请求包在开始接收Ack之前。
2.5 Ack Verification
SQ Logic接收每个响应包时,检查以确保它在unAck区域内,如果是这样,SQ Logic将相应地推进Ack区域的上端。
2.6 Detecting Duplicate Acks
某些情况下,SQ Logic将重新传输请求包,因此远端QP的RQ Logic对第一个请求包返回响应时,可能会收到重传的请求包。SQ Logic收到该请求返回的第一个响应包时,将推进确认区域的上端,因此重传返回的响应包的PSN将落在重复响应区域,SQ Logic将静默丢弃该响应包。
2.6.1 Worst-Case Duplicate Range Size
假设请求方已传输了2GB的message,并收到了除最后一个Packet的所有message的响应。此时,重复区域的大小为8388607个PSN。若因为等待返回最后一个Packet的响应超时,那么将回退到该请求包并重传。
协议中指出请求方可以倒回故障点(此情况仅备份一个数据包),也可以将SQ回退到该message的第一个请求包,重新开始。如本例选择这么做将重发8388607个落在重复区域的请求包,响应方QP的RQ Logic会返回一个Ack,但不会重写内地内存中的消息数据。
由于上述情况可能发生,请求方QP的SQ Logic需要始终记住它所传输的最后多达8388608个请求包的PSN,若应在重复区域返回Ack,将视其为重复请求。
2.6.2 Sometimes Duplicate Is Ack Used to Deliver Credits
远端QP的RQ Logic可能会故意发出一个与它返回的最后一个响应包的PSN相同的重复响应包,以便向SQ Logic提供端到端的流控积分(End-to-End flow control)。
2.7 Detecting Ghost Acks
PSN在Invalid范围内的“ghost” Ack可能会被接收,这种情况可能发生返回响应后QP被销毁,而返回的响应包一直存在在fabric中,建立新连接后该QP的SQ Logic又接收到该响应包。该响应包的PSN可能属于以下范围之一:
- 重复响应区域。SQ Logic被要求静默丢弃该响应包,但若该响应包携带credits,在丢弃前应从数据包中提取credits与MSN。
- 无效区域。会被静默丢弃,除非该响应包提供了初始credits(详见主动应答包)。
- 有效范围的未应答区域。这种情况下,“ghost”包可能看起来是一个有效的响应包(如果它的OpCode也是预期的OpCode),会如“stale”包一样,导致致命问题。
2.8 SQ Logic PSN Rollover
在一个QP的生命周期中,它的SQ Logic可能生成很多请求包,甚至可能到达整个PSN范围的上限,并发出PSN为FFFFFFh的请求包,那么它生成的下一个请求包中的PSN将滚动到零并继续从那里向上增长。
3 Responder QP's RQ Logic Request PSN Verification
3.1 Start ePSN Assignment
创建RC或UC QP时,分配给RQ Logic的ePSN(Expected PSN)必须与分配给远端QP的SQ Logic的Start PSN相同。
3.2 ePSN Verification and Update
当从远端QP SQ Logic接收到请求包时,RQ Logic将请求包的PSN与当前ePSN进行比较。若相等,则该请求包具有正确的PSN,它将由RQ Logic进行处理,RQ Logic更新ePSN如下:
- 刚收到并验证的请求包不是RDMA Read请求包,ePSN+1。
- 刚收到并验证的请求包是RDMA Read请求包,ePSN+请求的RDMA Read响应报文数。
注,只有当QP处于Initialized状态时,用户才能设置初始ePSN。当QP处在其他状态,用户设置PSN的尝试可能被传输层忽略。
3.3 Duplicate Requests
3.3.1 Duplicate Request Detection
远端QP的SQ Logic可能会重传数据包,RQ Logic可能最终接收请求包的两个副本。RQ Logic在收到第一个请求包后,验证自己的PSN是否与ePSN匹配,并更新ePSN通过向上调整应答请求区域。如果再次收到该请求包,它的PSN将落在重复请求区域,RQ Logic将其视为重复请求,重复区域最大有8388609个PSN。
3.3.2 RQ Logic‘s Handling of a Duplicate Request
响应方QP的RQ Logic在执行重复请求包时不会增加MSN。
3.3.2.1 Handling a Duplicate Request Packet
- 如果是重复的Send或RDMA Write请求:
——RQ Logic调度需要传输的Ack包,但Ack包的PSN不是原始请求中包含的,而是RQ Logic最近完成的请求的PSN。
——RQ Logic不再对本地内存执行写操作。
——RQ Logic不会更改其ePSN。(即使生成对重复请求的响应时检测到错误)
——RQ Logic响应重复请求后,继续等待带有ePSN的请求包。
——如RQ Logic在对重复的Send或RDMA Write请求生成响应时检测到错误,会静默丢弃重复的请求。(避免与任何可能得未完成的Nak混淆)
- 如果是重复的RDMA Read请求:
——RQ Logic从它的本地内存重新执行操作。
——它将请求的读数据以一系列一个或多个RDMA Read响应包的形式返回。
——第一个响应包使用原始请求包的PSN,随后的每个响应包PSN+1。
——RQ Logic不会更改其ePSN。(即使生成对重复请求的响应时检测到错误)
——RQ Logic响应重复请求后,继续等待带有ePSN的请求报文。
——重复的RDMA Read请求包中的PSN必须在原始请求返回的响应包的PSN范围内。
——所请求的读数据量必须是原始请求中所请求数据的一个子集。
——返回重复RDMA Read请求包的读数据后,RQ Logic可以使用最近完成的请求的PSN来响应随后收到的任何Send或RDMA Write请求包,这个更高的PSN充当了所有先前发出的请求数据包的合并Ack。
- 如果是Atomic Operation请求
——RQ Logic不能重新执行Atomic RMW operation。
——它使用原始执行的Atomic operation保存的结果返回一个Atomic响应包。
——RQ Logic不会更改其ePSN。(即使生成对重复请求的响应时检测到错误)
——RQ Logic响应重复请求后,继续等待带有ePSN的请求报文。
——如果重复的Atomic operation请求包的PSN与最近执行的任何Atomic operation的PSN不匹配,则请求包无效并被静默丢弃。这种情况不应该发生,因为请求方QP的SQ Logic发送的Atomic请求不应该超过响应方QP的RQ Logic能够处理的数量。
——如果CA中的本地错误阻止RQ Logic重新生成原始Atomic operation的读取数据,RQ Logic必须静默地丢弃重复的Atomic operation请求数据包。
3.3.2.2 Rules For Handling Multiple Duplicate Request Packets
响应方QP的RQ Logic必须按PSN顺序响应所有重复请求。
- 1如果在等待下一个预期请求包(PSN = ePSN)时接收到另一个重复的请求包,则处理它与之前的请求包完全相同。
- RQ Logic很可能会收到多个重复的请求数据包,这些请求数据包可能不是按顺序的PSN顺序(相对于收到的第一个重复请求数据包)。RQ Logic在传输对重复请求的响应时使用与用于预期的新请求数据包的响应相同的排序规则。重复的RDMA Read请求或Atomic请求报文必须用RDMA Read响应报文或Atomic响应报文来响应后,才能返回随后收到的重复Send或RDMA Write请求的响应包。
- 如果在重新执行重复的RDMA Read请求时,返回第一个响应包之前RQ Logic检测到错误,RQ Logic就会静默地丢弃重复的请求。
- 如果在重新执行重复的RDMA Read请求时,RQ Logic在返回一个或多个RDMA Read响应包后检测到错误,则终止RDMA Read响应操作(即不再返回响应包)。
- 如果重复RDMA Read请求的起始PSN和长度不是原始请求的子集,则该请求无效,RQ Logic可能会静默地丢弃它。
- 如果在响应新的或重复的RDMA Read请求时,另一个具有较早PSN的重复RDMA Read请求被接收,RQ Logic将停止响应原始请求,并开始响应新接收的具有较早PSN的重复请求。
- 如果RQ Logic的RDMA Read响应被另一个重复的RDMA Read请求中断,则RQ Logic不需要继续发送第一次读的响应报文。请求方QP有责任重新发送任何未应答的请求。
3.4 Invalid Request Detection
如果RQ Logic收到的请求包的PSN既不是ePSN,也不属于重复请求区域,则认为fabric中丢失了一个或多个请求包。如何处理这取决于QP的类型:
- RC或RD。RQ Logic采取以下动作:
——请求包不被处理。
——在无序请求之前收到的任何请求包都将在发出Nak之前被处理、完成和响应。
——将Nak-PSN Sequence Error发送到远端QP的SQ Logic。
——响应方不更新ePSN。
然后RQ Logic继续等待一个有效的入站请求数据包,该请求包的PSN与其ePSN相等,或者在其重复请求区域内。如果在等待过程中,RQ Logic接收到任何带有无效PSN的请求包,这些数据包将被静默丢弃,并且不返回Nak。
- UC。如果RQ Logic判断接收到的请求报文的PSN与自身的ePSN不一致,则进行如下处理:
——如果刚刚接收到的数据包具有“First”或“Only” OpCode,则它是新消息的First(或Only)数据包。该请求包被接受为新消息的Firs(或Only)包,RQ Logic将其ePSN设置为该包的PSN。
——如果刚刚收到的数据包没有“First”或“Only” OpCode,RQ Logic将丢弃该数据包以及随后收到的所有请求包,直到它收到具有“First”或“Only” OpCode的数据包。该请求包被接受为新消息的第First(或Only)包,RQ Logic将其ePSN设置为该包的PSN。
- UD。UD QP的RQ Logic通常不进行PSN检查(因为UD消息完全包含在单个数据包中)。
3.5 RQ Logic PSN Rollover
ePSN有可能最终到达-1的PSN上限(一个FFFFFFh的PSN),当它的ePSN增长到FFFFFFh,然后必须增加,RQ Logic的ePSN将滚到零,并继续从那里向上增长。
4 Retry and PSN
请求方发布的Retried Request Packet的PSN逻辑上小于迄今为止传输的最大PSN。
请求方维护这三个指针(Point of Maximum Advance、PSN of the oldest unacknowledged request和PSN of the Retried Request),以正确处理Expected Response。
在Retry Request的过程中,请求方应该保持一种标记最远PSN前进点的方法(high water mark)标记①。因为响应可能将Retried Request解释为重复请求,响应方有义务返回标记其最远前进点的PSN,所以响应方可能会用逻辑上比Retried Request PSN更大的PSN响应Retried Request。
【示例场景】
- Requester发出SEND Request Packet(PSN=1);
- 发出下一个Request Packet(PSN=2);
- Responder返回一个Response Packet(PSN=2),合并响应(1&2);
- 合并响应到达前,Timer超时,Requester重传请求(PSN=1)。
- Responder收到Retried Request将其视为重复请求,规则规定Responder有义务返回其最远前进点的PSN。
- 故Retried Request的Response PSN大于Retried Request的PSN。