首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >RDMA - IB规范卷1 - 传输层2(可靠服务)

RDMA - IB规范卷1 - 传输层2(可靠服务)

原创
作者头像
晓兵
修改2025-04-26 15:46:04
修改2025-04-26 15:46:04
6470
举报
文章被收录于专栏:DPUDPU

接上文: RDMA - IB规范卷1 - 传输层(概述-基本传输头-扩展头-功能-保序-包头校验), https://cloud.tencent.com/developer/article/2513460

术语

  • ghost: 幽灵请求
  • LSN: Limit Sequence Number (用于流控)
  • SSN: Send Sequence Number (用于流控)

9.7 可靠服务

简介

可靠服务保证消息从请求者到响应者最多一次、按顺序且无损坏地传递。可靠服务的关键要素包括:

用于检测损坏数据 (CRC) 的保护方案;

允许请求者确定消息已成功传递的确认机制;

用于检测丢失数据包并允许请求者将响应与请求关联的数据包编号机制;

以及用于检测丢失或丢失确认消息的计时器。

本节介绍确认和数据包序列编号机制。用于检测数据包损坏的 CRC 机制不在此处讨论。请注意,CRC 在较低的协议层进行检查,这可能导致数据包在传递到传输层之前被丢弃。这些丢弃的数据包最终可能会在传输层被检测为序列错误。

• 可靠服务的特征

• 在没有不可恢复的错误的情况下,消息最多一次、按顺序且无损坏地传递。

• 每条消息都以显式或隐式方式确认。

• 可靠服务的类型

• 可靠连接(RC)

• 可靠数据报(RD)

• 扩展可靠连接(XRC)

• 可靠性机制

• ACK / NAK 协议

• 数据包序列号 (PSN)

• 当响应方满足以下条件时,认为操作完成:

• 在 BTH 中接收到有效的“最后(Last)”或“唯一(Only)”操作码,

• 按照正确的 PSN 顺序接收到组成消息的所有数据包,

• 有效载荷已提交到本地故障区(local fault zone)(SENDS 或 RDMA WRITEs),

• 响应已提交到线路(wire)以进行 RDMA READ 或 ATOMIC 操作,

• 请求的最后一个数据包的确认数据包已提交到线路(包括 RDMA READ 响应的相应字段)

• 当请求方满足以下条件时,认为操作完成:

• 已接收响应的所有数据包(对于 RDMA READ 或 ATOMIC 操作)并将其提交到本地内存,

• 已接收并验证确认消息。

C9-60:在认为某个 (WQE) 已完成之前,请求者必须等待必要的响应到达。如果请求者需要明确的响应才能完成某个 (WQE),则请求者应负责采取必要的步骤,确保所需的响应即将到来。有几种机制可以实现此目的,例如:1) 在每个消息的最后一个数据包上设置 AckReq 位,从而保证响应方将生成所需的显式响应;2) 在需要显式响应的消息的最后一个数据包上设置 AckReq 位;3) 如果未设置需要显式响应的请求的 AckReq 位,则请求方可以重试该请求(设置 AckReq 位),从而要求响应方返回响应;4) 如果未设置需要显式响应的请求的 AckReq 位,则请求方可以发送 NOP 命令(例如,长度为零的 RDMA WRITE 请求)并设置 AckReq 位。此策略仅在响应方支持 RDMA WRITES 时才有效。选择使用哪种策略或其他策略取决于具体实现。

9.7.1 数据包序列号 (PSN)

所有数据包的 PSN 都在基本传输头 (BTH) 中传输。它们用于检测丢失或乱序的数据包,并且,为了提供可靠的服务,它们还将响应数据包与给定的请求数据包关联起来。每个 IBA QP 由一个发送队列和一个接收队列组成;同样,EE 上下文也包含发送方和接收方。请求方的发送队列中的 PSN 与响应方相应的接收队列中的 PSN 之间存在关联。因此,QP(或 EE 上下文)的每一半都维护一个独立的 PSN;给定队列对的发送队列和接收队列中使用的 PSN 之间,或不同连接之间,没有任何关联。如下图所示。为了确保可靠的运行,响应方必须检测并解决两种异常情况。这两种情况是重复数据包和无效数据包。

  1. 重复数据包。 如果请求方多次向Fabric注入请求数据包,响应方可能会识别出重复数据包。当请求方检测到规定的恢复机制需要重试操作的情况时,就会发生这种情况。超时情况主要有两个原因,可能导致请求方多次向Fabric注入给定的请求数据包:• 响应延迟到达请求方,原因可能是响应数据包在Fabric中丢失或延迟(如下图 87 所示),或者响应方在生成响应时遇到延迟;或者 • 请求数据包可能丢失或延迟到达响应方,如下图 89 所示。

无论原因如何,响应器都必须能够确定传入请求是否为先前已执行的重复请求,并做出适当的响应。在上图中,响应在Fabric中丢失或延迟,导致请求器检测到超时情况并重新传输请求。响应器将第二次到达的请求数据包解释为重复请求。

由于“幽灵(ghost)”请求数据包的存在,响应方也可能检测到重复数据包。当请求数据包在交换矩阵中延迟足够长的时间,导致请求方发生超时时,就会发生这种情况。请求方会重新发送原始请求数据包,响应方会向其生成正确的确认消息。一段时间后,原始(延迟)数据包到达响应方,响应方会将延迟到达的数据包解释为重复请求。例如,在自动路径迁移期间可能会发生这种情况。

  1. 无效的请求数据包序列。 当响应方认为交换矩阵中一个或多个请求数据包丢失时,就会发生这种情况。如下图所示。

区分无效数据包和重复数据包非常重要,因为请求方和响应方在这两种情况下的操作是不同的。响应方(对于请求数据包)和请求方(对于可靠服务上的响应数据包)都必须检测到这两种情况。除了重复数据包和无效数据包之外,还有第三种情况,称为陈旧(Stale)数据包(“TIME WAIT 数据包”)。如果在数据包传输过程中与响应方的连接断开并建立了新连接,则来自旧(陈旧)连接的数据包可能会到达响应方。响应方可能会将这个陈旧的传入数据包解释为有效数据包,而实际上它是前一个连接的残余。没有传输层机制可以防止这种情况;连接管理的责任是避免重复使用 QP,直到陈旧数据包不可能到达响应方。这是通过将请求者和响应者的 QP 置于足够长的“时间等待”状态来实现的,以确保在重新使用这些 QP 之前,Fabric中剩余的任何陈旧数据包都已过期。重复数据包通过基本传输头中携带的 24 位 PSN 字段与无效数据包区分开来,并允许唯一命名最多 16,777,216 个数据包。C9-61:为了使响应者能够区分重复数据包和无序数据包,给定发送队列在任何给定时间内未完成的 PSN 系列不得超过 8,388,608 个。因此,发送队列在任何给定时间内未完成的数据包不得超过 8,388,608 个。这包括所有 SEND 请求数据包、所有 RDMA WRITE 请求数据包、所有 ATOMIC 操作请求数据包以及所有预期的 RDMA READ 响应数据包的总和。因此,PSN 空间(包含 16,777,216 个 PSN)被划分为两个区域,每个区域包含 8,388,608 个 PSN,分别称为有效区域和无效区域。如图 90 所示。

响应器进一步将有效区域细分为预期 PSN 和重复区域。响应器的预期 PSN (ePSN) 在第 331 页的“第 9.7.4.1.2 节 响应器 - PSN 验证”中定义,并简单描述为响应器预期在下一个收到的新请求数据包中找到的 PSN。因此,重复区域定义为除单个预期 PSN 之外的整个有效区域。简而言之,重复 PSN 是响应器先前已看到并执行过的 PSN,并且该 PSN 位于有效区域内。

9.7.1.1 可靠服务的 PSN 模型

C9-62:对于使用可靠连接服务的 HCA 请求方,请求方应在其生成的每个请求的每个数据包中插入一个 PSN。响应请求时,响应方应在其生成的每个响应的每个数据包中插入一个 PSN。o9-29:如果 TCA 实现了可靠连接服务,或者 CA 请求方实现了可靠数据报或 XRC 服务,则请求方应在其生成的每个请求的每个数据包中插入一个 PSN。响应请求时,响应方应在其生成的每个响应的每个数据包中插入一个 PSN。除 RDMA READ 响应的特殊情况外,请求数据包中的 PSN 与相应响应数据包中的 PSN 之间存在 1:1 的关系。在通用 PSN 模型中,请求方计算要生成的下一个请求数据包的 PSN。计算出的 PSN 称为下一个 PSN。当请求方生成新的请求数据包时,“下一个 PSN”会被复制到 BTH 中,从而成为当前 PSN。然后,请求方会计算新的“下一个 PSN”。为了检测丢失或乱序的数据包,响应方还会计算其预期在下一个传入请求数据包中找到的 PSN。这被称为预期 PSN。相反,在生成响应时,响应方会计算响应 PSN,以将响应与给定请求关联起来。但是,由于确认合并(acknowledge coalescing)(如第 341 页上的 9.7.5.1.2 节“合并确认消息”中所述),请求方无法准确预测下一个响应数据包中会出现一系列 PSN 中的哪一个。因此,请求方必须准备好接受一系列响应 PSN 中的任意一个。该范围由最早的未确认请求数据包的 PSN 和最近发送的请求数据包的预期响应 PSN 所限定。请求方会评估传入响应数据包的 PSN,以确保其介于这两个极端值之间。该通用模型如下所示

在以下章节中,很少情况下无法从上下文中明确文中指的是这四个 PSN 中的哪一个。因此,通常使用“PSN”或“预期 PSN”或其他变体。在上下文不明确的情况下,为了清晰起见,使用上述表达方式。

9.7.2 ACK/NAK 协议

ACK/NAK 协议与数据包序列号一起,是可靠服务的基本组成部分,适用于可靠连接服务、XRC 服务和可靠数据报服务。本节及后续章节将描述该协议,提供一组控制 ACK 和 NAK 响应生成的规则,指定 ACK 和 NAK 代码,并指定请求方在收到 ACK 或 NAK 响应时所需的响应。ACK/NAK 协议的目的是允许请求方确定响应方是否正确接收了请求数据包。此外,还提供了确保完整消息被正确接收的机制。这通过数据包序列号和数据包操作码(首包/中间包/末包/唯一包指示(first/middle/last/only))的组合来实现。由于响应数据包可能在Fabric中丢失,ACK/NAK 协议要求请求方实现一个计时器来检测丢失的响应数据包。本节还将介绍传输计时器。本节始终使用“确认”一词来表示否定(NAK)或肯定(ACK)确认。通用术语“响应”用于描述响应方返回给请求方的确认。响应包含在一个或多个确认数据包中,并且可能包含(取决于原始请求消息)ACK 数据包、NAK 数据包、RDMA READ 响应或 ATOMIC 操作响应。以下是 ACK/NAK 协议规则的摘要:

• 可靠服务上收到的每个请求数据包都应被确认。

• 每个 RDMA READ 请求都需要明确的响应。具有正确格式的 ACK 扩展传输头 (AETH) 的 RDMA READ 响应被视为有效响应。ACK 扩展传输头出现在 RDMA READ 响应的第一个数据包和最后一个数据包(或唯一一个数据包)中。详细信息请参见第 355 页上的第 9.7.5.1.9 节 RDMA READ 响应

• 每个 ATOMIC 请求都需要一个明确的响应。带有正确格式的 ACK 扩展传输头 (AETH) 和 ATOMIC ACK 扩展传输头 (AtomicAckETH) 的确认数据包被视为有效响应。

• 确认可以合并(coalesced);也就是说,一个确认数据包可以作为一个或多个先前请求数据包的确认。

• 确认数据包应按照接收原始请求数据包的 PSN 顺序返回,包括 RDMA READ 响应。

• RDMA READ 响应由一个或多个数据包组成;所有其他响应都恰好由一个数据包组成。

C9-63:对于使用可靠连接服务的 HCA 响应者,响应者应按如下方式行为。响应者应确认收到的每个请求数据包。响应者应对收到的每个 RDMA READ 请求生成一个明确的响应。响应者应为收到的每个 ATOMIC 请求生成一个明确的响应。响应方应按照接收原始请求数据包的 PSN 顺序生成响应数据包,包括 RDMA READ 响应。o9-30:如果 TCA 响应方实现可靠连接服务,或者 CA 响应方实现可靠数据报或 XRC 服务,则响应方应按如下方式操作。响应方应确认收到的每个请求数据包。响应方应为收到的每个 RDMA READ 请求生成显式响应。响应方应为收到的每个 ATOMIC 请求生成显式响应。响应方应按照接收原始请求数据包的 PSN 顺序生成响应数据包,包括 RDMA READ 响应

9.7.3 请求方:生成请求数据包

本节规定了请求方生成请求数据包时的要求。

9.7.3.1 请求方端 - 生成 PSN

C9-64:对于 HCA 中的可靠连接服务,请求方必须在每个请求数据包的 BTH:PSN 字段中放置一个称为当前 PSN 的值。o9-31:如果在 CA 中实现了可靠数据报或 XRC 服务,或者在 TCA 中实现了可靠连接服务,则请求方必须在每个请求数据包的 BTH:PSN 字段中放置一个称为当前 PSN 的值。在连接建立期间,传输层的客户端会将下一个 PSN 编程为 0 到 16,777,215 之间的任意值。为了正常运行,响应方的初始预期 PSN 值必须加载相同的值。 C9-65:对于 HCA 中的可靠连接服务,由传输层客户端编程的初始 PSN 是应出现在请求方生成的第一个请求数据包中的 PSN。o9-32:如果在 CA 中实现了可靠数据报服务或 XRC 服务,或者在 TCA 中实现了可靠连接服务,则由传输层客户端编程的初始 PSN 是应出现在请求方生成的第一个请求数据包中的 PSN。此后,请求方计算下一个 PSN。计算取决于正在执行的操作(SEND、RDMA READ 等)和数据有效载荷的大小。有一种例外情况,请求方应为其生成的每个请求数据包将当前 PSN 值加一。唯一的例外是紧跟在 RDMA READ 请求消息之后的任何请求数据包。在这种情况下,紧跟在 RDMA READ 请求消息之后的请求数据包的 PSN 应比最后一个预期的 RDMA READ 响应数据包的 PSN 大一。这样,请求者在请求数据包的 PSN 序列中留下一个“空洞(hole))”,这样所有响应数据包的 PSN 都会单调递增

由于请求方知道请求的 RDMA READ 数据的总长度以及请求方和响应方之间的 PMTU,并且要求每个响应数据包(最后一个或唯一的数据包除外)都填充到完整的 PMTU 大小,因此请求方可以计算预期的响应数据包的总数,从而计算紧随 RDMA READ 请求之后的请求的 PSN。C9-66:对于使用可靠连接服务的 HCA 请求方,请求方应执行以下操作。对于除紧随 RDMA READ 请求消息之后的数据包之外的每个请求数据包,请求方应将下一个 PSN 值增加 1 % (2的24次幂)。对于紧随 RDMA READ 请求消息之后的任何请求数据包,该数据包的 PSN 应比最后一个预期的 RDMA READ 响应数据包的 PSN 大 1(模 2的24)。 o9-33:如果 TCA 请求方实现了可靠连接服务,或者 CA 请求方实现了可靠数据报服务或 XRC 服务,则请求方应按如下方式操作。对于除紧随 RDMA READ 请求消息之后的数据包之外的每个请求数据包,请求方应将下一个 PSN 值加 1,以 2的24次幂为模。对于紧随 RDMA READ 请求消息之后的任何请求数据包,该数据包的 PSN 应比上一个预期的 RDMA READ 响应数据包的 PSN 大 1(以 2的24次幂为模)

9.7.3.2 请求者 - 可靠数据报的特殊规则

9.7.3.2.1 RDD 检查

对于可靠数据报服务,任何给定的发送队列都通过可靠数据报域 (RDD: Reliable Datagram Domain) 与一个 EE 上下文关联。每个发送队列和 EE 上下文都有一个与之关联的 RDD。在发送请求之前,EE 上下文必须检查当前活动发送队列的 RDD。如果发送队列的 RDD 与 EE 上下文的 RDD 不匹配,则当前消息传输将终止,并向发送队列指示超时条件。o9-34:对于每个请求,请求者必须确认当前活动发送队列的 RDD 与所选 EE 上下文的 RDD 匹配。o9-35:此合规声明已过时,已被删除。 RDD 不匹配的错误行为定义在第 437 页的表 61“请求方错误行为”中。

9.7.3.2.2 RESYNC 生成

在某些情况下,请求方的 EE 上下文需要生成一种特殊形式的请求数据包,称为 RESYNC 请求。当请求方 EE 上下文选择中止(中止)当前请求消息时,就会发生这种情况。中止当前请求消息并生成后续 RESYNC 请求的过程在第 391 页的 9.7.8 可靠数据报中有关处理 QP 错误的小节中进行了描述。RESYNC 请求具有特殊属性,它会强制响应方将其预期的 PSN 重新初始化为由请求方 EE 上下文定义的值。以下段落规定了请求方在中止当前消息并生成 RESYNC 请求时必须使用的 PSN。它还规定了在响应 RESYNC 请求时收到的确认中应包含的 PSN。这些 PSN 在图 91 请求/响应 PSN(第 320 页)中标识为下一个 PSN 和响应 PSN。o9-35.a1:对于支持可靠数据报服务的 CA,在中止当前请求消息并生成 RESYNC 请求时,请求方端 EE 上下文应将 RESYNC 请求的 PSN 设置为比传输当前请求中使用的最大 PSN(模 2的24次幂)大 1 的增量(模 2的24次幂)。此外,请求方应将其在响应中期望的 PSN 重置为相同值。“传输当前请求中使用的最大 PSN”是指:

  1. 分配给请求消息的任何数据包(包括请求消息的任何重试)的(逻辑上)最大 PSN(模 2的24次幂),或
  2. 如果请求是 RDMA READ 请求,则为最后一个预期的 RDMA READ 响应的 PSN。例如,如果当前正在传输的请求包含三个数据包,PSN 编号分别为 4、5 和 6,则 RESYNC 请求的 PSN 将设置为 7。或者,考虑请求方发送包含许多数据包的大型请求消息的情况。即使响应方在传输初期返回 NAK,但请求方已发送后续数据包,RESYNC 请求的 PSN 也必须比任何发送的请求数据包的 PSN 大 1(模 2的24次幂),无论 NAK 数据包的生成时间或其 PSN 是什么。再举个例子,如果当前正在传输的请求是 PSN 为 24 的 RDMA READ 请求,并且请求方预计会收到 5 个响应数据包,则 RESYNC 请求的 PSN 将设置为 29,这比最后一个预期的 RDMA READ 响应数据包的 PSN 大 1。如果由于超时或其他原因,请求者执行一次或多次重试,则 RESYNC 请求的 PSN 必须比之前所有尝试中发送的任何请求数据包或预期的响应数据包的 PSN 大一(模 2的24次幂)。o9-35.a2:对于支持可靠数据报服务的 CA,请求者应在 RESYNC 请求中插入与当前请求(正在中止)中的源和目标 QP 相同的源和目标 QP

9.7.3.3 请求者 - 生成操作码

请求者生成的操作码必须符合如下所示的操作码表。C9-67:请求者必须生成符合有效操作码序列表的数据包操作码,如第 326 页表 45 有效操作码序列表所示。表 45 有效操作码序列表

C9-68:生成请求数据包时,BTH:Opcode 应按照第 261 页表 38 中的 OpCode 字段指定

9.7.3.4 请求方 - 生成有效载荷

请求方应根据操作码生成有效载荷长度,如下所示:C9-69:如果操作码指定“第一个”或“中间”数据包,则数据包有效载荷长度必须为完整的 PMTU 大小。C9-70:如果操作码指定“唯一”数据包,则数据包有效载荷长度必须介于 0 到 PMTU 字节之间。因此,创建零字节长度传输的唯一方法是使用单数据包消息。C9-71:如果操作码指定“最后一个”数据包,则数据包有效载荷长度必须介于 1 到 PMTU 字节之间。C9-72:对于 HCA,如果操作码指定 RDMA WRITE 请求,则 RETH 的 DMALen 字段中指定的长度不得小于 0,且不得大于 231 字节。 o9-36:如果在 TCA 中实现了 RDMA WRITE,并且 OpCode 指定了 RDMA WRITE 请求,则 RETH 的 DMALen 字段中指定的长度应不小于 0,且不大于 2的31次幂字节。

9.7.4 响应器:接收入站请求数据包

本节介绍响应器接收入站请求数据包时所使用的流程。

9.7.4.1 响应器 - 入站数据包验证

C9-73:对于 HCA 中的可靠连接服务,入站请求数据包应按照第 328 页图 92 所示进行验证。o9-36.a1:如果 TCA 中实现了可靠连接服务或 XRC,则入站请求数据包应按照第 328 页图 92 所示进行验证。o9-37:如果 CA 中实现了可靠数据报服务或 XRC 服务,则入站请求数据包应按照第 329 页图 93 所示进行验证。以下章节将分别介绍验证检查以及响应器的行为/响应。

9.7.4.1.1 响应者 - 可靠数据报检查的特殊规则

o9-38:对于 HCA 中的 RD,当入站数据包到达时,接收队列必须将其自身的 RDD 值与接收数据包所经过的 EE 上下文的 RDD 值进行比较。如果不匹配,接收队列必须丢弃该数据包并安排一个 NAK-Invalid RD 请求。用于返回 NAK 的 P_Key 和 PSN 应由 EE 上下文提供。对于可靠的数据报服务,PSN 由响应者的 EE 上下文检查。响应者响应请求的行为很大程度上基于对传入 PSN 的解释。从逻辑上讲,接收队列或 EE 上下文会维护一个预期的 PSN (ePSN)。这是响应者期望在其收到的下一个新请求数据包的 BTH 中找到的 PSN。响应方计算其下一个预期 PSN 的规则与请求方计算其下一个请求数据包中要插入的 PSN 值时使用的规则相同。注意:有关图 92 入站请求数据包验证(RC 模式,第 328 页)和图 93 入站请求数据包验证(RD 模式,第 329 页)中提到的每种错误条件下响应方的行为描述,请参阅 9.9.3 响应方行为(第 444 页)

o9-38.a1:如果CA中实现了可靠数据报服务,则响应方在收到入站数据包时应执行以下操作:

  1. 如果响应方收到一个操作码为“middle”或“last”的新请求数据包(即,PSN = 预期PSN)(即,响应方之前已收到一个操作码为“first”的新请求数据包,但尚未收到操作码为“last”的新请求数据包),则响应方应验证新请求数据包中包含的源QPns和目标QPns是否与最近收到的“first”数据包完全匹配。如果新的“middle”或“last”请求数据包的源QPns和目标QPns与最近收到的“first”请求数据包不匹配,则响应方应忽略该数据包。
  2. 如果响应方收到重复的请求数据包(即 PSN 位于重复区域),则响应方应验证重复请求数据包中的源 QPns 和目标 QPns 是否与最近收到的新请求完全匹配。如果源 QPns 和目标 QPns 与最近收到的新请求不匹配,则响应方应忽略该数据包。o9-38.a2:如果 CA 中实现了可靠数据报服务,则当传入的 RESYNC 请求到达时,响应方应执行以下操作:
  3. 如果响应方收到 RESYNC 请求,则无论 RESYNC 请求中源 QPns 和目标 QPns 的值如何,它都应接受该请求。
  4. 如果响应方收到 RESYNC 请求,则无论当前正在执行的请求(即最近收到的新请求)的操作码序列(“第一个”、“中间”等)的状态如何,它都应接受该请求。
  5. 如果 RESYNC 请求的 PSN 等于或逻辑上大于响应方的预期 PSN(即 RESYNC 请求是一个新请求),则响应方应: a) 将其预期 PSN 设置为 RESYNC 请求的 PSN 加一(模 2的24次幂); b) 使用 RESYNC 请求的 PSN 作为响应的 PSN; c) 如果当前正在执行的请求未完成(即,操作码为“last”或“only”的请求数据包尚未到达),则中止与当前正在执行的请求相关的任何处理。如果当前正在执行的此类请求是立即执行的 SEND RDMA WRITE 操作(因此会消耗一个接收 WQE),则部分消耗的接收 WQE 应被视为错误完成。
  6. 如果 RESYNC 请求的 PSN 在逻辑上小于响应方的预期 PSN,则响应方应将 RESYNC 请求视为重复请求,因此不应更改其预期 PSN。响应方应使用重复 RESYNC 请求的 PSN 作为响应的 PSN
9.7.4.1.2 响应方 - PSN 验证

C9-74:对于 HCA 响应方中的可靠连接服务,在执行入站请求之前,响应方应通过将入站 BTH:PSN 与响应方的预期 PSN 进行比较来检查 PSN。PSN 应由响应方的接收队列进行检查。o9-39:如果 CA 中实现了可靠数据报服务或 XRC 服务,或者 TCA 中实现了可靠连接服务,在执行入站请求之前,响应方应通过将入站 BTH:PSN 与响应方的预期 PSN 进行比较来检查 PSN。响应方的接收队列应检查 PSN。对于可靠数据报服务,PSN 由响应方的 EE 上下文检查。响应方响应请求的行为很大程度上基于对传入 PSN 的解释。逻辑上,接收队列或 EE 上下文维护一个预期 PSN (ePSN)。这是响应方期望在其收到的下一个新请求数据包的 BTH 中找到的 PSN。响应方用于计算其下一个预期 PSN 的规则与请求方计算要插入其下一个请求数据包中的 PSN 值时使用的规则相同。C9-75:对于 HCA 响应方中的可靠连接服务,响应方应使用第 322 页上 9.7.3.1 请求方端 - 生成 PSN 中给出的规则来计算其预期 PSN。 o9-40:如果在 CA 中实现了可靠数据报服务或 XRC,或者在 TCA 中实现了可靠连接服务,则响应方应使用第 322 页上 9.7.3.1 请求方 - 生成 PSN 中给出的规则来计算其预期 PSN。响应方的预期 PSN 在连接建立时由通信管理器初始化为 0 到 16,777,215 之间的任意值。为了正常运行,此初始值必须与请求方加载的初始下一个 PSN 值匹配。仅当队列处于已初始化状态时,客户端才能设置初始预期 PSN。客户端在任何其他状态下设置 PSN 的尝试都可能会被传输层忽略。C9-76:对于 HCA 响应方中的可靠连接服务,仅当接收队列处于适当调节以接收请求数据包的状态时,HCA 才应更新其预期 PSN例如,当队列对处于初始化状态时,传输不会修改预期的 PSN。o9-41:如果在 TCA 中实现可靠连接服务或在 CA 中实现 XRC 服务,则响应方应仅在接收队列处于适当调节以接收请求数据包的状态时更新其预期的 PSN。例如,当队列对处于初始化状态时,传输不会修改预期的 PSN。o9-42:如果在 CA 中实现可靠数据报服务或 XRC 服务,则响应方应仅在 EE 上下文处于适当调节以接收请求数据包的状态时更新其预期的 PSN。与预期的 PSN 相比,入站请求消息的实际 PSN 可能属于以下三个区域之一;它可能完全等于响应者的预期 PSN,也可能逻辑上“小于”响应者的预期 PSN,从而落入重复区域(如图 90 所示),或者它可能同时落在有效区域和预期 PSN“区域”之外,从而无效。预期(新)请求:如果接收到的入站请求数据包的 PSN 与响应者的预期 PSN 完全匹配,则该数据包为新请求数据包。C9-77:对于 HCA 响应者中的可靠连接服务,应正常验证新请求数据包,并根据执行顺序规则执行。执行请求后,应按照第 340 页 9.7.5 响应者:生成响应中的规定安排响应。o9-43:如果 CA 中实现了可靠数据报服务或 XRC,或者 TCA 中实现了可靠连接服务,则应正常验证新请求数据包,并根据执行顺序规则执行。请求执行后,应按照第 340 页 9.7.5 节“响应器:生成响应”中的规定安排响应。请注意,无需为每个传入请求数据包返回离散确认数据包。收到包含有效预期 PSN 的数据包后,响应器会通过计算新的预期 PSN 来提升其预期 PSN,并向上滑动有效区域窗口以反映新的有效 PSN 范围。有效重复请求:位于有效区域内但并非预期 PSN 的 PSN 为有效重复请求数据包。 C9-78:对于 HCA 响应器中的可靠连接服务,响应器应按照第 345 页上的 9.7.5.1.4 确认重复请求中的规定响应有效的重复请求。o9-44:如果在 CA 中实现了可靠数据报服务或 XRC 服务,或者在 TCA 中实现了可靠连接服务,则响应器应按照第 345 页上的 9.7.5.1.4 确认重复请求中的规定响应有效的重复请求。表 46 总结了这些操作。无效请求:如果数据包的实际接收 PSN 位于有效区域之外且不在预期的“区域”内,则该数据包为无效请求。无效的 PSN 值通常表示结构中丢失了一个或多个请求数据包。响应器对无效请求数据包的详细响应行为如下:

• 不执行错误的请求数据包。

• 在错误请求之前收到的任何请求数据包都必须在发出 NAK 序列错误之前执行并完成,因为它对先前未完成的 SEND 或 RDMA WRITE 请求充当隐式 ACK,对未完成的 RDMA READ 或 ATOMIC Operation 请求充当隐式 NAK。

• 向请求方返回 NAK 序列错误。

• 响应方不更新其预期的 PSN。

表 46 汇总:响应方对重复 PSN 的操作

无效请求:如果数据包的实际接收 PSN 超出有效区域,且不在预期的“区域”内,则该数据包为无效请求。无效的 PSN 值通常表示一个或多个请求数据包在结构中丢失。响应方响应无效请求数据包的具体行为如下: • 不执行错误的请求数据包。 • 在发出 NAK 序列错误之前,必须执行并完成在错误请求之前收到的任何请求数据包,因为它充当先前未完成的 SEND 或 RDMA WRITE 请求的隐式 ACK,以及未完成的 RDMA READ 或 ATOMIC 操作请求的隐式 NAK。 • 向请求方返回 NAK 序列错误。 • 响应方未更新其预期的 PSN。C9-79:对于 HCA 响应方中的可靠连接服务,当传入请求消息的实际 PSN 超出有效区域(无效请求)时,响应方应返回 NAK 序列错误。在发出 NAK 序列错误之前,必须执行并完成在错误请求之前收到的任何请求数据包。o9-45:如果 CA 中实现了可靠数据报服务或 XRC 服务,或者 TCA 中实现了可靠连接服务,并且如果入站请求消息的实际 PSN 超出有效区域(无效请求),则响应方应返回 NAK 序列错误。在发出 NAK 序列错误之前,必须执行并完成在错误请求之前收到的任何请求数据包。响应方将继续等待有效的入站请求数据包,该数据包的 PSN 等于其预期 PSN 或在其有效区域内。如果在等待有效的新请求时,响应方收到任何后续的无效请求数据包,则这些数据包将被静默丢弃;不返回 NAK。C9-80:对于 HCA 响应方中的可靠连接服务,在生成 NAK 序列错误后,响应方在收到有效的新请求或有效的重复请求之前不得生成 ACK 或 NAK。 o9-46:如果CA中实现了可靠数据报服务或XRC服务,或者TCA中实现了可靠连接服务,则在生成NAK序列错误后,响应方在收到有效的新请求或有效的重复请求之前不得生成ACK或NAK。无需停止队列,对于已连接的传输服务,也无需断开连接。

9.7.4.1.3 响应方 - 操作码序列检查
  1. 如果这是建立连接后的第一个数据包,则数据包操作码必须指示“first”或“only”。
  2. 如果收到的最后一个有效数据包的操作码指示“first”,则当前操作码必须指示“middle”或“last”。它还必须与最后一个有效数据包(发送、RDMA、ATOMIC 操作)中指定的操作类型匹配。如果当前 OpCode 指示“first”或“only”,则会出现错误,因为这意味着上一条消息的最后一个数据包丢失了。
  3. 如果收到的最后一个有效数据包的 OpCode 指示“middle”,则当前 OpCode 必须指示“middle”或“last”。它还必须与最后一个有效数据包(发送、RDMA、ATOMIC 操作)中指定的操作类型匹配。如果当前 OpCode 指示“first”或“only”,则会出现错误,因为这意味着上一条消息的最后一个数据包丢失了。
  4. 如果收到的最后一个有效数据包的 OpCode 指示“last”,则当前 OpCode 必须指示“first”或“only”。如果当前 OpCode 指示“middle”或“last”,则会出现错误,因为这意味着消息的第一个数据包丢失了。
  5. 如果收到的最后一个有效数据包的 OpCode 指示“only”,则当前 OpCode 必须指示“first”或“only”。如果当前 OpCode 指示中间数据包或最后一个数据包,则会出现错误,因为这意味着消息的第一个数据包丢失了。下表简要说明了这些规则。C9-81:对于使用可靠连接服务的 HCA 响应方,响应方应检查组成请求消息的数据包 OpCode 序列是否符合第 335 页表 47 有效 OpCode 序列表所示的时间表。如果响应方检测到无效的操作码序列,则应向请求方返回 NAK-Invalid 请求。 o9-47:如果 TCA 响应器实现可靠连接服务,或者 CA 响应器实现 XRC 服务,则响应器应检查组成请求消息的数据包 OpCodes 序列是否符合第 335 页表 47 有效 OpCode 序列表所示的时间表。如果响应器检测到无效的操作码序列,它应向请求者返回 NAK-Invalid 请求。表 47 有效操作码序列表 C9-81:对于使用可靠连接服务的 HCA 响应者,响应者应检查组成请求消息的数据包操作码序列是否符合第 335 页表 47 有效操作码序列表所示的序列。如果响应者检测到无效的操作码序列,它应向请求者返回 NAK-Invalid 请求。o9-47:如果 TCA 响应者实现可靠连接服务,或 CA 响应者实现 XRC 服务,响应者应检查组成请求消息的数据包操作码序列是否符合第 335 页表 47 有效操作码序列表所示的序列。如果响应者检测到无效的操作码序列,它应向请求者返回 NAK-Invalid 请求。 o9-48:如果CA响应器实现了可靠数据报服务,则响应器应检查构成请求消息的数据包OpCode序列是否符合第335页表47“有效OpCode序列表”中所示的序列。如果响应器检测到无效的OpCode序列,则应向请求器返回NAK-无效请求。无效OpCode序列情况下的详细行为已在第431页第9.9节“错误检测和处理”中说明。o9-49:此合规性声明已过时,已被删除
9.7.4.1.4 响应方操作码验证

C9-82:在执行入站请求之前,响应方应验证 BTH 的操作码 (OpCode) 字段。将检查操作码的以下特征: • 此接收队列是否支持所请求的功能(发送、RDMA、ATOMIC); • 如果请求是 RDMA 读取或 ATOMIC 操作,则检查是否有足够的资源来接收它。 当数据包向上传递到传输层时,将检查 BTH 操作码 (OpCode) 字段 [7:5],以确保请求的操作是可靠服务操作。如果不是,则数据包将被静默丢弃。此检查在第 301 页的 9.6 节“数据包传输头验证”中进行了详细说明。因此,在数据包根据本节中的规则到达队列对进行验证之前,它已被确定为可靠服务请求。 C9-83:对于 HCA 响应器中的可靠连接服务,如果请求是针对此接收队列不支持的功能,则应返回 NAK-Invalid 请求。例如,如果队列对未配置为接受 RDMA 请求,但请求是针对 RDMA WRITE,则应返回 NAK-Invalid 请求。o9-50:如果在 CA 中实现可靠数据报服务或 XRC 服务,或者在 TCA 中实现可靠连接服务,如果请求是针对此接收队列不支持的功能,则应返回 NAK-Invalid 请求。C9-84:对于 HCA 响应器中的可靠连接服务,并且 BTH OpCode 字段[4:0]指定了可靠连接保留操作码或可靠数据报保留操作码,则应返回 NAK-Invalid 请求。 o9-51:如果CA中实现了可靠数据报服务或XRC服务,或者TCA中实现了可靠连接服务,并且BTH OpCode字段[4:0]指定了可靠连接保留操作码、可靠数据报保留操作码或XRC保留操作码,则应返回NAK无效(NAK-Invalid)请求。C9-85:对于HCA响应方中的可靠连接服务,如果BTH OpCode字段[4:0]指定了第一个或中间请求数据包(例如,SEND First或RDMA WRITE Middle),则应验证填充计数位是否为b00,表示不存在填充字节。如果填充计数位非零,则应返回NAK无效请求。 o9-52:如果在 CA 中实现了可靠数据报服务或 XRC 服务,或者在 TCA 中实现了可靠连接服务,并且如果 BTH OpCode 字段 [4:0] 指定了第一个或中间请求数据包(例如 SEND First 或 RDMA WRITE Middle),则应验证填充计数位为 b00,表示不存在填充字节。如果填充计数位非零,则应返回 NAK-Invalid 请求。C9-86:对于 HCA 响应器中的可靠连接服务,如果没有足够的资源来接收新的 RDMA READ 或 ATOMIC 操作请求,则应返回 NAK-Invalid 请求。o9-53:如果在 CA 中实现了可靠数据报服务或 XRC 服务,或者在 TCA 中实现了可靠连接服务,并且如果没有足够的资源来接收新的 RDMA READ 或 ATOMIC 操作请求,则应返回 NAK-Invalid 请求。

返回 NAK-Invalid 请求的行为如下: • 错误的请求数据包未执行。 • 在发出 NAK-Invalid 请求之前,必须执行并完成在错误请求之前收到的任何请求数据包。这一点非常重要,因为 NAK 会有效地将响应合并到先前未完成的请求中,并充当先前未完成的 SEND、RDMA WRITE、ATOMIC 操作或 RDMA READ 请求的隐式响应。有关详细信息,请参见第 341 页上的第 9.7.5.1.2 节“合并确认消息”。 • 返回 NAK-Invalid 请求。 • 响应方未更新其预期的 PSN。 C9-87:对于 HCA 响应方中的可靠连接服务,在响应方发出 NAK-Invalid 请求之前,必须执行并完成在包含无效操作码的数据包之前收到的任何请求数据包。 o9-54:如果在 CA 中实现了可靠数据报服务或 XRC 服务,或者在 TCA 中实现了可靠连接服务,则在响应方发出 NAK-无效请求之前,必须执行并完成在包含无效操作码的数据包之前收到的任何请求数据包。有关无效请求时的错误行为的更多详细信息,请参见第 444 页的“9.9.3 节响应方行为”。

9.7.4.1.5 响应方 R_KEY 验证

对于 RDMA 读、RDMA 写或原子操作,以下任何或所有情况都会导致 R_Key 违规: • RETH 的 R_Key 字段无效(对于 RDMA 读或写操作) • AtomicETH 的 R_Key 字段无效(对于原子操作)。 • 指定的虚拟地址和长度或访问类型超出了与 R_Key 关联的本地定义限制。对于 RDMA WRITE 请求,长度检查是按数据包进行的,并基于 LRH:PktLen 字段。对于 RDMA READ 请求,长度检查基于 RETH:DMA Length 字段。 • 对于 HCA,R_Key 违规还包括违反 10.2.3 保护域(第 474 页)中定义的保护域。 C9-88:对于使用可靠连接服务的 HCA 响应方,对于每个零长度的 RDMA READ 或 WRITE 请求,即使请求包含立即数据,也不应验证 R_Key。o9-55:如果 HCA 响应方实现了可靠数据报或 XRC 服务,或者 TCA 响应方实现了可靠连接/XRC 和 RDMA 功能,则响应方应按如下方式操作。对于每个零长度的 RDMA READ 或 WRITE 请求,即使请求包含立即数据,也不应验证 R_Key。 C9-89:如果响应方的接收队列检测到 R_Key 违规,则应使用错误请求数据包的 PSN 向请求方返回 NAK-远程访问错误(NAK-Remote Access Error)。C9-90:在包含 R_Key 违规的数据包之前收到的任何请求数据包都应在响应方发出 NAK-远程访问错误之前执行并完成。有关更多详细信息,请参阅第 359 页上的 9.7.5.2.4 远程访问错误。

9.7.4.1.6 响应方 - 长度验证

C9-91:应检查 LRH 的 PktLen 字段,以确认接收 WQE 指定的接收缓冲区中有足够的可用空间。如果接收 WQE 定义的缓冲区不足以容纳传入的 SEND 请求,则应返回 NAK-无效请求。 C9-92:还应通过将数据包的长度与 OpCode 进行比较来验证其长度,如下所示:如果 OpCode 指定“第一个”或“中间”数据包,则数据包有效载荷长度必须是完整的 PMTU 大小。如果 OpCode 指定“唯一”数据包,则数据包有效载荷长度必须在 0 到 PMTU 字节之间。因此,创建零字节长度传输的唯一方法是使用单数据包消息。如果 OpCode 指定“最后一个”数据包,则数据包有效载荷长度必须在 1 到 PMTU 字节之间。C9-93:如果检测到数据包的长度无效,则请求应为无效请求。响应方在这种情况下的行为在第 444 页上的第 9.9.3 节响应方行为中指定。除了检查 LRH:PktLen 字段外,还要按如下方式检查 RETH 的 DMA 长度字段。对于 RDMA WRITE 请求,响应方可以选择检查 RETH 中的 DMA 长度字段,以确保其指定的传输长度不超过 2的31次幂字节。此外,在传输结束时,响应方还可以验证数据包有效负载的总和是否等于 RETH 中的 DMALen 字段。如果响应方检测到上述任一情况,则可将请求视为无效请求。C9-94:对于验证入站 RDMA READ 请求的 HCA,应检查 DMA 长度字段。如果请求长度超过 2的31次幂字节,则应返回 NAK-Invalid 请求。o9-56:如果 TCA 实现了 RDMA 操作,则对于入站 RDMA READ 请求,应检查 DMA 长度字段。如果请求长度超过 2的31次幂字节,则应返回 NAK-Invalid 请求。

9.7.4.1.7 响应器本地操作验证

有效的入站请求仍可能由于响应器本地故障而无法完成,例如访问本地内存时发生本地内存转换错误。所有本地响应器错误都会以 NAK(远程操作错误)的形式报告给请求器。更多详细信息,请参阅第 360 页的 9.7.5.2.6 远程操作错误。

9.7.5 响应方:生成响应

9.7.5.1 响应方行为

本节规定了响应方在生成确认消息时必须遵循的行为。

9.7.5.1.1 生成用于确认消息的 PSN

响应方在生成每个请求的响应时,应通过在响应的 BTH 中插入 PSN 来标识与该响应关联的请求。这允许请求方将其收到的响应数据包与其请求关联起来。此基本概念如下图 94 示例:响应消息的 PSN(第 340 页)所示。

C9-95:对于 SEND 请求或 RDMA WRITE 请求的响应,响应方应在响应的 PSN 字段中插入最近确认的请求数据包的 PSN。此处以及第 9 章中使用的“最近请求的 PSN”特指最近收到的 NEW 请求数据包的 PSN。(这与最近收到的重复请求的 PSN 有所区别)。因此,最近收到的请求(most recently received)的 PSN 标志着响应方感知到的最大前进进度点(the point of greatest forward progress),同时忽略重复请求。由于合并确认的规则(见第 9.7.5.1.2 节),连续响应数据包的 PSN 不一定是连续的。C9-96:对于 HCA 对 RDMA READ 请求的响应,响应数据包的 PSN 必须是连续的,并且从原始 RDMA READ 请求消息的 PSN 开始单调递增。 o9-57:如果 TCA 实现 RDMA READ 功能,则对于每个 RDMA READ 响应,响应数据包的 PSN 必须是连续的,并且从原始 RDMA READ 请求消息的 PSN 开始单调递增。o9-58:由于 ATOMIC 操作请求需要明确的响应,并且 ATOMIC 操作请求仅限于单个数据包,因此响应数据包的 PSN 必须与请求的 PSN 相同

9.7.5.1.2 合并确认消息

每个请求数据包不必都有一个唯一且离散的响应。响应方可以使用单个确认数据包来确认多个未完成的请求数据包。这称为确认合并。给定的响应数据包将按如下方式确认先前未完成的请求(即,PSN 早于响应数据包 BTH 中包含的 PSN 的请求):

  1. 如果存在未完成的 RDMA READ 或 ATOMIC 操作请求,其 PSN 早于响应数据包 BTH 中的 PSN,则该响应数据包意味着对最早的此类未完成 RDMA READ 或 ATOMIC 操作请求进行否定确认。任何在此类 RDMA READ 或 ATOMIC 操作请求之后发布到发送队列的请求都不会被确认。如图 95(请求者对合并确认的解释,见第 342 页)所示。
  2. 这意味着对所有未完成的 SEND 或 RDMA WRITE 请求数据包(其 PSN 早于响应数据包 BTH 中的 PSN)进行肯定确认,除非此类未完成的 SEND 或 RDMA WRITE 请求位于未完成的 RDMA READ 或 ATOMIC 操作请求之后(如上所述)。
  3. 如果给定的响应是 RDMA READ 响应消息,则它是 RDMA READ 响应消息中第一个(或唯一一个)隐式确认先前未完成请求的数据包。
  4. RDMA READ 响应消息的最后一个(或唯一一个)数据包仅显式确认 RDMA READ 请求。这些规则如图 96 所示

图 95 请求者对合并的解释

确认数据包 a4:

  1. 隐式确认 SEND 请求 r1 和 r2;
  2. 隐式拒绝 RDMA READ 请求 r3。
  3. 不确认 SEND 请求 r4。 因此,请求 r1 和 r2 的确认已合并,请求者必须重试请求 r3 和 r4。
9.7.5.1.3 确认 RDMA 读取请求

RDMA 读取响应与普通响应不同,它包含数据有效载荷。每个 RDMA 读取请求消息都需要一个离散的确认,称为 RDMA 读取响应,它由一个或多个数据包组成。C9-97:对于 HCA,如果 RDMA 读取响应包含多个数据包,则第一个和最后一个数据包必须包含 AETH。o9-59:在实现 RDMA 的 TCA 中,如果 RDMA 读取响应包含多个数据包,则第一个和最后一个数据包必须包含 AETH。第一个数据包中的 AETH 隐式确认先前未完成的请求,如第 9.7.5.1.2 节“合并确认消息”中所述。最后一个数据包中的 AETH 确认 RDMA 读取请求。 C9-98:对于 HCA,如果 RDMA READ 响应本身是一个数据包,则该数据包必须包含 AETH。o9-60:如果 TCA 实现了 RDMA 功能,并且 RDMA READ 响应本身是一个数据包,则该数据包必须包含 AETH。包含在 RDMA READ 响应中的 AETH 既可以隐式确认先前未完成的请求,也可以显式确认 RDMA READ 请求本身。C9-99:HCA 响应方应生成与操作码一致的 RDMA READ 响应数据包有效载荷长度,如下所示:

  1. 操作码为“仅 RDMA READ 响应”的数据包长度应为 0 到 (PMTU) 字节。
  2. 操作码为“RDMA READ 响应优先”或“RDMA READ 响应中间”的数据包长度应恰好为 (PMTU) 个字节。
  3. 操作码为“RDMA READ 响应最后”的数据包长度应为 1 到 (PMTU) 个字节。
  4. 允许零长度 RDMA READ 请求。
  5. 对零长度 RDMA READ 请求的响应应由单个数据包组成,操作码为“RDMA READ response only”。

o9-61:如果 TCA 实现 RDMA 功能,则应生成有效载荷长度符合上一合规性声明的响应数据包。C9-100:如果 HCA 响应器在返回多数据包 RDMA READ 响应的过程中检测到错误,则应强制提前终止 RDMA READ 响应,方法是不传输任何错误的有效载荷数据,并强制发生错误的数据包的操作码为“确认”,而不是“RDMA READ 响应”插入相应的 NAK 代码。o9-62:如果 TCA 实现 RDMA 功能,并在返回多数据包 RDMA READ 响应的过程中检测到错误,则它应通过不传输任何错误的有效载荷数据并强制发生错误的数据包的操作码为“确认”而不是“RDMA READ 响应最后”的操作码来强制提前终止 RDMA READ 响应。插入相应的 NAK 代码。由于 RDMA READ 请求的排序规则比较宽松因此允许响应者开始执行在 RDMA READ 请求之后到达的一个或多个 SEND 或 RDMA WRITE 请求。C9-101:对于 HCA,在执行 RDMA READ 请求之后的任何请求之前,必须验证 RDMA READ 请求的标头字段。在发送未完成的 RDMA READ 响应之前,不得确认这些请求。 o9-63:在执行 RDMA READ 请求之后的任何请求之前,必须验证 RDMA READ 请求的标头字段。在未完成的 RDMA READ 响应发送完毕之前,不得确认这些请求。

图 96 RDMA READ 的松散排序规则

9.7.5.1.4 确认重复请求

验证重复请求后,对重复请求数据包的响应如下:C9-102:验证重复请求后,如果重复数据包有效,响应方应生成响应。C9-103:在处理重复请求的整个过程中,响应方不得更新其预期 PSN;该值应保持为重复请求到达之前的值。即使响应方在生成对重复请求的响应过程中检测到错误,也是如此。在生成适当的响应(如下段所述)后,响应方将继续等待 PSN 与其预期 PSN 匹配的新入站数据包。响应方在等待新的入站数据包时可能会收到另一个重复请求。这完全正常,应仅视为另一个重复请求。此外,由于这是一个重复请求,因此不要求收到的下一个请求与第一个重复请求的 PSN 顺序一致。但是,响应器需要维护与正常新请求相同的生成重复请求响应的排序规则。C9-104:具体来说,重复的 RDMA READ 或 ATOMIC Operation 请求必须先通过显式响应确认,然后才能返回后续重复的 SEND 或 RDMA WRITE 请求的确认。如图 97 所示,维护对重复请求的响应顺序(第 347 页)

要生成的响应取决于重复请求消息,如下所示: • SEND、RESYNC 或 RDMA WRITE 请求 C9-105:对于接收到重复入站 SEND 或 RDMA WRITE 请求的 HCA,或对于接收到重复入站 SEND 请求的 TCA,响应方不应重新执行该请求,而应仅为重复数据包生成响应数据包,并等待任何未完成的重复 RDMA READ 请求或 ATOMIC 操作请求的响应。o9-64:如果 TCA 响应方实现了 RDMA 功能,则它不应重新执行 RDMA WRITE 请求,而应仅为重复数据包生成响应数据包,并等待任何未完成的重复 RDMA READ 请求或 ATOMIC 操作请求的响应。确认消息的 PSN 必须是最近完成的新请求的 PSN。可以将此过程视为合并确认能力的逻辑扩展。实际上,请求方在收到对重复请求的响应时,会将其视为任何其他合并确认;任何未完成的重复 RDMA READ 或 ATOMIC Operation 请求都被视为 NAK 响应。在这种情况下,响应方通过返回最近完成的请求的 PSN,告知请求方它认为已经看到并执行了重复请求和最近完成的请求之间的所有请求。如图 98 所示。C9-106:对于重复的 SEND、RESYNC 或 RDMA WRITE 请求,如果响应方在返回响应的过程中检测到错误,它将静默丢弃重复请求。这样做是为了避免与任何可能未完成的新请求 NAK 混淆。

• RDMA 读请求 C9-107:HCA 响应器必须重新创建请求的读响应数据。生成的读数据将通过 RDMA 读响应返回给请求器。第一个 RDMA 读响应数据包的 PSN 应与重复请求的 PSN 相同,后续响应数据包的 PSN 将按照生成 RDMA 读 PSN 的正常规则递增。C9-108:如果 HCA 响应器在返回第一个响应数据包之前重新执行重复的 RDMA 读请求时检测到错误,则响应器应默默丢弃该重复请求。C9-109:如果 HCA 响应器在返回一个或多个响应数据包后重新执行重复的 RDMA 读请求时检测到错误,则应中止 RDMA 读响应操作,即不再返回任何响应数据包。生成 RDMA 读取请求时,系统会根据 RDMA 读取响应中预期的数据包数量分配一定数量的连续 PSN 编号。响应方在生成 RDMA 读取响应数据包时会使用这些 PSN。此外,原始请求包含 RETH 中定义的 DMA 长度,该长度表示所请求数据的范围。如第 285 页第 9.4.4 节“RDMA 读取操作”所述,要被视为重复的 RDMA 读取请求,重复请求的 PSN 必须位于响应方当前的重复 PSN 区域内。此外,要被视为有效的重复 RDMA 读取请求,重复请求的 PSN 必须位于分配给原始 RDMA 读取响应的 PSN 范围内,并且重复请求中请求的数据量必须完全包含在原始 RDMA 读取请求中请求的数据范围内。换句话说,重复 RDMA 读取请求中请求的数据必须是原始 RDMA 读取请求中请求数据的适当子集。如果重复的 RDMA 读请求的起始 PSN 和长度不在分配给原始 RDMA 读响应的 PSN 范围内,则该请求无效,响应方可以默默丢弃重复的 RDMA 读请求。C9-110:响应方应按 PSN 顺序响应所有重复请求;即,应首先执行具有(逻辑上)最早的 PSN 的请求。如果在响应新的或重复的请求时,收到具有逻辑上更早的 PSN 的重复请求,则响应方应停止响应原始请求,并开始响应具有逻辑上更早的 PSN 的重复请求。如果响应方被重复请求中断,则无需恢复中断的请求。请求方有责任重新发送任何未确认的请求。o9-65:如果 TCA 实现 RDMA 功能,则 RDMA 读响应应符合 HCA 的前 4 条合规性声明。在重复的 RDMA READ 响应之后,响应方可以使用最近完成的请求的 PSN 来确认任何后续的重复 Send 或 RDMA WRITE 请求。如图 99 所示。

• 原子操作请求 给定接收队列可能仅拥有支持有限数量原子操作的资源。当收到重复的原子操作请求时,会将重复请求的 PSN 与最近执行的原子操作的 PSN 进行比较。o9-66:如果重复的原子操作请求的 PSN 与最近执行的某个原子操作的 PSN 完全匹配,则应将该操作的已保存结果返回给请求方。响应方不得重新执行该请求。o9-67:如果重复的原子操作请求的 PSN 与最近执行的某个原子操作的 PSN 不匹配,则该请求无效,重复的请求数据包将被静默丢弃。只要请求方遵守未完成原子操作请求数量的限制,这种情况就不会发生。o9-68:如果本地错误阻止响应方重现原始原子操作请求数据,则响应方必须静默丢弃重复的请求。在所有情况下,确认消息中返回的 PSN 都是重复请求的 PSN

9.7.5.1.5 生成 NAK

有几种情况会导致响应方生成 NAK。C9-111:除 RDMA READ 请求外,所有情况下,NAK 数据包的 PSN 均应包含响应方预期的 PSN。C9-112:对于 RDMA READ 响应数据包,NAK 响应数据包中给出的 PSN 应指向被 NAK 的 RDMA READ 响应数据包。C9-113:生成 RNR NAK 时,响应数据包的 PSN 应指向被 RNR NAK 的数据包的 PSN。C9-113.a1:生成 NAK 时,包含 NAK 代码的数据包应具有“确认”操作码。这意味着,即使对于 RDMA 读取响应,如果响应方返回 NAK 代码,它也会通过替换带有确认操作码的数据包来代替 RDMA 读取响应的正常操作码(第一个/中间/最后一个/仅)。一旦响应方返回 NAK 序列错误或 RNR NAK,它会等待请求方发送带有响应方预期 PSN 的数据包。响应方必须遵循的规则如下:C9-114:一旦因 PSN 序列错误返回 NAK,响应方应忽略所有其他新请求(重复请求除外),直到收到 PSN 与其预期 PSN 匹配的有效请求。它不得返回任何其他 NAK 数据包,除非是响应 PSN 与其预期 PSN 匹配的有效请求。C9-115:响应方必须继续按上述规定响应重复请求。但是,响应方不得在处理重复请求期间发生错误情况时返回 NAK。

9.7.5.1.6 确认消息调度(ACKNOWLEDGE MESSAGE SCHEDULING)

响应的调度本身并未指定;但是,请求方可以使用 BTH 中的 AckReq 位来要求响应方调度响应。C9-116:当响应方收到设置了 AckReq 位的有效请求数据包时,它应为该请求调度一个响应数据包。响应的 PSN 必须等于或逻辑上大于(模 224)请求的 PSN。在收到设置了 AckReq 位的请求消息后,响应方在准备传输响应数据包时仍会接受请求消息(包括标记为 AckReq 位的其他请求消息)。当响应方能够发送响应时,这些其他请求消息可能会导致合并的 ACK。在这种情况下,单个响应消息可以满足多个未完成的请求消息。当一个或多个请求到达且未设置 AckReq 位时,响应方可能会选择故意合并其响应;它甚至可能会无限期地等待其他请求,直到收到需要调度响应的请求。AckReq 位在多个情况下对请求方非常有用。例如,如果请求方正在发送发布到发送队列的最后一个请求 WQE 的最后一个数据包,则建议请求方设置 AckReq 位或使用其他机制强制响应方返回响应。如果请求方不这样做,响应方可能会选择无限期地合并响应。请求方可以使用其他一些机制来确保响应方返回响应: • 始终在每个消息的最后一个(或唯一一个)数据包上设置 AckReq 位 • 在给定请求后跟一个设置 AckReq 位的 NOP 操作 • 重试需要响应且设置 AckReq 位的请求。

对于 SEND 或 RDMA WRITE 请求,可以在数据实际写入响应方内存之前安排 ACK。ACK 仅表示数据已成功到达响应节点的故障域。也就是说,数据已被通道适配器接收,并且通道适配器会将该数据写入响应节点的内存系统,或者至少会通知响应应用程序故障。缺少 AckReq 位并不禁止响应方生成响应数据包。与往常一样,RDMA READ 和 ATOMIC Operation 请求需要显式响应,因此 AckReq 位对请求没有影响。

9.7.5.1.7 响应格式

响应可能采用以下三种形式之一:

  1. 用于正常 SEND、RESYNC 或 RDMA WRITE 操作的确认数据包;
  2. RDMA READ 响应;以及
  3. 用于 ATOMIC 操作的确认消息 - 请参阅第 289 页的 9.4.5 ATOMIC 操作。

这三种形式之间的主要区别在于,正常确认数据包(用于 SEND、RESYNC 和 RDMA WRITE)不携带有效载荷字段,而 RDMA READ 和 ATOMIC 操作的响应都携带有效载荷字段。这一观察结果会影响响应的格式和合并确认的规则。确认数据包包含以下信息: • 用于通知请求者给定请求消息成功或失败的综合征(syndrome); • 请求者用来将确认消息与其未完成列表关联的 PSN 值 • 响应方用于通知请求方请求消息已完成的消息序列号, • 可选的端到端流量控制信用, • RDMA READ 响应或 ATOMIC 操作响应中的有效载荷数据。

以下章节将分别讨论这三种形式

9.7.5.1.8 发送、重新同步或 RDMA 写请求的响应格式

此格式用于确认发送、重新同步或 RDMA 写请求数据包。正常的确认消息由单个数据包组成,如图 100 所示。

注 1:GRH 可能出现,也可能不出现,具体取决于 LRH Next Header 字段 注 2:RDETH 仅在可靠数据报操作中出现 注 3:DETH、RETH、EOP、PYLD 和 IMM 字段被禁止 图 100 SEND 和 RDMA WRITE 的响应格式

9.7.5.1.9 RDMA 读取响应

此响应格式称为 RDMA 读取响应,用于确认 RDMA 读取请求。RDMA 读取响应消息由一个或多个数据包组成。C9-117:对于 HCA,RDMA 读取响应数据包的 PSN 必须是连续且单调递增的。如果响应消息由多个数据包组成,则响应消息的第一个和最后一个数据包必须包含确认扩展传输头 (AETH)。o9-69:如果 TCA 实现 RDMA 功能,则 RDMA 读取响应数据包的 PSN 必须是连续且单调递增的。如果响应消息由多个数据包组成,则响应消息的第一个和最后一个数据包必须包含确认扩展传输头 (AETH)。C9-118:对于 HCA,如果响应消息仅包含一个数据包(“唯一”数据包),则该数据包必须包含 AETH。如图 101.o9-70 所示:如果 TCA 实现 RDMA 功能,并且响应消息仅包含单个数据包(“唯一”数据包),则该数据包必须包含 AETH,如图 101 所示

RDMA READ 响应消息除了确认 RDMA READ 请求本身之外,还会隐式确认 RDMA READ 请求之前的请求。合并确认消息的规则在第 9.7.5.1.2 节(第 341 页)中给出。第一个数据包或唯一一个数据包的到达会触发对任何未完成请求消息的隐式确认,如第 9.7.5.1.2 节(第 341 页)所述。这样做是为了减少完成任何未完成请求消息的延迟。最后一个数据包或唯一一个数据包的到达会触发对 RDMA READ 请求本身的显式确认。

9.7.5.2 AETH 格式

确认综合征包含在确认消息的 AETH 中。下表 357 页上的表 48 AETH 综合征字段说明了 AETH 的综合征字段。C9-119:生成 AETH 时,实现 RC 服务的 HCA 响应器应按照表 357 页上的表 48 AETH 综合征字段所示对 AETH 综合征字段进行编码。o9-71:如果 TCA 响应器实现 RC 服务,或者 CA 响应器实现 RD 或 XRC 服务,则响应器应按照表 357 页上的表 48 AETH 综合征字段所示对 AETH 综合征字段进行编码。

C9-119.a1:对于 HCA,AETH 综合征字段的最高位应保留并设置为零。o9-71.a1:对于提供 RC 或 RD 服务的 TCA 或提供 XRC 服务的 CA,AETH 综合征字段的最高位应保留并设置为零。o9-72:如果 CA 实现可靠数据报服务,则 C CCCC 位应设置为零,因为 RD 服务未定义端到端信用。位 [4:0] 的解释取决于位 [6:5] 中包含的代码。位 [4:0] 可能包含有或没有端到端流量控制信用的肯定确认(取决于服务是 RC、XRC 还是 RD)、RNR NAK 计时器值、没有端到端信用的肯定确认或 NAK 代码。 C CCCC = 编码的端到端流量控制信用, T TTTT = RNR NAK 定时器字段 - 参见第 363 页的表 50 RNR NAK 定时器字段编码 N NNNN = NAK 代码 - 参见第 358 页的表 49 NAK 代码 代码 011 N NNNN (NAK) 允许 MSN 与 NAK 数据包一起携带。确认综合征在确认消息的 AETH 中携带。上文第 357 页的表 48 AETH 综合征字段说明了 AETH 的综合征字段

9.7.5.2.1 端到端流量控制信用字段

如果 AETH 综合征字段的 [7:5] 位为零,则 AETH 综合征字段的 [4:0] 位携带从响应方到请求方的编码端到端流量控制信用。此字段仅在可靠连接下有效。编码 5b11111 表示信用字段无效。此编码也用于接收队列不支持端到端信用的情况。有关更多详细信息,请参阅第 380 页上的“9.7.7.2 端到端(消息级)流量控制”一节。

9.7.5.2.2 NAK 代码

如果 AETH 综合征字段的 [6:5] 位为 b11,则 [4:0] 位携带 NAK 代码。该代码指导请求方选择恢复策略。以下章节介绍了所有可能的 NAK 代码。尽管 RNR NAK 有其自身的 AETH 校验子 (AETH[6:5] = b01),本节仍会介绍 RNR NAK。有效 NAK 代码列表请参见表 49:NAK 代码。

C9-120:如果请求方收到包含保留代码的确认消息,则应认为该确认数据包格式错误并默默丢弃。这最终可能导致请求方在等待丢失的确认数据包时超时,届时它将重新发送原始请求消息或停止该发送队列的操作。

9.7.5.2.3 PSN 序列错误

当响应方检测到超出 PSN 序列的数据包(即 PSN 值既不等于预期 PSN,也不在有效的重复数据包范围内)时,会发生序列错误。C9-121:响应方在构建 NAK 数据包以响应序列错误时,必须将其预期 PSN 值插入 BTH 的 PSN 字段。这使得请求方可以将其发送队列至少备份到故障点,并从该点开始重新发送请求数据包。请求方可以多次重试 PSN 序列错误。重试计数到期后,请求方的传输会通知其客户端其消息传输失败。重试计数到期后,请求方所需的行为在第 433 页的 9.9.2 请求方错误行为中给出。以下讨论指定了重试计数到期之前的行为。当响应方检测到序列错误时,接收队列不会受到影响,也不会消耗任何 WQE。相反,接收队列只会将 NAK 数据包返回给请求方,并继续等待具有正确 PSN 值的入站请求数据包。C9-122:一旦序列错误的 NAK 数据包返回给请求方,响应方应丢弃所有不包含响应方预期 PSN 的后续请求,有效重复请求除外。C9-123:如果响应方收到的请求数据包的 PSN 在逻辑上小于其预期 PSN(即有效重复请求数据包),则它应根据重复数据包处理规则响应该请求。

9.7.5.2.4 远程访问错误

对于 RDMA 读、RDMA 写或原子操作,以下任一或所有情况都会导致 R_Key 冲突: • RETH 的 R_Key 字段无效。 • 指定的虚拟地址和访问长度或类型超出了与 R_Key 关联的本地定义限制。 • 对于 HCA,检测到保护域冲突。 C9-124:对于 HCA 响应器,在报告 RDMA 远程访问错误时,确认消息的 BTH 字段必须包含导致远程访问错误的请求数据包的 PSN。o9-73:如果 TCA 响应器实现了 RDMA 功能,或者 CA 响应器支持原子操作,则在报告远程访问错误时,确认消息的 BTH 字段必须包含导致远程访问错误的请求数据包的 PSN。响应方在检测到访问错误时的行为(除了生成 NAK-远程访问错误数据包外)在第 9.9.3 节“响应方行为”(第 444 页)中进行了说明。请求方在收到 NAK-远程访问错误时的行为在第 9.9.2 节“请求方错误行为”(第 433 页)中进行了说明。

9.7.5.2.5 无效请求(INVALID REQUEST)

请求方请求的操作超出了传输服务的既定用途——通常是响应方不支持的操作码 (OpCode),或者请求的长度超出了可用的接收缓冲区空间。例如,向不支持 RDMA 的响应方发送 RDMA 请求会导致无效请求错误。根据具体服务的不同,操作码顺序错误也可能导致 NAK-无效请求。 C9-125:报告无效请求时,确认数据包的 BTH 字段必须包含响应方的预期 PSN 值,即包含无效请求的请求数据包的 PSN。响应方在检测到无效请求时的行为(除了生成 NAK-无效请求)在第 444 页的“9.9.3 响应方行为”中给出。请求方在收到 NAK-无效请求时的行为在第 433 页的“9.9.2 请求方错误行为”中给出。

9.7.5.2.6 远程操作错误

当响应方遇到导致其接收队列无法完成当前请求的情况时,就会发生远程操作错误。由于响应方可检测到并可报告为远程操作错误的错误条件列表与具体实现相关,因此未指定。远程操作错误不可能由请求方执行的任何操作引起。相反,它们反映了响应方自身的故障。 C9-126:报告远程操作错误时,确认消息的 BTH 字段必须包含响应方检测到操作错误时正在执行的请求的 PSN。响应方在检测到操作错误时的行为(除了返回 NAK-远程操作错误)在第 9 节中给出。9.3 响应方行为(第 444 页)。请求方收到 NAK 远程操作错误时的行为在 9.9.2 请求方错误行为(第 433 页)中进行了说明。

9.7.5.2.7 无效 RD 请求

当响应方在 RD 服务中运行时检测到 Q_Key 或 RDD 违规,或者目标 QP 未配置为 RD 服务,或者目标 QP 处于无法接收入站数据包的状态,或者检测到 XRC 服务的远程 XRC 域/XRCETH 违规时,都会生成此 NAK 代码(参见表 63 响应方错误行为摘要(第 445 页))。o9-74:如果响应方的 EE 上下文检测到无效的 P_Key,则 EE 上下文应静默丢弃请求数据包。如果未检测到 P_Key 违规,EE 上下文会将数据包转发到 BTH 中指定的接收队列。 C9-127:如果 BTH 中指定的 QP 未配置用于 RD 服务,则应返回 NAK-Invalid RD 请求。接收队列会检查传入请求数据包的 Q_Key,并检查其当前 RDD 值是否与 EE 上下文的 RDD 值匹配。如果响应方的接收队列检测到无效的 Q_Key,或者接收队列的 RDD 值与 EE 上下文的 RDD 值不匹配,则响应方应向请求方返回 NAK-Invalid RD 请求。响应方在检测到 Q_Key 或 RDD 违规时的行为(除了生成 NAK-无效 RD 请求外),在第 9.9.3 节“响应方行为”(第 444 页)中进行了说明。请求方在响应 NAK-无效 RD 请求时的行为,在第 9.9.2 节“请求方错误行为”(第 433 页)中进行了说明。

9.7.5.2.8 RNR NAK

在某些情况下,接收队列可能暂时无法接受入站请求消息。例如,当前可能没有有效的接收 WQE 发布到接收队列。发生这种情况时,响应方可能会返回指示“接收器未就绪”(RNR NAK)的响应。注意:响应方可以对任何类型的请求(例如 SEND、RDMA READ 请求、RDMA WRITE 请求等)返回 RNR NAK。收到 RNR NAK 后,请求者可以在至少等待 RNR NAK 中指定的时间间隔后重试相同请求。“相同请求”是指完全相同的请求消息,其开头的数据包与响应者在其 RNR NAK 数据包中报告的 PSN 相同。C9-128:对于使用可靠连接服务的 HCA 请求者,在收到 RNR NAK 后,请求者不得通过重新使用相同的 PSN 替换不同的请求消息。o9-75:如果 TCA 请求者实施可靠连接服务或 CA 实施 XRC 服务,在收到 RNR NAK 后,请求者不得通过重新使用相同的 PSN 替换不同的请求消息。对于可靠数据报服务,请求方可以完全重复请求、将 EEC 移至错误状态、放弃请求或暂停请求,如第 391 页第 9.7.8 节可靠数据报中所述。C9-129:使用可靠连接服务的 HCA 响应方在生成 RNR NAK 时,应在 AETH 的计时器字段中指示适当的间隔。AETH 的计时器字段中加载的值应如第 363 页表 50 RNR NAK 计时器字段的编码所示。o9-76:如果 CA 响应方实现可靠数据报服务或 XRC 服务,或者如果 TCA 实现可靠连接服务,则应遵循以下规则:在生成 RNR NAK 时,响应方应在 AETH 的计时器字段中指示适当的间隔。 AETH 的计时器字段中加载的值应如第 363 页的表 50 RNR NAK 计时器字段的编码所示。C9-130:提供可靠连接服务的 HCA 请求者在收到 RNR NAK 后,必须至少等待 AETH 计时器字段中指定的间隔,才能重试请求。如果请求者在重试请求前未能等待适当的超时间隔,则响应者可以静默丢弃数据包。o9-76.a1:提供可靠数据报服务或 XRC 服务的 HCA 请求者在收到 RNR NAK 后,必须至少等待 AETH 计时器字段中指定的间隔,才能重试请求。如果请求者在重试请求前未能等待适当的超时间隔,则响应者可以静默丢弃数据包。 o9-76.a2:提供可靠连接服务或 XRC 服务的 TCA 请求方,或提供可靠数据报服务的 TCA 请求方,在收到 RNR NAK 后,必须至少等待 AETH 计时器字段中指定的时间间隔,才能重试请求。如果请求方在重试请求前未能等待适当的超时间隔,响应方可能会默默丢弃该数据包。C9-131:此合规声明已过时,并已被删除。C9-132:使用可靠连接服务的 HCA 请求方应维护一个 3 位重试计数器,该计数器在连接建立期间加载,其中包含响应方提供的信息。此计数器用于限制请求者重试被 RNR NAK 拒绝的操作的次数。收到 RNR NAK 响应时,如果 RNR NAK 重试计数器不等于 7(表示无限次重试),则请求者应减少 RNR NAK 重试计数器。此后,当重试计时器到期时,如果重试计数器非零,则请求者可以重新发出请求。o9-77:如果 CA 请求者实施可靠数据报或 XRC 服务,或者如果 TCA 请求者实施可靠连接服务,则它应维护一个 3 位重试计数器,该计数器在连接建立期间使用响应者提供的信息加载。此计数器用于限制请求者重试被 RNR NAK 拒绝的操作的次数。收到 RNR NAK 响应时,如果 RNR NAK 重试计数器不等于 7(表示无限次重试),请求方应减少 RNR NAK 重试计数器。此后,当重试计时器到期时,如果重试计数器非零,则请求方可以重新发出请求。如果在 RNR NAK 重试计时器到期时,重试计数器已递减至零,则请求方会记录本地检测到的错误。更多详情,请参阅第 433 页上的“9.9.2.1 节 请求方侧错误检测 - 本地检测到的错误”。计时器字段的编码如下表所示。

对于不影响整个消息的临时问题(例如内存页面不存在),可以使用 RNR NAK。特别是对于可靠数据报服务,如果响应方在 SEND 请求消息中途返回 RNR NAK,则可能导致请求方放弃当前消息,并从另一个队列对发送新消息。这可能会导致响应方收到意外的不完整消息。响应方在执行 RESYNC 请求时会检测到这些不完整消息,从而允许响应方错误地完成部分完成的 WQE 并开始接收新请求。响应方应使用此功能作为一种机制,在本地资源极少不可用的情况下延迟传入请求。RNR NAK 机制会消耗带宽,因为传入的数据包将被中止并必须重新发送。

9.7.5.2.9 操作进行中 NAK

在某些情况下,响应方执行传输操作所需的时间可能超过 QP 中配置的传输超时时间。为防止响应方出现误超时,响应方可使用“操作进行中 NAK”通知请求方操作已执行。请求方则应重新填充其传输计时器,以防止由于响应方执行时间过长而导致超时重传。请求方在收到“操作进行中 NAK”后不得重传数据包(参见第 358 页的表 49 NAK 代码)。

9.7.6 请求方:接收响应

9.7.6.1 验证入站响应数据包

收到入站确认数据包后,请求方将按如下方式验证数据包:C9-133:为验证数据包的完整性,请求方应按照第 301 页的“数据包传输头验证”部分中的规定进行验证。无效数据包将被请求方静默丢弃。 C9-134:对于使用可靠连接服务的 HCA 请求者,应检查 PSN 以检测乱序数据包。由于确认消息可以按照第 341 页 9.7.5.1.2 节“合并确认消息”中的说明进行合并,因此 PSN 用于检测合并后的响应。o9-78:如果 TCA 请求者实现了可靠连接服务,或者 CA 请求者实现了可靠数据报服务或 XRC 服务,则应检查每个确认数据包的 PSN 以检测乱序数据包。由于确认消息可以按照第 341 页 9.7.5.1.2 节“合并确认消息”中的说明进行合并,因此 PSN 用于检测合并后的响应。 C9-135:对于使用可靠连接服务的 HCA 请求者,应根据第 358 页上的表 49 NAK 代码检查确认综合征的有效性。包含保留 NAK 代码的响应数据包应被直接丢弃。o9-79:如果 TCA 请求者实现可靠连接服务,或者 CA 请求者实现可靠数据报或 XRC 服务,则应根据第 358 页上的表 49 NAK 代码检查确认综合征的有效性。包含保留 NAK 代码的响应数据包应被直接丢弃。o9-79.a1:如果 CA 实现可靠数据报服务或 XRC 服务,则在接收响应数据包时,请求者应根据当前 EEC 的预期 QPn 检查 BTH 中包含的目标 QPn。如果响应数据包不是发往当前活动的请求者端 QP,则请求者应将其丢弃。请求方还必须确保响应适合正在执行的操作类型。例如,在某些拥塞的网络结构情况下,当预期 RDMA READ 或 Atomic 响应时,可能会收到 ACK。即使响应数据包中包含的 PSN 与请求方预期的响应 PSN 匹配,也可能发生这种情况。反之亦然。因此,请求方应验证收到的响应数据包是否与未完成的请求一致。如果不一致,则请求方的行为应如第 437 页表 61“请求方端错误行为”中所述。C9-135.a1:此合规性声明已过时。如果确定数据包有效,则请求方会对其进行处理。在处理确认数据包时,请求方可能会遇到本地错误。由于具体实现不同,因此未指定请求方在处理确认消息时可能遇到的本地错误列表,但其中包含由于请求方端故障导致的任何错误。此情况所需的行为在 9.9.2 请求方错误行为(第 433 页)中指定。验证入站响应数据包的 PSN 依赖于识别 PSN 序列中的三个关键点。这三个点是:

  1. 请求方的最大转发进度 - 请求方发送的任何请求中逻辑上最大的 PSN(模 2的24次幂)。(这包括为 RDMA READ 响应分配的 PSN 空间。)它标志着“正确”有效区域的“左”边缘。
  2. 最旧的未确认请求 - 最旧的未完成(未确认)请求的 PSN。这代表了请求者所看到的响应者的最大前进进度。此 PSN 的意义在于它标志着重复区域的结束,即逻辑上 PSN 小于此的响应将被视为无效或重复。
  3. 最旧的有效请求 - 此点标志着有效区域的“左”边缘。下图对这三个点进行了说明。

与请求数据包一样,每个响应数据包都携带一个 PSN。请求方在收到响应数据包后,会检查 PSN,以确定该响应是预期响应还是幽灵确认数据包。从概念上讲,请求方会跟踪最早的未确认请求数据包的 PSN,以及迄今为止发送的逻辑上最大的 PSN(模 224),其中包括为 RDMA READ 响应保留的 PSN。这两个 PSN 定义了上图中标识为未确认区域的 PSN 范围的端点。如果响应数据包的 PSN 在该范围内,则该数据包为预期响应数据包。如果响应不在该区域内,则将其视为重复响应,并根据第 9.7.5.1.4 节“确认重复请求”(第 345 页)中定义的规则进行处理,或者将其视为幽灵(无效)确认数据包,并被请求方丢弃。 C9-136:对于使用可靠连接服务的 HCA 请求者,请求者应丢弃幽灵确认数据包。o9-80:如果 TCA 请求者实现了可靠连接服务,或者 CA 请求者实现了可靠数据报服务或 XRC 服务,请求者应丢弃幽灵确认数据包。

9.7.6.1.1 重试请求的 PSNs

在某些情况下(如下所述),请求者可能需要重试请求。就 PSN 而言,这意味着请求者可以重新发送一个数据包,该数据包的 PSN 在逻辑上小于(模 2的24次幂)迄今为止传输的最大 PSN。在下图中,这被标识为重试请求

三种 PSN 范式

  • 请求者前进到最大前进进度点。
  • 由于超时,请求“备份/返回(backing up)”并重试请求。
  • 与此同时,响应者可能仍在继续前进。因此,它返回的响应的 PSN 可能在逻辑上大于重试请求的 PSN。(但是,对重试请求的响应不能大于请求者的最大前进进度点)

在重试请求的过程中,请求方应维护一种标记最大 PSN 前进点(高水位线)的方法,即使在逻辑上“备份”重试请求时的 PSN 序列。这是必要的,因为对重试请求的响应可能具有逻辑上大于重试请求的 PSN 的 PSN。发生这种情况的原因是,在某些情况下,响应方可能会将重试请求解释为重复请求。如果是这样,它(响应方)有义务返回标记其最大前进点的 PSN,该 PSN 可能超出重试请求的 PSN。请求方需要维护这三个指针(最大前进点、最早未确认请求的 PSN 和重试请求的 PSN),这被称为三 PSN 范式。尽管各种实现方式可能存在实现三 PSN 范式的不同方法,但请求方必须考虑到这样一个事实:响应方可能对重试请求返回一个 PSN,该 PSN 在逻辑上大于(更高级)重试请求本身的 PSN。

9.7.6.1.2 请求方对 NAK 消息的响应

请求方对否定响应消息的反应取决于返回的 NAK 代码,以及队列对配置为可靠连接、XRC 还是可靠数据报服务。NAK 序列错误会触发请求的自动重试。响应数据包中的 PSN 指示响应方认为其丢失了哪个请求数据包,因此请求方可以重试该请求。为了防止请求方永远重试同一个请求,请求方维护一个 3 位重试计数器,用于计数特定请求数据包重试和超时的次数。有关重试计数器的完整说明,请参阅第 433 页上的第 9.9.2.1 节“请求方错误检测 - 本地检测到的错误”。C9-137:使用可靠连接服务的 HCA 请求方应在响应方每次对给定请求数据包返回 NAK 序列错误时减少其 3 位重试计数器。每当给定的未完成请求被清除时,都应重新加载计数器。如果不支持自动路径迁移,并且如果再次返回 NAK 序列错误,则请求方应声明本地检测到错误。o9-80.a1:支持可靠数据报服务或 XRC 服务的 HCA 请求方应在响应方每次对给定请求数据包返回 NAK 序列错误时减少其 3 位重试计数器。每当给定的未完成请求被清除时,都应重新加载计数器。如果不支持自动路径迁移,并且如果再次返回 NAK 序列错误,则请求方应声明本地检测到错误。 o9-81:实施可靠连接服务、可靠数据报服务或 XRC 服务的 TCA 请求方应在响应方每次针对给定请求包返回 NAK 序列错误时减少其 3 位重试计数器。每当清除给定的未完成请求时,都应重新加载计数器。如果不支持自动路径迁移,并且如果再次返回 NAK 序列错误,则请求方应声明本地检测到错误。o9-82:如果 CA 支持自动路径迁移,则需要执行以下操作。如果在重试计数器递减为零后返回 NAK 序列错误,则通道适配器应尝试自动路径迁移。自动路径迁移之后,请求方应重新加载重试计数器并重新开始该过程。如果请求方在多次重试后仍未成功发送请求,则请求方应声明本地检测到错误。对于其他 NAK 数据包,发送队列的响应取决于该队列提供的是可靠数据报服务还是可靠连接/XRC 服务。可靠数据报行为:可靠数据报需要使用 EE 上下文来维护数据包序列号,从而确保请求的可靠传输。响应 NAK 的规则确保请求方的当前 PSN 与响应方的预期 PSN 保持同步。因此,请求方的 EE 上下文与响应方的 EE 上下文之间的连接仍然有效。这使得该连接能够继续为其他发送/接收 QP 提供服务。根据原因和操作,EE 上下文在检测到失败的请求数据包后,可能会采取以下任一操作: a) 它可能会从同一个 QP 重试同一个失败的数据包(请注意,并非所有 NAK 都可以重试,并且对于可以重试的 NAK,重试次数是有限制的),或者 b) 它可能会将 QP 和 EE 上下文转换为 Error 状态,以错误方式完成失败的请求消息,或者 c) 它可能会将当前 QP 置于 SQEr 状态,并根据详细遵循第 391 页 9.7.8 节“可靠数据报”中列出的规则。在这种情况下,失败的 WQE 通常最终会以错误完成告终。 最后一种策略旨在允许请求方 EE 上下文继续提供服务,从而避免拆除 EE 上下文到 EE 上下文的连接。如果要重试“相同的失败数据包”,请求方无需从响应方 NAK 中指示的 PSN 开始重传序列;相反,它可以从更早的请求数据包开始重传。响应方会将这些较早的请求数据包视为正常的重复数据包,不会产生任何不良副作用。有关错误和 EE 上下文后续行为的完整描述,请参见第 431 页 9.9 节“错误检测和处理”。C9-138:对于使用可靠连接服务的 HCA 请求方,请求方必须接收并丢弃任何重复的确认消息,且不会产生任何不良副作用。 o9-83:如果 TCA 请求方实现了可靠连接服务,或者 CA 请求方实现了可靠数据报服务或 XRC 服务,则请求方必须接收并丢弃任何重复的确认消息,且不产生任何不良副作用。可靠连接行为:对于可靠连接(包括 XRC),请求方在收到 NAK 时只有两种可能的选择:要么重试相同的请求数据包,要么将当前 WQE 标记为错误完成并通知其客户端。请注意,并非所有 NAK 都可以重试。如果请求方重试相同的请求数据包,则无需从响应方 NAK 中指示的 PSN 开始其重传序列;相反,它可以从更早的请求数据包开始重传。响应方会将这些更早的请求数据包视为正常的重复数据包,不会产生任何不良副作用。

9.7.6.1.3 检测丢失的确认消息和超时

在某些错误情况下,请求方未收到对其一个或多个请求的确认消息。这可能由以下三个原因之一引起:

  1. 响应方生成的确认消息随后在结构中丢失;
  2. 响应方由于某种原因发生故障,无法生成确认消息;
  3. 原始请求消息在被响应方接收之前已在结构中丢失。

所有这三种情况都会被请求方检测为丢失的确认消息。通常,这些错误会由于确认合并而自动纠正;请求方收到的下一个确认消息将隐式确认所有未完成的请求。但是,在某些情况下,丢失的确认消息不会被合并确认规则自动恢复。例如,结构中丢失的 NAK 消息将无法通过确认合并来解决,因为响应方规则要求响应方在给定时间内不能有超过一条未完成的 NAK 消息。C9-139:对于使用可靠连接服务的 HCA 请求者,为了检测丢失的响应,每个发送队列都需要实现一个传输计时器来计时未完成的请求。o9-84:如果 TCA 请求者实现可靠连接服务,或者如果 CA 实现 XRC 服务来检测丢失的响应,则每个发送队列都需要实现一个传输计时器来计时未完成的请求。o9-85:如果 CA 请求者实现可靠数据报服务,为了检测丢失的响应,每个 EE 上下文都需要实现一个传输计时器来计时未完成的请求。由于结构、调度算法和通道适配器架构以及许多其他因素的变化,不可能也不可取以高精度计时未完成的请求。尽管如此,传输计时器仍然是 ACK/NAK 协议不可或缺的元素,它提供了一种确定性方法来检测丢失的请求或响应。请求方无需单独对每个发起到结构中的请求进行计时,只需在预期响应时启动计时器即可。启动后,只要有未完成的预期响应,每次收到确认数据包时,计时器就会重新启动。计时器不会检测特定预期确认数据包的丢失,而只是检测响应数据包的持续缺失。计时器测量以下较小值: • 自请求方发送 BTH 中设置 AckReq 位的数据包以来的时间, • 或自最后一个有效确认数据包到达以来的时间。操作如下: 当计时器当前未运行且满足以下条件时,请求方启动计时器:

  1. 请求方在发送或 RDMA 写入请求中设置 AckReq 位,或
  2. 请求方生成 RDMA 读取请求,或
  3. 请求方生成原子操作请求。此后,请求者每次收到新的入站确认时都会重新启动计时器

只要仍有未完成的预期响应,传输计时器就会停止。 只要没有未完成的预期响应,计时器就会停止。“预期响应”由请求方通过设置请求数据包中的 AckReq 位或生成 RDMA READ 请求或 ATOMIC 操作请求来创建。未完成的预期响应是对任何在 BTH 中设置了 AckReq 位的请求数据包,或任何尚未确认的 RDMA READ 请求或 ATOMIC 操作请求的响应。每个 QP 都有一个与之关联的本地 ACK 超时值,该值用于派生传输计时器超时间隔 Ttr。C9-140:对于使用可靠连接服务的 HCA 请求方,传输计时器超时间隔 Ttr 应定义为 4.096 uS * 2(本地 ACK 超时)。本地 ACK 超时应为 5 位值,零表示计时器已禁用。本地 ACK 超时的最小可接受值(零除外)应由 CA 供应商定义。如果在 QP 上下文中加载的非零本地 ACK 超时值小于 CA 支持的最小值,则 CA 可以使用其最小值。C9-141:对于使用可靠连接服务的 HCA 请求者,QP 应提供检测超时条件的功能。超时间隔应在请求调度后开始。超时条件 To 的检测时间应不短于超时间隔 Tr,且不长于四倍超时间隔 4Tr:

一旦检测到给定请求包超时,请求者可以重试该请求。C9-142:对于使用可靠连接服务的 HCA 请求者,为防止请求者永远重试请求,请求者应维护一个 3 位重试计数器,用于计算特定请求包重试和超时的次数。每次给定请求包的传输计时器到期时,此计数器都应递减。每当清除给定的未完成请求时,都应重新加载计数器。有关重试计数器的完整说明,请参阅第 433 页上的第 9.9.2.1 节“请求者端错误检测 - 本地检测到的错误”。C9-143:对于使用可靠连接服务的 HCA 请求者,如果不支持自动路径迁移,并且如果在重试计数器递减到零之后传输计时器到期,则请求者应声明本地检测到错误。 o9-86:如果支持自动路径迁移,并且传输计时器在重试计数器递减至零后到期,则通道适配器应尝试自动路径迁移。自动路径迁移完成后,请求者应重新加载传输计时器重试计数器,并重新开始该过程。如果请求者在多次重试后仍未成功发送请求,则请求者应声明本地检测到错误。o9-87:如果TCA请求者实现了可靠连接服务,或者CA实现了XRC服务,则前五条HCA合规性声明(即未完成请求的超时规则)应适用于该TCA或CA。o9-88:如果CA请求者实现了可靠数据报服务,则前五条HCA合规性声明(即未完成请求的超时规则)应适用于该CA。在这种情况下,所描述的功能适用于EE上下文,而不是队列对。

9.7.6.1.4 重复确认

9.7.1 数据包序列号 (PSN)(第 314 页)描述了重复请求的生成方式。这些请求可能导致响应方返回重复确认。响应方还可能发送未经请求的确认,这些确认在请求方看来似乎是“幽灵确认”。C9-144:对于使用可靠连接服务的 HCA 请求方,如果响应方配置为生成端到端流量控制信用,则请求方必须从重复确认中提取端到端流量控制信用。o9-89:如果 TCA 实现了可靠连接服务,并且响应方配置为生成端到端流量控制信用,则请求方必须从重复确认中提取端到端流量控制信用。 C9-145:对于使用可靠连接服务的 HCA 请求者,应丢弃重复的确认。o9-90:如果 TCA 请求者实现了可靠连接服务,应丢弃重复的确认。完整说明请参见第 380 页上的“9.7.7.2 节 端到端(消息级)流量控制”。

9.7.7 可靠连接

可靠连接是指在单个本地 QP 和单个远程 QP 之间建立的连接,该连接可以保证消息在本地和远程 QP 之间最多传递一次,且按顺序传递,并且不会出现损坏(在没有不可恢复的错误的情况下)。扩展可靠连接服务 (XRC) 具有许多与可靠连接服务相同的特性,如第 408 页上的“XRC”部分所述。所需的可靠性特性通过应用数据包序列号和 ACK/NAK 协议来提供。 C9-146:对于 HCA,每个配置为可靠连接服务的 QP 必须符合第 312 页 9.7 节“可靠服务”中规定的要求、第 375 页表 51“可靠连接服务特性”中给出的特性以及本节给出的任何其他要求。

表 51“可靠连接服务特性”

所需的可靠性特性由数据包序列号和 ACK/NAK 协议的应用提供。C9-146:对于 HCA,为可靠连接服务配置的每个 QP 必须符合第 312 页第 9.7 节“可靠服务”中规定的要求、第 375 页表 51“可靠连接服务特性”中给出的特性以及本节中给出的任何其他要求。o9-91:此合规性声明已过时,已被删除。o9-91.a1:如果 CA 实施 XRC 服务,则其应遵守 XRC 服务合规性声明 C9-146、C9-147、C9-148 和 C9-149 的等效规定。

9.7.7.1 生成 MSN 值

对于可靠连接服务,消息序列号是响应方返回给请求方的数字,指示响应方已完成的消息数量。 MSN 包含在 AETH 的三个最低有效字节中。MSN 作为一种服务提供给请求方,通过告知请求方响应方已完成的消息来协助其完成 WQE。C9-147:使用可靠连接服务的 HCA 响应方应在任何包含 AETH 的响应数据包的 AETH 中返回 MSN。o9-92:如果 TCA 响应方实现了可靠连接服务,则它应在任何包含 AETH 的响应数据包的 AETH 中返回 MSN。逻辑上,请求方将一个连续的发送序列号 (SSN) 与发布到发送队列的每个 WQE 关联起来。SSN 与响应方在每个响应数据包中返回的 MSN 是一一对应的关系。因此,当请求方收到响应时,它会将 MSN 解释为响应方完成的最新请求的 SSN,以确定哪些发送 WQE 可以完成。请注意,如上所述,SSN 只是一个逻辑概念,用于传达 MSN 的应用概念;无需实现即可按所述方式实现它。初始化后,第一个发布到发送队列的 WQE 会被分配一个 SSN 值 1。响应方会将其 MSN 计数器初始化为零。此后,每当响应方完成对入站请求消息的执行时,都会递增其 24 位 MSN 值。如下图所示

C9-148:使用可靠连接服务的 HCA 响应器应将其 MSN 值初始化为零。响应器应在成功处理完新的有效请求消息后递增其 MSN。对于重复的请求,MSN 不应递增。递增后的 MSN 应在 RDMA READ 或 Atomic 响应的最后一个或唯一一个数据包中返回。对于 RDMA READ 请求,响应器可以在完成请求验证之后、开始传输任何请求数据之前递增其 MSN,并可在第一个响应数据包的 AETH 中返回递增后的 MSN。对于任何给定的请求消息,MSN 应仅递增一次。o9-93:如果 TCA 响应器实现了可靠连接服务,则应按照前述合规性声明中的说明计算并更新 MSN。

9.7.7.1.1 请求者在收到新的 MSN 时的行为

如上所述,响应数据包中存在新的 MSN 值可被请求者用作完成已发布到其发送队列的某些 WQE 的信号。由于响应者可以选择合并确认,因此单个响应数据包实际上可能包含多条请求消息的确认。因此,当请求者收到新的 MSN 时,它会从最早的未完成 WQE 开始评估其发送队列中的 WQE,并依次向前推进。下图展示了发送队列中没有未完成的 RDMA 读取请求或原子操作请求的情况。

对于存在未完成的 RDMA READ 请求或 ATOMIC 操作请求的情况,情况会稍微复杂一些。在这种情况下,请求者只会完成第一个未完成的 WQE,直到第一个未完成的 RDMA READ 请求、ATOMIC 操作请求或 SSN 与响应数据包中的 MSN 匹配的 WQE(以先到者为准)。这是因为 RDMA READ 请求和 ATOMIC

由于 RDMA 读操作顺序松散,响应方很可能在返回读操作响应数据(a3、a4、a5)之前就“完成”了 SEND4 操作。尽管如此,a3 的 MSN 为 4,表明响应方已完成 SEND1、SEND2 和 SEND4 操作。然而,由于发送队列中存在 READ3,请求方可能只会完成 SEND1 和 SEND2 操作。

操作请求需要显式响应,因此在收到此类显式响应之前无法完成。C9-149:对于使用可靠连接服务的 HCA 响应方,无论响应是肯定确认、否定确认还是重复确认,都应将 MSN 计数器插入 AETH。o9-94:如果 TCA 响应方实现了可靠连接服务,无论响应是肯定确认、否定确认还是重复确认,都应将 MSN 计数器插入 AETH。

9.7.7.2 端到端(消息级)流量控制

IBA 为可靠连接提供端到端(或消息级)流量控制功能,响应方可利用该功能优化其接收资源的使用。本质上,请求方只有在拥有适当的信用额度的情况下才能发送请求消息。编码后的信用值通过 AETH 中 Syndrome 字段的确认消息从响应方传输到请求方。AETH 中携带的信用值与同一 AETH 的 MSN 字段相关;因此,正确解释信用值字段也需要解释 MSN 字段。有关相应 AETH 字段的完整描述,请参见第 357 页上的“第 9.7.5.2 节 AETH 格式”。每个信用值代表接收一条入站请求消息所需的接收资源。具体来说,每个信用值代表发布到接收队列的一个 WQE。但是,接收信用值的存在并不一定意味着已分配足够的物理内存。例如,即使有足够的信用值,仍然可能出现内存不足以接收整个入站消息的情况。另一方面,共享接收队列概念允许一组接收队列从一个公共的接收 WQE 池(即共享接收队列)中提取资源。因此,任何单个接收队列都无法准确估算共享接收队列中可用的 WQE 数量。因此,对于与共享接收队列关联的任何 QP,端到端流量控制机制均被禁用。

  1. 端到端信用机制仅适用于可靠连接服务。
  2. 端到端信用由响应方的接收队列生成,并由请求方的发送队列使用
  3. 第 17 章“通道适配器”(第 1239 页)给出了 CA 支持端到端流量控制的要求。HCA 接收队列必须生成端到端信用(与共享接收队列关联的 QP 除外),但 TCA 接收队列无需这样做。如果 TCA 的接收队列生成端到端信用,则相应的发送队列必须接收并响应这些信用。
  4. 信用额度按每条消息发放,与消息大小无关。
  5. 端到端信用额度在 AETH 中以 5 位编码字段的形式携带。
  6. 响应方可以使用非请求确认包异步向请求方发送信用额度。非请求确认包是通过重新发送最近发送的确认包创建的。

C9-150:此合规声明已作废,已被 C9-150.2.1 取代。C9-150.2.1:对于未与 SRQ 关联的 QP,每个 HCA 接收队列应生成端到端流量控制信用额度。如果 QP 与 SRQ 关联,则 HCA 接收队列不应生成端到端流量控制信用额度。 o9-95:此合规声明已作废,已被 o9-95.2.1 取代:o9-95.2.1:每个 TCA 接收队列均可生成端到端信用,但与 SRQ 关联的 QP 除外。如果 TCA 支持 SRQ,则该 TCA 不得为与 SRQ 关联的 QP 生成端到端流量控制信用。C9-151:如果 TCA 的指定接收队列生成端到端信用,则相应的发送队列应接收并响应这些信用。这是对 CA 的每个发送队列的要求。

9.7.7.2.1 将信用从响应者转移到请求者

定义了两种机制,用于将信用从响应者的接收队列传输到请求者的发送队列。信用值可以捎带在现有的确认消息上,或者响应方可以生成特殊的非请求确认消息。捎带信用值是指在已调度的确认数据包的 AETH 字段中携带的信用值。捎带信用值:端到端信用值的捎带是指将信用值通过正常确认数据包的 AETH 传输给请求方。信用值在 AETH Syndrome[4:0] 中携带。当 AETH 中的 MSN 字段也有效时,信用值可以捎带在任何确认数据包上。非请求确认数据包:从 PSN 的角度来看,非请求确认消息在请求方看来就像是最新肯定确认消息的副本。但是,它始终具有 Ac 操作码。即使最近的肯定确认是 RDMA 读取响应或原子响应,也无需知晓。由于 ACK/NAK 协议禁止响应方发送重复的否定确认数据包 (NAK),因此无法通过重新发送 NAK 数据包来创建未经请求的确认。响应方可以随时发送未经请求的确认。请求方的发送队列只需从最近收到的确认数据包中恢复信用字段和 MSN。由于未经请求的确认数据包对请求方而言是重复的响应,因此除了信用转移之外,它对请求方没有任何影响。C9-152:未经请求的确认数据包的 MSN 字段必须具有有效的 MSN 字段。

9.7.7.2.2 协商连接:初始信用

对于每个已建立的连接,每个方向均单独设置是否使用端到端流量控制。接收队列的功能决定了该连接一半的流量控制特性。C9-153:如果接收队列发出信号表示它期望生成信用,则相应的发送队列必须遵守端到端流量控制规则。另一方面,如果接收队列发出信号表示它不会生成端到端流量控制信用,则相应的发送队列可以随意传输请求消息,而无需考虑信用。这是对 CA 的每个发送队列的要求。C9-154:如果 TCA 的接收队列未生成端到端信用,则它应将值 5b11111 放入 AETH Syndrome[4:0],表示信用字段无效。 o9-95.2.2:如果CA支持SRQ,且QP提供可靠连接服务并与SRQ关联,则QP不得生成端到端信用,并应将值5b11111放入AETH Syndrome[4:0],以表明信用字段无效。C9-155:当接收队列处于RESET状态时,传输层应将初始信用计数设置为零。一旦队列对转换为INITIALIZED、RTR、SQD或RTS状态,它应为每个已发布的接收WQE增加其信用计数。一旦处于RTR、SQD或RTS状态,响应方可以通过使用非请求确认将这些信用转移给请求方。通常,非请求确认是通过重新发送最近发送的带有更新信用字段的肯定确认数据包来创建的。然而,在初始化时,尚未发送任何确认数据包,因此无法使用创建非请求确认的常规方法。因此,在初始化时,通过从初始 PSN 中减去“1”来创建非请求确认。因此,如果在接收队列处于 RESET 状态时将 PSN 初始化为 0x000000,则初始非请求确认的 PSN 应为 0xFFFFFF。此处的“初始化时间”是指从接收队列退出 RESET 状态且尚未在 RTR、SQD 或 RTS 状态下发送确认数据包开始的时间间隔。对于接收此初始非请求确认数据包的发送队列,它将显示为“幽灵”确认数据包(图 102 响应数据包 PSN 区域,第 367 页)。请求者的发送队列可能会接受非请求确认数据包中包含的 MSN 和信用值,但忽略数据包的其余部分。这是幽灵响应正常规则的一个例外,正常规则要求丢弃幽灵确认数据包。尽管有上述规定,从响应者处收回初始信用额的责任仍应由请求者承担;如果响应者使用未经请求的确认提供初始信用额,则请求者可以接受这些信用额作为其初始信用额,以履行其收回初始信用额的责任。C9-156:如果响应者未提供初始信用额,则请求者的行为应符合第 9.7.7.2.5 节“请求者行为 - 有限发送 WQE”(第 390 页)中的规定。图 107(第 384 页)请求者端到端信用额流程和图 108(第 385 页)响应者端到端信用额初始化流程描述了此行为。请注意,这些图并未描述接收和发送队列的所有正常状态转换。这些内容在“软件接口”一章中有完整说明。

9.7.7.2.3 响应方计算信用值的算法

C9-157:此合规声明已作废,已被 C9-157.2.1 取代。C9-157.2.1:对于在未与 SRQ 关联的 QP 上使用可靠连接服务的 HCA,接收队列应为每条发布到接收队列的 WQE 增加其信用值。接收队列应为每条接收的消耗 WQE 的入站请求消息减少其信用值。因此,响应方在接收到入站 RDMA 读请求、不包含立即数据的 RDMA 写请求或原子操作请求时不会调整其信用值。如果接收队列与 SRQ 关联,则无论发布到接收队列的 WQE 有多少,响应方都不会调整其信用值。 o9-96:如果 TCA 实现了可靠连接服务,并且接收队列生成端到端流量控制信用,则它应为每条发送到接收队列的 WQE 增加其信用计数。对于每条消耗 WQE 的入站请求消息,它应减少其信用计数。因此,响应方在收到 RDMA 读请求、不包含立即数据的 RDMA 写请求或原子操作请求时,不会调整其信用计数。C9-158:此合规声明已过时,已被 C9-158.2.1: 取代。 C9-158.2.1:对于在未关联 SRQ 的 QP 上使用可靠连接服务的 HCA,对于生成的每条确认消息(无论是正常确认消息还是主动确认消息),接收队列都应插入其当前的编码信用计数,如第 387 页表 52 端到端流量控制信用编码中 AETH 综合征 [4:0] 所示。例如,如果接收队列有 5 个可用信用,则应在 AETH 中插入 5 位值 b00100。它还应包含其当前的 MSN 值。如果 QP 与 SRQ 关联,则接收队列应在 AETH o9-97 中插入 5 位值 5b11111:如果 TCA 实现了可靠连接服务,并且接收队列生成了端到端流量控制信用值,则对于生成的每条确认消息(无论是正常确认消息还是主动确认消息),它都应插入其当前编码的信用计数,如第 387 页表 52 端到端流量控制信用编码中的 AETH 综合征[4:0] 所示。例如,如果接收队列有 5 个可用信用值,则应在 AETH 中插入 5 位值 b00100。它还应包含其当前的 MSN 值。如果 TCA 未生成端到端流量控制,则应插入第 387 页表 52 端到端流量控制信用编码中所示的值,以指示信用计数字段无效。

9.7.7.2.4 请求者行为

信用额度的存在与否限制了发送者发送将消耗接收 WQE 的请求(SEND 请求或带有立即数据的 RDMA WRITE 请求)的能力。C9-159:当发送队列没有可用信用额度时,其行为应遵循第 390 页“请求者行为 - 受限发送 WQE”部分中的规定。请求者始终可以发送不消耗接收 WQE 的请求(不带立即数据的 RDMA WRITE 请求、RDMA READ 请求或 ATOMIC 操作请求),而无需考虑信用额度。 C9-160:请求者不得违反本规范中规定的正常事务排序规则,尤其是在第 299 页的“9.5 事务排序”部分。具体而言,请求者不得搜索发送队列,查找不消耗接收 WQE 的请求,并乱序传输这些请求,也不得违反隔离 WQE 的管理规则。可用信用额度以 AETH Syndrome[4:0] 的形式编码并携带;MSN 则以 AETH 的最低 3 个有效字节的形式携带。下表 52 显示了每个有效编码信用额度的实际信用额度。

表 52 端到端流量控制信用额度编码

从逻辑上讲,请求方会将一个连续的发送序列号 (SSN) 与发布到发送队列的每个 WQE 关联起来。SSN 与响应方在每个响应数据包中返回的 MSN 一一对应。因此,请求方会将 MSN 解释为响应方最近完成的请求的 SSN。C9-161:响应方在 AETH 中返回的编码信用计数应指定相对于 MSN 发布到响应方接收队列的 WQE 数量,除非响应方未生成端到端流量控制信用,在这种情况下,AETH 中会携带“无效”代码。由于 MSN 与请求方的 SSN 直接相关,因此信用计数只是响应方最近完成的请求的 SSN 在发送队列中的偏移量。从逻辑上讲,MSN 加上信用计数之和就是请求方的限制序列号 (LSN)。请求者可以自由传输任何 SSN 小于或等于计算出的 LSN 的请求。如果响应者在 AETH 中返回“无效”代码而非信用计数,则请求者可以随意传输请求。响应者使用“无效”代码来指示 AETH 信用计数字段无效,因为响应者不生成端到端信用。即使是生成端到端信用的响应者,也可以选择在 AETH 中发送“无效”代码。但是,一旦请求者在 AETH 中收到来自响应者的“无效”代码,请求者可以选择在该连接上的所有未来交易中忽略 AETH 信用计数字段。因此,如果响应者在发出“无效”信号后恢复返回有效信用,结果可能难以预测。任何 SSN 大于当前计算出的 LSN 的请求都被称为受限请求。发送队列在遇到受限请求时的行为如第 9.7.7.2.5 节“请求者行为 - 受限发送 WQE”中所述。图 109 将 AETH 值与发送队列关联(第 389 页)说明了响应者在 AETH 中返回的值与请求者的发送队列之间的关系

请求者每次收到包含有效信用的确认包时,都会计算一个新的 LSN。请求者还会动态调整 LSN,为每个希望发送且不消耗接收 WQE 的请求(RDMA READ 请求、不包含立即数据的 RDMA WRITE 请求或 ATOMIC 操作请求)加 1。此调整机制允许请求者发送不消耗接收 WQE 的请求。任何给定的实现都无需实现上述 LSN 和 SSN 机制,但必须在语义上符合上述行为。

9.7.7.2.5 请求者行为 - 受限发送 WQE

C9-162:当请求者在其发送队列中遇到一个 WQE,而该 WQE 没有可用信用时,该 WQE 被称为受限的。发送队列遇到受限 WQE 时的行为应如下: • 如果受限请求 WQE 是 RDMA READ 请求、不包含立即数据的 RDMA WRITE 请求或 ATOMIC 操作请求,则可以正常发送,而无需考虑信用额度的可用性。正常的请求排序规则仍然适用(即,发送队列不得搜索已发布的 WQE 列表,以尝试查找要乱序发送的无限 WQE)。发送此类请求后,请求者将增加其计算出的 LSN 值[参考11],因为发送的请求不会消耗接收 WQE,因此也不会消耗信用额度。 • 如果受限请求 WQE 是 SEND 请求,则发送队列在必须停止传输并等待确认数据包之前,最多只能传输一个请求消息数据包。为确保响应者能够生成响应,请求者应在该数据包中设置 AckReq 位。 • 如果受限请求 WQE 是包含立即数据的 RDMA WRITE 请求,则请求方可以在必须停止传输并等待确认数据包之前传输整个请求消息。这是允许的,因为实际消耗接收 WQE 的是包含请求立即数据的单个数据包。为确保响应方生成响应,请求方应在请求消息的最后一个数据包中设置 AckReq 位。 C9-163:对于使用可靠连接服务的 HCA,如果受限 WQE 是 SEND 请求,则发送队列应传输不超过一个请求消息数据包。在此单个数据包内,应设置 BTH 的确认请求 (AckReq) 位。然后,请求方应停止传输并等待确认数据包。o9-98:如果 TCA 实现了可靠连接服务,并且受限 WQE 是 SEND 请求,则发送队列应传输不超过一个请求消息数据包。在此单个数据包内,应设置 BTH 的确认请求 (AckReq) 位。然后,请求者应停止传输并等待确认数据包。

[11.可能会出现一种有趣的情况,即使用某些消息模式人为限制发送方的 LSN;如果发送方在接收方有两个信用的情况下执行 Send、RDMA、RDMA、RDMA,则会将 LSN 增加 3。如果此后,响应到达时带有 MSN+1 信用,则 LSN 将回退 2,使请求者处于限制状态,直到来自 RDMA 的确认到达]

o9-99:在使用可靠连接服务的 HCA 中,或者如果 TCA 实现可靠连接服务,并且如果受限请求 WQE 是 RDMA WRITE 请求,则请求者可以在必须停止传输并等待确认数据包之前传输整个请求消息。为确保响应方生成响应,请求方应在 RDMA WRITE 请求的最后一个数据包中设置确认请求 (AckReq) 位。C9-164:由于响应方的接收队列可能随时生成未经请求的确认消息,因此请求方应随时准备好接收来自响应方的未经请求的确认消息,前提是接收队列已发出信号表示它将生成端到端流量控制信用。未经请求的确认仅用于将信用从响应方转移到请求方。在收到未经请求的确认后,请求方会按照上述规定重新计算其 LSN 并进行相应响应。缺少信用不会影响请求方重新传输先前已传输的请求(作为其从丢失的数据包中恢复的一部分)的能力。端到端信用仅限制新请求消息的传输。例如,如果请求者在发送了一个有限的 SEND 请求数据包后检测到超时情况,它会像往常一样减少其超时重试计数器并重新发送该请求。

未完, 下一篇(9.7.8 可靠数据报): https://cloud.tencent.com/developer/article/2516321

参考

IB Spec1.6 卷1第9章

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 术语
  • 9.7 可靠服务
    • 简介
    • 9.7.1 数据包序列号 (PSN)
      • 9.7.1.1 可靠服务的 PSN 模型
    • 9.7.2 ACK/NAK 协议
    • 9.7.3 请求方:生成请求数据包
      • 9.7.3.1 请求方端 - 生成 PSN
      • 9.7.3.2 请求者 - 可靠数据报的特殊规则
      • 9.7.3.3 请求者 - 生成操作码
      • 9.7.3.4 请求方 - 生成有效载荷
    • 9.7.4 响应器:接收入站请求数据包
      • 9.7.4.1 响应器 - 入站数据包验证
    • 9.7.5 响应方:生成响应
      • 9.7.5.1 响应方行为
      • 9.7.5.2 AETH 格式
    • 9.7.6 请求方:接收响应
      • 9.7.6.1 验证入站响应数据包
    • 9.7.7 可靠连接
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档