每个 IBA 数据包都包含一个传输头。传输头包含端节点完成指定操作所需的信息,例如,将数据有效载荷传送到端节点内的相应实体(线程或 IO 控制器)。本章定义了 IBA 使用的传输服务。IBA 通道适配器的客户端通过操作由发送工作队列和接收工作队列组成的“队列对”(QP)与传输层通信。对于主机平台,传输层的客户端是 Verbs 软件层。客户端将缓冲区或命令发布到这些队列,硬件则从缓冲区传输数据或将数据传入缓冲区。在本章中,发起操作(即将消息注入到结构中的 QP)称为请求方,接收消息的 QP 称为响应方。创建 QP 时,它会与五种 IBA 传输服务类型之一或非 IBA 协议封装服务相关联。传输服务描述了 QP 的可靠性程度以及传输数据的目标对象和方式。
五种 IBA 传输服务类型包括:
非 IBA 协议封装服务包括:
第 1246 页的表 383“通道适配器属性”列出了主机通道适配器和目标通道适配器所需的服务。表 38:下面的“OpCode”字段比较了这五种传输服务类型的几个关键属性。可靠传输服务使用序列号和确认消息 (ACK/NAK) 的组合来验证数据包的传送顺序,防止处理重复的数据包和乱序的数据包,并检测丢失的数据包。一旦检测到错误(例如丢失的数据包),请求者将重新传输丢失的数据包以及所有后续数据包。IBA 不支持选择性数据包重传,也不支持乱序接收数据包。IBA 操作被定义为包含一个请求消息,对于可靠服务,还包括其相应的响应。因此,请求消息由请求者生成,响应(如果存在)由响应者生成。
请求消息由一个或多个 IBA 数据包组成。请求消息的数据包称为请求数据包。响应(RDMA READ 响应除外)仅由一个数据包组成。响应也称为确认。响应数据包确认已收到一个或多个数据包。响应可以确认已收到包含从请求消息的一部分到多个请求消息的数据包。不可靠传输服务不使用确认消息。但它们会生成序列号。这允许响应者检测乱序或丢失的数据包并执行本地恢复处理。不可靠数据报的任何恢复处理细节均超出了 IBA 规范的范围(理解为: 不可靠类型暂不支持错误恢复)。
IBA 传输服务类型比较
基本传输头 (BTH) 包含所有 IBA 传输服务中始终存在的字段 - 原始数据包中不存在该字段(Raw packets)。BTH 的存在由链路下一头 (LRH:LNH) 字段指示(Link Next Header (LRH:LNH) field)。原始数据包不使用 IBA 传输服务,因此原始数据包无需基本传输头。C9-1:所有 IBA 传输服务都应包含基本传输头。
OpCode 字段定义了剩余报头和有效载荷字节的解释。OpCode 列表定义如第 261 页的表 38 OpCode 字段所示。如果 Opcode 字段设置为 GET 扩展操作或 PUT 扩展操作,则扩展 OpCode 报头及其后的报头和有效载荷由该报头中的扩展 OpCode 字段定义。C9-2:表 38:OpCode 字段应用于定义 BTH 中的 OpCode 参数以及 BTH 之后的报头和有效载荷。o9-0.2.1:此合规声明已被删除,因为它已被 C9-2 覆盖。
为了未来扩展其传输层,IBA 提供了保留的和制造商定义的 BTH 操作码。除非明确标识设备支持制造商定义的操作码,否则不应在设备之间使用制造商定义的操作码。
9.2.3 请求事件 (SE) - 1 位 请求方将此位设置为 1,表示响应方应调用 CQ 事件处理程序。其他操作指南:
• SE 位应仅在 SEND、立即发送 SEND 或立即 RDMA 写入的最后一个或唯一一个数据包中设置。
• 有关影响 HCA 的其他操作指南,请参阅第 689 页上的第 11.4.2.2 节“请求完成通知”。
SE 位不被视为数据包头验证的一部分,即,如果收到设置了此位但不符合调用要求的数据包,则不会导致生成 NAK。
C9-3:对于 HCA,如果传入请求数据包的 BTH 中的请求事件位设置为 1,并且其他 SE 操作指南有效,则它将调用 CQ 事件处理程序。 o9-1:对于支持请求事件的 TCA,如果入站请求数据包的 BTH 中的请求事件位设置为 1,并且附加 SE 操作指南有效,则它应调用 CQ 事件处理程序。
C9-4:响应方不应考虑数据包头验证的 BTH 部分中的 SE 位。除了在 SEND、立即发送或立即写入 RDMA 操作中使用外,还可以使用带有 Invalidate 操作的 SEND 来设置 SE 位。在这种情况下,SE 位应仅在带有 Invalidate 的 SEND 的最后一个或唯一一个数据包中设置。在所有其他方面,SE 位的使用遵循与正常 SEND 操作中使用 SE 位相同的规则
9.2.4 MIGREQ (M) - 1 位
用于传达迁移状态。如果设置为 1,表示连接或 EE 上下文已迁移;如果设置为 0,表示当前迁移状态没有变化。请参阅第 17 章:通道适配器(第 1239 页)中的“自动路径迁移”。
9.2.5 填充字节数 (PADCNT) - 2 位
数据包有效载荷以 4 字节数量的倍数发送。填充字节数表示附加到数据包有效载荷的填充字节数 - 0 到 3。填充字节用于将有效载荷(有效载荷的长度可以为零个或多个字节)“拉伸”为 4 字节的倍数。
9.2.6 传输头版本 (TVER) - 4 位
指定用于此数据包的 IBA 传输的版本。此版本适用于所有传输字段,包括 BTH、扩展报头和不变 CRC - 此字段设置为 0x0。如果接收方不支持指定的传输版本,则丢弃数据包。
C9-5:使用 IBA 传输的请求方和响应方应生成 BTH:TVer = 0x0 的 IBA 传输数据包。
9.2.7 分区键 (P_KEY) - 16 位
P_Key 标识目标 QP (RC、UC、UD、XRC) 或 EE 上下文 (RD) 所属的分区。
9.2.8 目标 QP (DESTQP) - 24 位
此字段指定目标队列对 (QP) 标识符。
9.2.9 FECN/RES1 (F/RES1) - 1 位
F (FECN):0 表示未收到 FECN 指示。1 表示数据包经过拥塞点。 Res1:传输为 0,接收时忽略。此字段不包含在不变 CRC 中。
9.2.10 BECN/RES1(B/RES1)- 1 位
B(BECN):0 表示数据包未经过拥塞点,或者经过拥塞点但未标记。1 表示此报头指示的数据包受到前向拥塞。B 位在 ACK 或 CN BTH 中设置。Res1:传输为 0,接收时忽略。此字段不包含在不变 CRC 中。
9.2.11 保留 6(RESV6)- 6 位保留(可变(variant))- 6 位。传输为 0,接收时忽略。此字段不包含在不变 CRC 中。C9-6:生成数据包时,发送方应将 Resv6、F/Res1 和 B/Res1 字段设置为零。通常,接收方应忽略保留字段。
9.2.12 ACKREQ (A) - 1 位 请求响应方在相关 QP 上安排确认。
9.2.13 保留 7 (RESV7) - 7 位 传输为 0,接收时忽略。此字段包含在不变 CRC C9-7 中:生成数据包时,发送方应将 Resv7 字段设置为零。接收方应忽略此字段。
9.2.14 数据包序列号 (PSN) - 24 位 此字段用于标识数据包在数据包序列中的位置。所有 IBA 请求方都应按照第 322 页 9.7.3.1 请求方 - 生成 PSN 中的规定生成 PSN。根据传输服务类型和/或实施要求,响应方可以验证 PSN 以检测丢失的数据包
9.3.1 可靠数据报扩展传输报头 (RDETH) - 4 字节 可靠数据报扩展传输报头 (RDETH) 包含端到端上下文标识符。
9.3.1.1 保留 - 8 位 o9-2:如果 CA 实现可靠数据报功能,则在生成数据包时,发送方应将此字段设置为 0x0。接收方应忽略此字段。9.3.1.2 端到端 (EE) 上下文 - 24 位此字段指示用于此数据包的端到端 (EE) 上下文。EE 上下文是一个唯一的端节点标识符,用于在任意两个端节点之间复用/解复用可靠数据报数据包。EE 上下文为可靠传输状态提供上下文,类似于用于可靠连接的上下文。
9.3.2 数据报扩展传输头 (DETH) - 8 字节数据报扩展传输头 (DETH) 包含用于可靠和不可靠数据报服务的附加传输字段
9.3.2.1 Q_KEY - 32 位 此字段用于授权访问目标队列。响应方将此字段与目标的 QP Q_Key 进行比较。
9.3.2.2 保留 - 8 位 C9-8:生成数据包时,发送方应将此字段设置为 0x0。接收方应忽略此字段。
9.3.2.3 源 QP (SRCQP) - 24 位 此字段指定源队列对 (QP) 标识符。这用作响应数据包的目标 QP。
9.3.3 RDMA 扩展传输头 (RETH) - 16 字节 RDMA 扩展传输头 (RETH) 包含用于 RDMA 操作的附加传输字段
9.3.3.1 虚拟地址 (VA) - 64 位缓冲区的起始地址。RDMA VA 可以从任何字节边界开始。
9.3.3.2 R_KEY - 32 位 R_Key 具有以下属性:
• R_Key 充当保护密钥,用于访问给定操作的指定内存地址和范围,即,它是一种保护机制,用于确保正确访问目标内存。响应者将 R_Key 与本地保护机制关联,以验证请求者的访问权限。
• 必须将 R_Key 导出给请求者 - 此过程(还包括导出起始虚拟地址和内存大小,即长度)超出了本节的范围。
• 对 RDMA READ、RDMA WRITE 和 ATOMIC 的任意组合授予访问权限 - 包括无和全部(none and all)。
• 每个内存区域或窗口在任何给定时刻都有一个有效的 R_Key。几乎连续的内存位置范围可以同时关联多个区域或窗口,每个区域或窗口都有一个关联的 R_Key。
• 一个 R_Key 可以导出到多个远程响应器。
• R_Key 仅用于 RDMA 和 ATOMIC 操作。R_Key 包含在数据包头中。
支持 RDMA 和/或 ATOMIC 操作的响应器应验证 R_Key、关联的访问权限和指定的虚拟地址。响应器还必须执行边界检查(即验证所引用数据的长度不跨越关联的内存起始和结束地址)。任何违规都会导致数据包被丢弃,并且对于可靠服务,还会生成 NAK
9.3.3.3 DMA 长度 (DMALEN) - 32 位 此字段指示远程 DMA 操作的长度(以字节为单位)。C9-9:对于执行 RDMA 操作的 HCA,DMALen 字段中指定的最小长度为 0;最大长度为 2的31次方(2G)。o9-3:如果 TCA 实现 RDMA 功能,则 DMALen 字段中指定的最小长度为 0;最大长度为 2的31次方。
9.3.4 原子扩展传输头 (ATOMICETH) - 28 字节 原子扩展传输头 (AtomicETH) 包含用于原子请求操作的附加传输字段
9.3.4.1 虚拟地址 (VA) - 64 位 缓冲区的起始地址。
9.3.4.2 R_KEY - 32 位 R_Key 用于验证对指定虚拟地址的远程访问。请参阅第 268 页上的 9.3.3.2 R_Key - 32 位。
9.3.4.3 交换(添加)数据 (SWAPDT) - 64 位 原子操作中使用的数据操作数。在 CmpSwap 操作中,如果 CmpDt 与现有缓冲区内容匹配,则此字段将交换到寻址缓冲区中。在 FetchAdd 操作中,此字段将添加到寻址缓冲区的内容中。
9.3.4.4 比较数据 (CMPDT) - 64 位 CmpSwap 原子操作的比较部分中使用的数据操作数。
9.3.5 ACK扩展传输头(AETH)- 4字节 ACK扩展传输头(AETH)包含ACK数据包的附加传输字段。所有ACK以及RDMA READ响应消息的第一个和最后一个数据包中都包含ACK扩展传输头。
9.3.5.1 综合征(SYNDROME)此字段指示这是 ACK 还是 NAK。如果数据包是 ACK,并且 QP 与可靠连接传输服务相关联,则综合征还会提供限制序列号 (LSN) - 请参阅第 380 页上的 9.7.7.2 端到端(消息级别)流量控制。如果数据包是 NAK,则它指示错误代码。对于 RNR NAK,此字段指示在重新传输请求之前响应方请求使用的计时器。
9.3.5.2 消息序列号 (MSN) 响应方完成的最后一条消息的序列号。此字段用于优化请求方的完成处理。
9.3.5.3 原子确认扩展传输头 (ATOMICACKETH) - 8 字节原子确认扩展传输头 (AtomicETH) 包含用于原子响应操作的附加传输字段。
9.3.5.4 原始远程数据 (ORIG REM DT) - 64 位 原子操作的结果数据。这是从远程内存缓冲区读取的初始内容。
9.3.6 立即扩展传输头 (IMMDT) - 4 字节 立即数据 (ImmDt) 包含放置在接收完成队列元素 (CQE) 中的数据。ImmDt 仅允许在包含立即数据的 SEND 或 RDMA WRITE 数据包中使用。
9.3.7 无效扩展传输报头 (IETH) - 4 字节 带无效功能的 SEND 操作带有一个 R_Key 字段。响应方在收到并执行带无效功能的 SEND 请求后,将使用此 R_Key 来使内存区域或内存窗口无效。R_Key 包含在一个名为“无效扩展传输报头 (IETH)”的新扩展传输报头中,如下所示
9.3.7.1 R_KEY - 32 位 R_Key 定义响应者要使其无效的内存区域或内存窗口。
9.3.8 XRC 扩展传输报头(XRCETH) XRC 扩展传输报头(XRCETH)包含目标 XRC SRQ 标识符 o9-3.a1:如果 CA 实现 XRC 传输服务,则在生成请求数据包时,发送者应按如下所述设置 XRCETH 字段
9.3.8.1 保留 - 8 位 生成数据包时,发送方应将此字段设置为 0x0。接收方应忽略此字段。
9.3.8.2 XRCSRQ - 24 位 此字段指示响应方将用于此数据包的 XRC 共享接收队列号。
9.3.9 扩展操作码 扩展传输报头 (EOETH) 扩展操作码报头包含 GET 和 PUT 类型的扩展操作码传输处理所需的字段。
9.3.9.1 保留 - 16 位 发送方在生成数据包时应将此字段设置为 0x0。接收方应忽略此字段。
9.3.9.2 扩展操作码 - 16 位 扩展操作码字段定义了剩余报头和有效载荷字节的解释。
9.3.9.3 响应数据长度 - 32 位响应数据长度定义 GET 扩展操作码的返回值的字节长度。
9.3.9.4 偏移量 - 32 位偏移量定义对于大于单个 MTU 的请求(该字段由传输层使用),已执行请求部分的字节长度。
QP 为传输层的客户端(例如 HCA 中的 verbs 层)提供特定的传输服务。不同的传输服务针对连接和无连接通信具有不同的可靠性级别。本节介绍每种传输服务使用的基本功能。其他传输部分将更深入地介绍响应数据包、排序、错误恢复等细节。本节提供这些功能的高级视图及其工作原理。并非所有功能都适用于每种传输服务,如下表 41(第 274 页)中所述。
传输服务类型与传输方法支持矩阵:
SEND 操作有时被称为推送操作(PUSH)或具有通道语义。这两个术语指的是传输服务的软件客户端如何看待数据的移动。通过 SEND 操作,数据传输的发起者将数据推送到远程 QP。发起者并不知道数据在远程节点上的去向。远程节点的通道适配器将数据放入该 QP 的下一个可用接收缓冲区中。在 HCA 上,接收缓冲区由 QP 接收队列头部的 WQE 指向。SEND 操作被称为具有通道语义,因为它移动数据的方式与大型机 IO 通道非常相似——数据带有鉴别符标记(tagged)(对于 IBA,鉴别符是目标 LID 和 QP 编号),目标根据鉴别符选择数据的位置。SEND 操作移动单条消息。对于 RC、RD、UC 和 XRC 传输服务,此消息可能比单个数据包更长。消息大小范围从零字节到 2的31次方字节(2G)
C9-10:请求者生成的 SEND 操作的大小应在零到 2的31次方字节之间(含)。
C9-11:对于 HCA 中的 RC 和 UC 传输服务,长度大于 PMTU 的请求消息应分段为 PMTU 大小的段,以便通过多个数据包传输。同样,HCA 响应者应将这些数据包重新组合成单个消息。
o9-4:对于 HCA 中的 RD 和 XRC 传输服务,长度大于 PMTU 的请求消息应分段为 PMTU 大小的段,以便通过多个数据包传输。同样,HCA 响应者应将这些数据包重新组合成单个消息。
o9-5:对于 TCA 中的 RC、UC、RD 和 XRC 传输服务,长度大于 PMTU 的请求消息应分段为 PMTU 大小的段,以便通过多个数据包传输。同样,TCA 响应者应将这些数据包重新组合成单个消息。
C9-12:对于不可靠数据报传输服务,SEND 操作应仅包含单数据包消息(即,消息数据有效载荷限制为请求方和响应方之间的最大 PMTU,即 256、512、1024、2048 或 4096 字节)。
SEND 操作可由客户端自行决定在每条发送消息中包含 4 个字节的立即数据。如果包含,则立即数据将包含在 SEND 操作最后一个数据包的附加报头字段(立即扩展传输报头或 ImmDt)中。例如,下图 77 显示了一个 700 字节的 SEND 操作,需要 3 个 SEND 数据包(假设 PMTU 为 256 字节)。
从上图中可以看出以下几点:
• BTH OpCode 字段决定了 SEND 消息的开始和结束。
• 如果 SEND 消息小于或等于 PMTU,则使用 BTH OpCode“SEND Only”或“SEND Only with Immediate”。
• 如果 SEND 消息的长度为零,则使用 BTH OpCode“SEND Only”或“SEND Only with Immediate”。在这种情况下,没有数据有效载荷字段,但所有其他字段都如图所示。
• 如果 SEND 消息大于 PMTU,则第一个数据包的 BTH OpCode 为“SEND First”,最后一个数据包的 BTH OpCode 为“SEND Last”或“SEND Last with Immediate”。
• 如果 SEND 消息大于 PMTU 的两倍,则第一个和最后一个之间的数据包使用 BTH OpCode“SEND Middle”。
• 消息中每个不包含操作码 SEND Only、SEND Only with Immediate、SEND Last 或 SEND Last with Immediate 的数据包都应具有 PMTU 长度的数据字段。
• 响应者节点(SEND 操作的目的地)直到最后一个包含“SEND Last”或“SEND Last with Immediate”操作码的数据包到达时才知道 SEND 消息的最终长度。
• 响应者使用数据包序列号字段检测无序或丢失的数据包。
• 如果整个消息不是 PMTU 的倍数,则消息的初始数据包携带完整的 PMTU 字节数,最后一个数据包携带剩余部分作为部分有效载荷。
• 对于给定请求节点的 QP,一旦启动多数据包 SEND 操作,在“SEND Last”或“SEND Last with Immediate”数据包之前,不能生成任何其他请求数据包。
C9-13:多数据包消息不得与同一 SEND 队列上的其他操作交错。
• 并非所有 SEND 消息都携带立即数据。如果携带立即数据,则在消息的最后一个或唯一一个数据包中会包含一个特殊报头。报头的存在由 BTH 中的特殊操作码“SEND Last with Immediate Data”或“SEND Only with Immediate Data”指示。
• 对于 HCA,SEND 消息的源缓冲区或目标缓冲区没有对齐要求。对于 TCA 内的缓冲区,任何对齐要求都取决于具体实现。
verbs动词章节解释了 HCA 的上层软件客户端如何使用工作请求发送缓冲区,该缓冲区随后被分段并以数据包的形式在结构中发送。同一章节还描述了目标节点如何发送接收缓冲区,目标 HCA 将数据重新组装到该缓冲区中。由 TCA 发起的 SEND 消息使用特定于具体实现的机制来创建(并响应)SEND 数据包。
C9-14:在为 SEND 操作生成数据包时,请求者应在请求的每个数据包中至少包含以下报头和字段:LRH、BTH、ICRC 和 VCRC。
C9-15:在生成对 SEND 操作的响应时,响应者应至少包含以下标头和字段:LRH、BTH、AETH、ICRC、VCRC
在大多数方面,带有 Invalidate 的 SEND 操作与正常 SEND 操作完全相同。显著的区别是消息的最后一个(或唯一一个)数据包在 IETH(无效扩展传输头)中携带一个 R_KEY。这是响应方被要求使之无效的 R_KEY。实际上,Invalidate 功能被搭载在正常 SEND 操作上。关于带有 Invalidate 的 SEND 相对于正常 SEND 操作有几点需要注意。以下所有陈述都假设 Invalidate 操作被搭载在“正常”SEND 操作上。
• 如果搭载了无效操作的 SEND 消息小于或等于 PMTU,则使用 BTH OpCode“仅使用 Invalidate 发送”。
• 如果搭载了无效操作的 SEND 消息长度为零,则使用 BTH OpCode“仅使用 Invalidate 发送”。在这种情况下,没有数据有效负载字段,但所有其他字段都如所示。
• 如果搭载了无效操作的 SEND 消息大于 PMTU,则第一个数据包的 BTH OpCode 为“SEND First”,最后一个数据包的 BTH OpCode 为“SEND Last with Invalidate”。该消息所有其他数据包的 BTH OpCode 为“SEND Middle”。
• SEND 消息中每个不包含操作码“SEND Only”、“SEND Only with Immediate”、“SEND Only with Invalidate”、“SEND Last”、“SEND Last with Immediate”或“SEND Last with Invalidate”的数据包都应具有 PMTU 长度的数据字段。
• 响应者节点(SEND 操作的目的地)在最后一个包含“SEND Last with Invalidate” OpCode 的数据包到达之前,不知道搭载了无效操作的 SEND 消息的最终长度。
• 对于给定请求节点的 QP,一旦启动多数据包 SEND 操作,在生成“SEND Last”、“SEND Last with Immediate”或“SEND Last with Invalidate”数据包之前,不得生成任何其他请求数据包。
远程无效操作用于禁用通过 IETH 中包含的 R_Key 访问内存。但是,无效操作会保留与被无效的 R_Key 关联的内存转换和保护资源。带有无效的 SEND 操作不会禁用对 R_Key 引用的内存的所有访问,它只是意味着被无效的 R_Key 无法再用于访问这些内存区域或内存窗口。引用同一内存的其他 R_Key 仍然有效。目的是让无效操作由通道接口执行,该接口可能包括动词下方的硬件和软件驱动程序。因此,无效操作可以由传输层硬件正上方的软件驱动程序执行。在这种情况下,传输层硬件只需将 IETH 向上传递到通道接口的软件部分,该部分将执行必要的失效操作。因此,IETH 不会作为正常传输数据包头验证的一部分进行验证。失效操作不会对引用内存的状态进行任何更改。
o9-5.2.1:对于任何支持带 Invalidate 功能的 SEND 操作的 HCA,在收到 IETH 后,Invalidate 操作必须在正常传输头验证检查成功完成后才能执行。如果包含 IETH 的数据包(例如,带 Invalidate 功能的 SEND 操作)不是正常数据包验证程序所描述的有效数据包,则不得发生 Invalidate 操作。但是,由于 Invalidate 操作并非由传输层执行,因此 Invalidate 操作可以在传输层确认生成之前或之后执行,但无论如何,传输层确认 (ACK/NAK) 均不反映 Invalidate 操作的成功或失败。以下定义了带 Invalidate 功能的 SEND 操作的顺序规则:
传输层在传输层数据包头验证期间不会验证 IETH 的 R_Key 字段。通道接口负责在执行失效操作之前验证 IETH 的 R_Key 字段。因此,IETH 不被视为传输头,因此本节不讨论远程失效操作的 R_Key 验证。有关验证 IETH R_Key 字段的说明,请参阅第 280 页上的“9.4.1.1.3 远程内存失效的 R_Key 验证”。
o9-5.2.2:对于支持远程无效操作的 CA,在执行远程无效操作之前,必须验证 IETH 中包含的 R_Key。要使其有效,必须满足以下所有条件:1) R_Key 不得处于无效状态。2) 如果实现支持 L_Key 和 R_Key 使用单个密钥空间,则 IETH 中包含的 R_Key 不得与保留的 L_Key 相同。3) 对于 HCA,R_Key 不得引用通过注册内存区域或重新注册内存区域创建的内存区域。4) 对于 HCA,R_Key 不得引用共享内存区域。5) 对于 HCA,R_Key 不得引用与接收 IETH 的 QP 不同的保护域关联的内存区域。 6) 对于 HCA,R_Key 不能引用 1 型内存窗口。有关 1 型内存窗口的描述,请参阅第 536 页上的第 10.6.7.2.3 节“1 型内存窗口”。7) 对于 HCA,R_Key 不能同时处于有效状态并引用与接收 IETH 的 QP 不同的 QP 关联的 2A 型内存窗口。有关 2 型内存窗口的描述,请参阅第 538 页上的第 10.6.7.2.4 节“2 型内存窗口”。8) 对于 HCA,R_Key 不能同时处于有效状态并引用与接收 IETH 的 QP 不同的保护域或 QP 关联的 2B 型内存窗口。有关 2 型内存窗口的描述,请参阅第 538 页上的第 10.6.7.2.4 节“2 型内存窗口”。 9) 对于 HCA,R_Key 不能同时处于自由状态并引用与接收 IETH 的 QP 的保护域不同的保护域关联的 2 型内存窗口。有关 2 型内存窗口的描述,请参见第 538 页上的第 10.6.7.2.4 节“2 型内存窗口”。
注意:如果 L_Key 及其伴随的 R_Key 处于自由状态,则远程无效操作不会更改 L_Key 及其伴随的 R_Key 状态。如果 R_Key 验证(如上文合规性声明 o9-5.2.2 中定义)失败,则 QP 的行为在“表 63 响应者错误行为摘要”(第 445 页)的“远程无效错误”条目下定义。
RESYNC 操作仅支持可靠数据报传输服务。RESYNC 本质上与零长度可靠数据报仅发送请求相同,但具有以下几个独特属性:1) 请求方使用 RESYNC 强制响应方将其预期 PSN 重置为请求方定义的值;2) RESYNC 请求携带零长度的数据有效载荷;3) 即使当前正在执行的请求尚未完成,响应方也必须接受 RESYNC 请求。4) RESYNC 请求本身不会直接消耗请求方的发送 WQE,也不会消耗响应方的接收 WQE。C9-15.a1:RESYNC 请求应携带零长度的数据有效载荷。
请求节点使用 RDMA 写操作将数据写入目标节点的虚拟地址空间。消息长度可以在 0 到 2的31次方字节(含)之间,并写入目标 QP 虚拟地址空间的连续范围(不一定是连续的物理内存范围)。C9-16:对于执行 RDMA 写操作的 HCA 请求者,RETH:DMALen 字段中反映的 RDMA 写消息的长度应在 0 到 2的31次方字节(含)之间。o9-6:如果 TCA 请求者实现了 RDMA 写功能,RETH:DMALen 字段中反映的 RDMA 写消息的长度应在 0 到 2的31次方字节(含)之间。在允许传入的 RDMA 写操作之前,目标节点首先分配一个内存范围供目标 QP(或一组 QP)访问。目标的通道适配器将一个 32 位 R_Key 与此内存区域或窗口关联。对于 HCA,动词层将此称为注册内存区域 - 请参阅第 510 页上的 10.6 节“内存管理”。TCA 使用特定于实现的机制来分配和管理 R_Key,这超出了 IBA 规范的范围。目标将虚拟地址、长度和 R_Key 传达给它希望访问该内存区域的任何其他主机。地址和 R_Key 的通信由客户端上层协议完成 - 交换超出了 IBA 的范围。例如,应用程序可以将地址、长度和 R_Key 嵌入到私有数据结构中,然后使用 SEND 操作将其推送给其他应用程序。C9-17:与 SEND 操作一样,HCA 请求者应将大于 PMTU 的 RDMA WRITE 消息拆分成多个数据包。 o9-7:如果 TCA 请求方实现了 RDMA WRITE 功能,则应将大于 PMTU 的 RDMA WRITE 消息拆分成多个数据包。如果 verbs 层指定,则立即数据将包含在 RDMA WRITE 消息的最后一个数据包中。立即数据不会写入目标虚拟地址范围,而是在最后一个 RDMA WRITE 数据包成功处理后传递给客户端。例如,在 HCA 上,立即数据被放置在完成队列中。例如,下图 78 显示了 700 字节的 RDMA WRITE 操作(在具有 256B PMTU 的路径上)。
从上图中可以看出以下几点:
• BTH OpCode 字段决定了 RDMA WRITE 消息的开始和结束。
• 如果 RDMA WRITE 请求的长度为零,则使用 BTH OpCode“RDMA WRITE Only”或“RDMA WRITE Only with Immediate”。在这种情况下,没有数据有效负载字段,但所有其他字段都如图所示。
• 如果 RDMA WRITE 消息小于或等于 PMTU,则使用 BTH OpCode“RDMA WRITE Only”或“RDMA WRITE Only with Immediate”。
• 如果 RDMA WRITE 消息大于 PMTU,则第一个数据包的 BTH OpCode 为“RDMA WRITE First”,最后一个数据包的 BTH OpCode 为“RDMA WRITE Last”或“RDMA WRITE Last with Immediate”。
• 如果 RDMA WRITE 消息大于 PMTU 的两倍,则第一个和最后一个之间的数据包使用 BTH OpCode“RDMA WRITE Middle”。
• RDMA WRITE 消息中没有操作码 RDMA WRITE Only、RDMA WRITE Only with Immediate、RDMA WRITE Last 或 RDMA WRITE Last with Immediate 的每个数据包都具有 PMTU 长度的数据字段。
• RETH 标头存在于消息的第一个(或唯一一个)数据包中。它包含目标缓冲区的虚拟地址以及 R_Key 和消息长度字段。
• 响应方使用数据包序列号字段来检测乱序或丢失的数据包。
• 如果整个消息不是 PMTU 的倍数,则消息的初始数据包携带完整的 PMTU 字节数,最后一个数据包携带部分有效载荷中的剩余部分。
• 对于给定请求节点的 QP,一旦启动多数据包 RDMA WRITE 操作,在发送“RDMA Last”或“RDMA Last with Immediate Data”数据包之前,不得生成任何其他请求数据包。
C9-18:对于 HCA RDMA WRITE 请求,多数据包消息不得与同一 SEND 队列上的其他操作交错。o9-8:如果 TCA 请求者实现了 RDMA WRITE 功能,则对于 RDMA WRITE 请求,多数据包消息不得与同一 SEND 队列上的其他操作交错。
• 并非所有 RDMA WRITE 消息都携带立即数据。如果 RDMA WRITE 携带立即数据,则消息的最后一个(或唯一一个)数据包中包含一个特殊标头。标头的存在由 BTH 中的特殊“RDMA WRITE Last with Immediate Data”或“RDMA WRITE Only with Immediate Data”操作码指示。
• 对于 HCA,RDMA WRITE 消息的源缓冲区或目标缓冲区没有对齐要求。对于 TCA 内的缓冲区,任何对齐要求都是特定于实现的。
C9-19:生成 RDMA WRITE 请求时,HCA 请求者应在每个请求数据包中至少包含以下标头和字段:LRH、BTH、数据有效负载、ICRC、VCRC。请求的第一个(或唯一)数据包还应包含 RETH。o9-9:如果 TCA 请求者实现了 RDMA WRITE 功能,则其行为如下。生成 RDMA WRITE 请求时,TCA 请求者应在每个请求数据包中至少包含以下标头和字段:LRH、BTH、数据有效负载、ICRC、VCRC。请求的第一个(或唯一)数据包也应包括 RETH。
C9-20:生成 RDMA WRITE 响应时,HCA 响应器应在每个响应数据包中至少包括以下标头和字段:LRH、BTH、AETH、ICRC、VCRC。o9-10:如果 TCA 响应器实现 RDMA WRITE 功能,则在生成 RDMA WRITE 响应时,TCA 响应器应在每个响应数据包中至少包括以下标头和字段:LRH、BTH、AETH、ICRC、VCRC。
RDMA 读操作类似于 RDMA 写操作。它们允许请求节点读取远程节点上虚拟连续的内存块。与 RDMA 写操作一样,响应节点首先允许请求节点访问其内存。响应方将虚拟地址、长度和 R_Key 传递给请求方,以便在 RDMA 读请求数据包中使用。单个 RDMA 读请求可以读取 0 到 2的31次方字节(含)的数据。C9-21:对于响应 RDMA 读请求的 HCA,如果请求的数据大小大于 PMTU,则响应方应将数据分割成 PMTU 大小的数据段,以便作为多个 RDMA 读响应数据包进行传输。数据在请求节点的内存中重新组装。 o9-11:如果 TCA 响应方实现了 RDMA 读功能,且请求的数据大小大于 PMTU,则响应方应将数据分割成 PMTU 大小的数据段,以便作为多个 RDMA 读响应数据包传输。数据在请求节点的内存中重新组装。C9-22:对于使用 RDMA 操作的 HCA 请求方,请求的 RDMA 读数据的长度(如 RETH:DMALen 字段所示)应介于 0 到 2的31次方字节(含)之间。o9-12:如果 TCA 请求方实现了 RDMA 读功能,则请求的 RDMA 读数据的长度(如 RETH:DMALen 字段所示)应介于 0 到 2的31次方字节(含)之间。图 79 中的以下示例显示了一个 700 字节的 RDMA 读操作(在具有 256B PMTU 的路径上)。
从上图可以看出以下几点:
• 如果读取长度大于 PMTU,则单个请求数据包将导致多个读取响应数据包。
• BTH OpCode 字段标识数据包是 RDMA READ 请求还是响应,并确定是否存在任何扩展传输头。
• BTH OpCode 字段确定 RDMA READ 确认消息的开始和结束。
• 如果 RDMA READ 请求消息请求零字节传输,则使用 BTH OpCode“RDMA READ Response Only”。所有其他字段保持所示状态。
• 如果 RDMA READ 确认消息小于或等于 PMTU,则使用 BTH OpCode“RDMA READ Response Only”。
• 如果 RDMA READ 消息大于 PMTU,则第一个数据包的 BTH OpCode 为“RDMA READ Response First”,最后一个数据包的 BTH OpCode 为“RDMA READ Response Last”。
• 如果 RDMA READ 响应消息大于 PMTU 的两倍,则第一个和最后一个数据包之间的数据包使用 BTH OpCode“RDMA READ Response Middle”。
• RDMA READ Response First 或 RDMA READ Response Middle 消息中的每个数据包都具有 PMTU 长度的数据字段。
• 如果整个消息大于 PMTU 的倍数,则响应消息的初始数据包将携带完整的 PMTU 字节数,而最后一个数据包将携带部分有效载荷。
• 数据包序列号 (PSN) 字段用于检测乱序或丢失的响应数据包。
• 发起 RDMA READ 请求数据包后,请求节点可以发送其他请求数据包,而无需等待响应数据包返回。有关如何确定后续请求数据包的 PSN 的说明,请参阅第 322 页上的 9.7.3.1 节“请求方 - 生成 PSN”。
• 在建立连接时协商特定 QP 在任何时候可以待完成的 RDMA READ 请求的最大数量。响应方可以将连接限制为每个 QP 只有一个未完成的 RDMA READ 请求。如果支持 ATOMIC 操作,则在建立连接时协商的未完成请求数包括 ATOMIC 操作请求和 RDMA READ 请求。
• RDMA READ 数据包从不携带立即数据。如果请求方未收到正确的响应,则会重试 RDMA READ 请求。
• 重试的 RDMA READ 请求不需要从相同的地址开始,也不需要与原始 RDMA READ 具有相同的长度。重试的请求只能重新读取第一次未成功响应的部分。
• 响应方验证重试请求的 R_Key 和 RDMA READ 虚拟地址。
• 重试的 RDMA READ 的 PSN 必须位于重复的 PSN 区域内。请参阅第 296 页上的第 9.7.1 节“数据包序列号 (PSN)”
• 重试的 RDMA READ 请求的 PSN 不必与原始 RDMA READ 请求的 PSN 相同。任何重试请求都必须与原始 RDMA READ 请求的子集完全对应,以便所有潜在的重复响应数据包都必须具有相同的有效载荷数据和 PSN,而不管它是对原始请求的响应还是重试请求。
• 对于 HCA,RDMA READ 消息的源缓冲区或目标缓冲区没有对齐要求。对于 TCA 内的缓冲区,任何对齐要求都是特定于实现的。
C9-23:生成 RDMA READ 请求时,HCA 请求者应在其请求数据包中至少包含以下标头和字段:LRH、BTH、RETH、ICRC、VCRC。o9-13:如果 TCA 请求者实现 RDMA 操作,则它应在其请求数据包中至少包含以下标头和字段:LRH、BTH、RETH、ICRC、VCRC。 C9-24:HCA 响应器生成 RDMA READ Response 时,每个响应数据包至少应包含以下报头和字段:LRH、BTH、Data Payload、ICRC、VCRC。若响应数据包的 BTH:Opcode 为“RDMA READ Response First”、“RDMA READ Response Last”或“RDMA READ Response Only”,则数据包还应包含 AETH。若响应数据包的 BTH:Opcode 为“RDMA READ Response Middle”,则不应包含 AETH。o9-14:若 TCA 响应器执行 RDMA 操作,则每个响应数据包至少应包含以下报头和字段:LRH、BTH、Data Payload、ICRC、VCRC。如果响应数据包 BTH:Opcode 为“RDMA READ Response First”、“RDMA READ Response Last”或“RDMA READ Response Only”,则数据包还应包含 AETH。如果响应数据包 BTH:Opcode 为“RDMA READ Response Middle”,则不应包含 AETH。
原子操作在远程节点的指定地址执行 64 位操作。这些操作以原子方式读取、修改和写入目标地址,并保证同一 CA 上的其他 QP 不会在读取和写入之间对该地址执行操作。原子性保证的范围可以可选地扩展到其他 CPU 和 HCA。原子操作使用与 RDMA 读取和写入相同的远程内存寻址机制。请求数据包中指定的虚拟地址位于原子操作所针对的远程 QP 的地址空间中。原子操作包含两种数据包类型:“原子命令”请求数据包和“原子确认”响应数据包。1) 原子操作仅受可靠连接和可靠数据报传输服务支持。2) 原子操作不支持立即数据。 3) 强烈建议严格在硬件中提供 ATOMIC 操作支持。4) ATOMIC 命令请求数据包中的虚拟地址应自然对齐到 8 字节边界。响应 CA 会检查这一点,如果未自然对齐则返回无效请求 NAK。
IBA 定义了以下 ATOMIC 操作:• FetchAdd(获取和添加)FetchAdd ATOMIC 操作告知响应方读取响应方内存中自然对齐的虚拟地址处的 64 位缓冲区值,使用 AtomicETH 中的 64 位添加数据字段执行无符号添加,并将结果(必须与请求方的内存类型匹配)写回同一虚拟地址。响应方的操作应为原子操作(即不受其他实体干扰),如第 292 页上的 9.4.5.1 节原子性保证所述。FetchAdd 操作以目标内存的字节序格式执行。原始远程数据从目标内存的字节序格式转换后返回。字段在线路上采用大端格式。CA 实现可以使用软件辅助 - 这应该与纯硬件实现没有区别;性能必须确保更高级别的软件应用程序不受影响。如果使用有符号数,则与使用二进制补码算法相同(不保存也不报告进位)。请求者指定:• 远程数据地址和 R_Key • 添加数据确认包返回:• 原始远程数据操作后,响应者在指定虚拟地址的内存包含原始值与 AtomicETH 标头中的 Add 字段的无符号和。对请求者内存的所有操作均以请求者的本机字节序格式完成。 • CmpSwap(比较和交换)CmpSwap ATOMIC 操作指示响应方读取其内存中自然对齐的虚拟地址处的 64 位值,将其与 AtomicETH 头中的“比较数据”字段进行比较,如果相等,则将 AtomicETH 头中的“交换数据”字段写入相同的虚拟地址。如果相等,则不更改响应方内存中的内容。无论哪种情况,都会将从虚拟地址读取的原始值返回给请求方。响应者的操作应为原子操作(即不受其他实体干扰),如第 292 页上的 9.4.5.1 节原子性保证所述。请求者指定:• 远程数据地址和 R_Key• 写入(交换)数据• 比较数据确认包返回:• 原始远程数据操作后,远程数据缓冲区包含“原始远程值”(如果比较不匹配)或“写入(交换)数据”(如果比较匹配)。CmpSwap 操作涉及三个 8 字节数据缓冲区、比较数据、写入(交换)数据和原始远程数据。所有这三个数据都以字节大端格式在请求和响应包中传输。响应者的 CA 内存上的所有操作都以该内存系统的本机端格式完成。请求者的内存上的所有操作都以请求者的本机端格式完成。例如,假设一个大端CA向一个小端响应者发起CmpSwap原子操作请求包。该请求包包含两个大端数据字段:比较数据和写入(交换)数据。响应者将这些数据字段转换为小端格式,并进行比较和交换操作。原始目标数据字段将转换为大端格式,并在响应包中返回。
o9-15:请求方生成 ATOMIC 操作请求时,应至少包含 LRH、BTH、AtomicETH、ICRC 和 VCRC。LRH、BTH 和 AtomicETH 标头的数据源应如第 459 页表 65 数据包字段和参数(按服务)所示。o9-16:响应 ATOMIC 操作请求时,响应方应在其响应数据包中至少包含 LRH、BTH、AETH、AtomicAckETH、ICRC 和 VCRC。
o9-17:在同一 CA 上其他 QP 并发原子访问的情况下,应确保原子操作 (ATOMIC Operation) 对响应方节点的读/修改/写操作的原子性。o9-18:CA 可以选择在来自其他 CA、IO 设备和 CPU 的并发内存访问的情况下,确保原子操作的原子性。对于 HCA,Verbs 层应报告其是否支持此增强的原子性保证。
1)对于请求方,当响应数据包返回时,原子操作即视为完成。2) 如果 RDMA READ 工作请求先于 ATOMIC Operation 工作请求发出,则原子操作可以在前一个 RDMA READ 读取其数据之前执行其远程内存操作。发生这种情况的原因是允许响应者延迟执行 RDMA READ。可以通过使用栅栏修饰符发布 ATOMIC 操作工作请求来确保严格的顺序。请参阅栅栏修饰符(fence) Post Send Request 的说明。栅栏修饰符使请求者等到 RDMA READ 完成后再发出 ATOMIC 操作。3) 当一系列请求到达 QP 时,ATOMIC 操作仅在先前(非 RDMA READ)请求访问内存之后以及后续请求访问内存之前访问内存。由于响应者需要时间来发出对原子请求的响应,并且该响应需要更多时间才能到达请求者,甚至需要更多时间让请求者创建完成队列条目,因此原子操作之后的请求可能会在请求者为 ATOMIC 操作请求写入完成队列条目之前访问响应者的内存。4) 每个 ATOMIC 操作请求都需要明确的响应和确认消息。具有正确格式的 AETH 的 ATOMIC 操作响应被视为确认消息。
响应方利用特定于供应商的资源和设施来实现原子操作 (ATOMIC) 和 RDMA 读取 (RDMA READ),并促进重试原子操作 (ATOMIC)。请求方有责任确保所有未确认的原子操作和 RDMA 读取 (RDMA READ) 加起来不会超出接收方的资源。这些资源的数量是在连接建立时根据每个 QP 协商的(参见第 285 页的 9.4.4 RDMA 读取操作和第 289 页的 9.4.5 原子操作)。响应节点保存回复数据、PSN 以及指示存储数据来自原子操作的指示。这些保存的数据用于生成重试原子操作的响应。需要注意的是,执行 RDMA 读取操作可能消耗与保存原子操作 PSN 和回复数据相同的资源。这些信息存储在目标 QP 的“连接上下文”中。对于可靠连接服务 (RCO),“连接上下文”指的是 QP 上下文。对于可靠数据报服务 (RDO),“连接上下文”实际上是“EE 上下文”。以下规则决定了响应方何时存储原子操作 (ATOMIC Operation) 的 PSN 和回复数据:• 仅保存有效的、新的原子操作 (ATOMIC Operation) 请求(即所有标头检查均有效、传入的 PSN 与预期的 PSN 匹配、R_Key 对正在访问的数据有效且地址与 64 位边界对齐)。• 如果响应方 QP 支持多个未完成的原子操作 (ATOMIC Operation) 和 RDMA 读操作 (RDMA READ Operation),则每个有效请求的信息将按 FIFO 顺序保存。FIFO 深度与连接建立时每个 QP 协商的最大未完成原子操作 (ATOMIC Operation) 和 RDMA 读请求数相同。• 重复的原子操作 (ATOMIC) 或 RDMA 读操作不会再次保存。保存的原子操作 (ATOMIC) 和 RDMA 读操作状态如下图所示。
a. 对于可靠连接服务 (RDS),用于跟踪最新 ATOMIC 和 RDMA 读操作的状态位保存在每个 QP 状态中。对于可靠数据报服务 (RDS),这些状态位保存在 EE 上下文中,而不是每个 QP 状态中。 梯形图显示了多个 ATOMIC 和 RDMA 读请求。在此示例中,响应方的 QP 在连接建立时已同意,它可以接受最多 2 个未完成的 ATOMIC 或 RDMA 读操作的任意组合。此示例展示了响应方如何维护最近的 ATOMIC 和 RDMA 读操作的状态。另请注意,在此示例中,如果 RDMA 读操作先于 ATOMIC 操作执行,但目标地址相同,则可能在 ATOMIC 操作执行后返回值。在 HCA 中,通过在 RDMA 读操作后发布 ATOMIC 操作时使用“fence”选项,可以实现严格的排序。请参阅第 672 页上的 11.4.1.1 发布发送请求。
ATOMIC 操作保证最多执行一次。如果 ATOMIC 操作未在目标端执行,则会将其报告给发送端(例如,R_Key 保护故障),并附带相应的 NAK 综合征响应。但是,与所有操作一样,在响应端执行之后、响应到达请求端之前发生的不可恢复错误(例如,致命的 HCA 错误)会导致请求端无法获知响应端内存的状态。这种情况必须由客户端或上层协议检测和处理。与所有操作一样,任何传输都可能发生错误。如果原始“ATOMIC 命令”请求丢失,或“ATOMIC 确认”丢失,发送端将使用常规重试程序进行重试。如果重试失败,则无法确定 ATOMIC 操作是否在目标端执行,但连接将处于错误状态。与重试发送和 RDMA 写操作一样,如果响应 CA 实际上已执行请求,它将仅再次确认请求,而不会重新运行 ATOMIC 操作。这是必要的,因为 ATOMIC 操作不是幂等的。响应者识别重试的 ATOMIC 操作并返回先前存储在 QP(或可靠数据报服务的 EE 上下文)“隐藏状态”中的原始确认的回复数据。如果满足以下条件,响应者将返回存储的 ATOMIC 操作结果:• 请求有效(即标头和 OpCode 有效)• 请求用于 ATOMIC 操作(响应者可能会检查 ATOMIC 操作 OpCode 是否与存储的操作相同)• 请求的 PSN 位于“重复区域”。请参阅第 314 页上第 9.7.1 节“数据包序列号 (PSN)”中有关 PSN 空间的描述。• PSN 与已保存的 ATOMIC 操作的 PSN 匹配。如果重试的 ATOMIC 操作不满足上述条件,则会被响应方丢弃。请参阅第 445 页上的表 63“响应方错误行为摘要”。重试 ATOMIC 操作时,响应方不会验证 R_Key,也不会转换重试请求中的虚拟地址。下图演示了一个失败的 ATOMIC 操作响应数据包,并显示了重试的请求和最终成功的响应。
a. 对于可靠连接服务,用于跟踪最新原子读操作和 RDMA 读操作的状态位保存在每个 QP 状态中。对于可靠数据报服务,这些状态位保存在 EE 上下文中,而不是每个 QP 状态中。 梯形图显示了多个原子读操作和 RDMA 读操作。在此示例中,响应方的 QP 在连接建立时已同意,它可以接受最多 2 个未完成的原子读操作或 RDMA 读操作的任意组合。此示例显示了一个丢失的原子读确认(在时间 2)。重试请求时,将返回原始结果值。即使来自相同或不同 QP 的后续操作修改了原子读操作的目标,也会返回原始值。
如果所有重试都失败,则意味着连接已断开,请求 CA 驱动程序中的错误恢复例程将通知本地应用程序。操作的大小始终为 64 位。目标必须自然对齐(虚拟地址的低 3 位必须为零)。如果 R_Key 范围未完全包含目标,则会报告错误。如果发生此错误或其他保护错误,则会报告错误 (NAK_Remote_Access),但不会导致占用任何“原子操作隐藏队列”资源。也就是说,如果重复相同的请求(相同的 PSN),并且响应方随后分配了 R_Key 范围,则此新操作现在将成功。
IBA 有两种机制用于未来扩展其传输层:• 保留和制造商定义的 BTH 操作码。可以通过定义新的 BTH 操作码来扩展 IBA 传输层功能。指定了两块未定义的操作码。一块用于 IBA 的未来修订,另一块用于制造商特定的功能。
功能类是一组具有相似特征的传输操作。功能类定义了该类中任何传输操作所需的任何请求和响应的报头格式。
获取类操作类似于 RDMA 读取操作。它们允许请求节点向响应节点请求数据。获取类操作是通用操作,它们的共同点是它们都涉及响应方发送一个或多个读取响应数据包。生成响应有效载荷的方法因扩展 GET 操作码而异。每个扩展 GET 操作码都定义了哪些附加标头将跟在 EOETH 之后。Get 类操作最多可以在请求数据包中传递 256 字节的有效载荷。单个 RDMA GET 操作可以读取 0 到 2的31次方字节(含)的数据。
梯形图显示了请求者节点发起的单个“获取类操作请求包”。在本例中,目标节点将数据分割成三个响应
PUT 类操作是用于将数据从请求方节点传递到响应方节点的通用操作。远程节点上数据的放置位置特定于每个扩展的 PUT 操作码。每个扩展的操作码定义了哪些附加标头将跟在 EOETH 之后。消息长度可以在 0 到 2的31次方个字节之间(含)
本节定义了给定队列P (QP) 的事务传输、执行和完成的排序规则:C9-25:请求方应按照工作队列元素 (WQE) 的发布顺序传输请求消息。C9-26:对于分段为 PMTU 大小数据包的消息,数据有效载荷应使用与 WQE 定义的数据段相同的顺序。从给定源 QP 到给定目标 QP 的数据包在结构中沿相同路径传输,并按照注入的顺序接收。C9-27:对于 HCA 上的可靠服务,所有确认数据包都应严格排序,例如,所有先前的 RDMA READ 响应和 ATOMIC 响应都应在后续的 SEND、RDMA WRITE 响应、RDMA READ 响应或 ATOMIC Operation 响应之前注入结构。 o9-19:如果 TCA 响应器实现可靠连接服务,或者 CA 响应器实现可靠数据报服务或 XRC 服务,则所有确认数据包都应严格排序。也就是说,所有先前的 RDMA READ 响应和 ATOMIC 响应都应在后续的 SEND、RDMA WRITE 响应、RDMA READ 响应或 ATOMIC Operation 响应之前注入到结构中。C9-28:响应器应按照接收消息的顺序执行 SEND 请求、RDMA WRITE 请求和 ATOMIC Operation 请求。如果请求针对不受支持的功能或服务,则还应按照接收 PSN 的顺序生成相应的响应(例如,NAK 消息、静默丢弃或错误日志记录)。• 应用程序不应依赖消息中数据写入内存的顺序。例如,如果应用程序为消息中的不同数据段设置了重叠的数据缓冲区,则不能保证最后发送的数据始终会覆盖先前的数据。 C9-29:接收方按发送顺序完成(仅适用于 SEND 和立即数的 RDMA WRITE),并不意味着之前的 RDMA READ 已完成,除非请求方隔离。C9-30:请求方应按传输顺序完成 WQE。C9-31:设置了隔离属性的工作请求应阻塞,直到所有之前的 RDMA Read 和 Atomic WR 都完成。C9-32:所有 WQE 应按发布的顺序完成,与执行顺序无关。由于可靠服务的请求和响应的排序规则保证,请求方可以在收到响应后写入 CQ 完成事件。o9-20:应用程序不应依赖于响应方 RDMA WRITE 缓冲区的内容,直到发生以下情况之一:• 与立即数一起使用时,最后一个 RDMA WRITE 请求数据包到达并完成。• 后续 SEND 消息到达并完成。 • 通过后续的原子操作更新内存元素。o9-21:在相应的 WQE 完成之前,应用程序不得依赖请求方的 RDMA READ 目标缓冲区的内容。o9-21.a1:在响应方的 SEND 缓冲区完成之前,应用程序不得依赖其内容。C9-33:在相应的接收 WQE 完成之前,应用程序不得依赖接收队列缓冲区的内容。
数据包传输头验证会对从较低 IBA 层向上传递到传输层的每个数据包进行。其目的是确定入站数据包是否可以与特定的队列对关联。如果无法关联,则该数据包将被静默丢弃。数据包传输头验证仅适用于使用 IBA 传输的数据包。 C9-34:传输层应根据本节的要求(第 301 页上的 9.6 数据包传输头验证)验证所有使用 IBA 传输的数据包的数据包头。如果 LRH:LNH 字段的最高位设置为 1,则应将数据包视为使用 IBA 传输。如果 LRH:LNH 字段的最高位设置为零,则该数据包为原始数据包。原始数据包在 429 页上的第 9.8.4 节原始数据报中描述。C9-35:对于使用 IBA 传输的每个入站数据包,CA 应根据图 8510 所示的状态图来验证数据包。状态图的详细信息将在本节的其余部分讨论。在将数据包呈现给传输层之前,会在链路层验证 LRH 的 LVer 字段。在将数据包呈现给传输层之前,还会在链路层验证 ICRC 和 VCRC 头。具有无效 LVer 字段的数据包、无效ICRC 或无效 VCRC 在到达传输层之前被悄悄丢弃
如果数据包可以与给定的队列对关联,则通过将数据包的某些特征与队列对中存储的上下文信息(或可靠数据报服务中的 EE 上下文)进行比较来进行进一步验证。第 9.7 节“可靠服务”和第 9.8 节“不可靠服务”中描述了这种级别的验证。本节始终使用短语“数据包被静默丢弃”。除非另有说明,否则在发生静默丢弃时响应方的行为如下:• 不返回确认消息。• 响应方不使用任何接收 WQE。• 不执行错误的请求数据包。• 在错误请求之前收到的任何请求数据包都将被执行并正常完成。• 响应方不更新其预期的 PSN。• 响应方继续等待有效的入站请求数据包。除非另有说明,否则在发生静默丢弃时请求方的行为如下:• 由于数据包被静默丢弃,没有发送 WQE 完成。 • 静默丢弃的数据包不会直接被采取任何措施,但错误计数器可能会增加或发生其他类似事件。• 静默丢弃的数据包不计入传输计时器的计算。队列状态不会更改。此外,对于已连接的传输服务或可靠数据报,连接或EE上下文不会被拆除。
本节规定了接收方在接收入站数据包(请求或响应数据包)之前必须验证的报头和字段,才能信赖该数据包的完整性。
本节描述了所有传入数据包必须验证的 BTH 字段。
C9-36:传输层应验证 CA 或路由器是否支持传输报头的版本号。如果 CA、交换机或路由器不支持指示的版本,则应静默丢弃该数据包。唯一有效的传输版本为零。 tver_check • 好(good):BTH 的 TVer 字段为 0x0 • 坏(bad):BTH 的 TVer 字段非零
由于入站数据包 BTH 中包含的操作码 (OpCode) 用于确定所选目标 QP 是否有效,因此操作码验证与目标 QP 及其当前状态的验证相结合。C9-37:传输层应验证目标 QP 是否存在,以及 QP 状态对于接收入站数据包是否有效。o9-22:此合规声明已作废,并由 o9-23.2.1 取代:o9-23:对于支持不可靠数据报多播的 CA,仅当至少有一个本地管理的 QP 配置为 IBA 不可靠数据报多播服务时,目标 QP 值 0xFFFFFF 才有效。 C9-38:应检查 BTH:OpCode[7:5],以确保请求的服务(RC、UC、RD、UD、XRC)与目标 QP 的配置一致。对于包含无效目标 QP 或其目标 QP 状态无效,无法接收入站数据包的入站数据包的响应取决于所请求的服务。这通过检查 BTH:OpCode[7:5] 来确定,BTH:OpCode[7:5] 指示请求的服务是 RC、RD、UC、UD 还是 XRC。此外,如果 BTH:OpCode[7:5] 指示该数据包用于 RD 服务,则必须检查 OpCode 的其余位,以确定入站数据包是请求数据包还是响应数据包。 C9-39:如果 BTH:OpCode[7:5] 指示数据包用于 RC、UC、UD 或 XRC 服务,并且目标 QP 不存在、目标 QP 未配置为提供请求的服务或目标 QP 状态无效,则传入数据包将被静默丢弃。C9-40:此合规声明已过时,并由 o9-23.2.1 取代:o9-23.2.1:对于实现 RD 服务的 CA:如果 BTH:OpCode[7:0] 指示 RD 请求数据包(SEND、RDMA READ 请求等),并且 EE 上下文有效,而目标 QP 不存在、目标 QP 未配置为提供 RD 服务或目标 QP 状态无效,则必须返回 NAK 无效的 RD 请求。如果 BTH:OpCode[7:0] 指示 RD 响应数据包(RDMA READ Response、Acknowledge 等),并且目标 QP 不存在,或者目标 QP 未配置为提供 RD 服务,或者目标 QP 状态无效,则应静默丢弃传入数据包
检查目的QP:
• good:BTH 中指定的目标 QP 是有效的 QP,并且处于接收数据包的正确状态,并且 QP 的配置与所请求的服务一致。
• bad:BTH 中指定的目标 QP 不存在,或者未处于接收数据包的正确状态,或者配置与所请求的服务不一致
C9-41:如果目标 QP 是 QP0,则不检查 BTH:P_Key。C9-42:如果目标 QP 是 QP1,则应将 BTH:P_Key 与数据包到达的端口关联的 P_Key 集进行比较。如果 P_Key 与端口关联的任何密钥匹配,则应将其视为有效。C9-43:对于除 QP0 或 QP1 之外的所有目标 QP,对于除可靠数据报之外的所有传输服务,应将 P_Key 与响应方的接收队列关联的 P_Key 进行比较。无效的 P_Key 将导致请求数据包被静默丢弃。o9-24:对于可靠数据报,应将 P_Key 与响应方的 EE 上下文关联的 P_Key 进行比较。无效的 P_Key 将导致请求数据包被静默丢弃。有关匹配 P_Key 过程的更多详细信息,请参阅第 567 页上的 10.9.3 分区键匹配。pkey_check • good:BTH:P_Key 与接收队列或 EE 上下文关联的值匹配 • bad:BTH:P_Key 与接收队列或 EE 上下文关联的值不匹配
本节介绍必须验证的 GRH 字段(如果存在)。在接收入站数据包之前,会配置 QP 或 EEC,以确定在此连接上接收的每个数据包中是否需要 GRH。此配置发生的机制超出了规范的范围。一种可能的实现是,此配置在建立连接时通过 CM REQ 消息中的子网本地位进行。只有当 GRH 的存在或不存在与 QP(或 EEC)配置一致时,才保证入站数据包通过 GRH 检查。对于 RC、RD、UC 和 XRC 服务,如果收到的入站数据包在 GRH 存在与否方面与 QP(或 EEC)配置不一致,则应丢弃该数据包。对于 UD 服务,由于预测数据包来源不切实际,因此不应检查 GRH 是否存在。如第 312 页第 9.6.1.6.2 节“IBA 不可靠多播检查”中所述,多播数据包必须包含 GRH。C9-43.1.1:对于 UD 服务,如果数据包是第 312 页第 9.6.1.6.2 节“IBA 不可靠多播检查”中规定的多播数据包,并且数据包中不存在 GRH,则应静默丢弃该数据包。 C9-43.1.2:对于 RC、RD、UC 和 XRC 服务,如果接收到的数据包在 GRH 存在与否方面与 QP(或 EEC)的配置一致,则该数据包应被视为已通过 GRH 检查,但需遵守第 306 页第 9.6.1.2 节“GRH 检查”其余部分中描述的其余 GRH 检查。
C9-44:如果存在 GRH,则必须检查 GRH 的下一个报头字段。下一个报头字段的值应设置为 0x1B。任何其他值都表示此数据包不使用 IBA 传输,并且应静默丢弃该数据包。 nxthdr_check • good:GRH:NxtHdr 字段指示 IBA 传输 • bad:GRH:NxtHdr 字段指示非 IBA 传输
C9-45:如果存在 GRH,则应检查 GRH 的版本字段。如果版本号不是 6,则应静默丢弃数据包。 ip_vers • not_v6:无效的 GRH 版本号 • v6:GRH 版本号有效
连接管理负责在传输层加载主 SGID 和 DGID。如果给定的 CA 支持自动路径迁移,则还会加载一组备用 SGID 和 DGID。主 GID 和备用 GID 比较及操作符合第 17.2.8 节“自动路径迁移”中定义的规则。如果存在 GRH,则应按如下方式验证 SGID 和 DGID:C9-46:如果目标 QP 配置为 UD 传输服务,则不应在传输层验证 SGID。仅当数据包为有效多播数据包时,才应验证 DGID。有关有效多播数据包的定义,请参阅第 312 页的 9.6.1.6.2 IBA 不可靠多播检查。C9-47:此合规声明已过时,并由 C9-47.1.1 取代:C9-47.1.1:如果目标 QP 配置为 RC、UC、RD 或 XRC 传输服务,则应在传输层验证 SGID 和 DGID。未通过这些有效性检查的数据包必须被静默丢弃。 DGID 的验证方法如下:1) 如果 DGID 设置为保留 GID,则 DGID 无效。2) 如果 DGID 设置为环回 GID,则 DGID 无效。3) 如果 DGID 的范围指示多播 GID,但没有本地关联的 QP,则 DGID 无效。完成这些检查后,将 DGID 与以下内容进行比较。如果与以下内容均不匹配,则 DGID 无效。4) 将 DGID 与主 DGID 进行比较。5) 将 DGID 的高 64 位与默认 GID 前缀 (0xFE80::0) 进行比较,并将 DGID 的低 64 位与 l 进行比较主 DGID 的高 64 位 6) 如果支持自动路径迁移,则将 DGID 与备用 DGID 进行比较。 7) 如果支持自动路径迁移,则将 DGID 的高 64 位与默认 GID 前缀 (0xFE80::0) 进行比较,将 DGID 的低 64 位与备用 DGID 的低 64 位进行比较 SGID 的验证方式如下: 1) 如果 SGID 设置为多播,则 SGID 无效。 2) 如果 SGID 设置为环回 GID,则 SGID 无效。 完成这些检查后,将 SGID 与以下内容进行比较。 如果 SGID 与以下至少一项不匹配,则它无效。 3) 将 SGID 与主 SGID 进行比较 4) 将 SGID 的高 64 位与默认 GID 前缀 (0xFE80::0) 进行比较,并将 SGID 的低 64 位与主 SGID 的低 64 位进行比较 5) 如果支持自动路径迁移,则将 SGID 与备用 SGID 进行比较 6) 如果支持自动路径迁移,则将 SGID 的高 64 位与默认 GID 前缀 (0xFE80::0) 进行比较,并将 SGID 的低 64 位与备用 SGID 的低 64 位进行比较 gid_check • 成功比较 GRH SGID 和 DGID • 错误 GRH SGID 或 DGID 无效
本节介绍 XRC 的字段(如果存在),这些字段必须经过 XRC 服务验证XRC_check: • 好的 XRC SRQ 与 XRC TGT QP 位于同一域 • 坏的 XRC SRQ 与 XRC TGT QP 不在同一域 o9-24.a1:如果 BTH:OpCode[7:5] 指示 XRC 传输服务,则应根据第 410 页上的“XRC 数据包格式规则”验证 XRCETH
本节介绍可靠数据报服务必须验证的 RDETH 字段(如果存在)。
C9-47.2.1:如果 BTH:OpCode[7:5] 指示 RD 传输服务且 CA 未实现 RD 服务,则必须静默丢弃该数据包。 o9-25:如果 BTH:OpCode[7:5] 指示 RD 传输服务,则应验证 RDETH。 o9-26:EE 上下文标识符应按照第 309 页表 43 EE 上下文验证中的规则进行验证。如果 EE 上下文无效,则必须静默丢弃该数据包
context_check
• 好:RDETH 中指定的 EE 上下文有效
• 坏:RDETH 中指定的 EE 上下文无效或 CA 不支持 RD 传输服务
本节描述 DETH 的字段(如果存在),必须检查数据报服务是否可靠。
C9-48:如果目标 QP 是 QP0,则无需验证 DETH:Q_Key 字段。 C9-49:如果目标 QP 是 QP1,则 DETH:Q_Key 字段与众所周知的 Q_Key 0x80010000 成功比较后应被视为有效。 C9-50:对于为数据报服务配置的队列对接收的所有数据包(QP0 除外),接收器的接收队列都应检查 Q_Key。如果 Q_Key 不匹配,则响应者的行为取决于服务是不可靠数据报还是可靠数据报,并应如下所示: 不可靠数据报:应静默丢弃数据包。可靠数据报:• 应返回 NAK-无效 RD 请求。• NAK 中使用的 P_Key 可以由响应方的 EE 上下文提供,也可以从被确认的请求包中提取。• NAK 消息中使用的 PSN 是错误请求包的 PSN。• EE 上下文的 PSN 保持不变;它仍然指向失败的请求包。• 响应方继续等待有效的入站请求包。C9-51:在接收队列检查完数据包的 Q_Key 和 P_Key 之前,响应方不得返回数据包的确认消息。qkey_check• 好:DETH 中包含的 Q_Key 与接收队列存储的 Q_Key 关联的 Q_Key 匹配。• 坏:DETH 中包含的 Q_Key 与接收队列存储的 Q_Key 关联的 Q_Key 不匹配。
本节介绍所有入站数据包必须验证的 LRH 字段。
C9-52:必须验证 LRH 中包含的 16 位完全解析的 SLID 和 DLID。 C9-53:仅对可靠连接、不可靠连接或可靠数据报服务(包括 XRC)才必须验证 DLID。对于不可靠数据报服务,不应验证 DLID。 C9-54:仅对可靠连接、不可靠连接或可靠数据报服务(包括 XRC)才必须验证 SLID。对于不可靠数据报服务,或者如果 QP 或 EEC 配置为需要 GRH,则不应验证 SLID - 请参阅第 306 页上的第 9.6.1.2 节 GRH 检查。要确保有效性,LRH 中包含的 SLID 和 DLID 必须与下列之一完全比较:1) 宽容 LID 2) 多播 LID(仅适用于 DLID)3) 主 LID 4) 备用 LID C9-55:仅当目标队列对为 QP0 时,宽容 LID 才会被接受为有效。C9-56:如果 SLID 是多播 LID,则它无效。C9-57:在配置为可靠连接或不可靠连接服务的 HCA 中,如果检测到无效的 LID,则应静默丢弃数据包。对于 RC 和 UC 服务,此检查由发送或接收队列执行。 o9-27:如果 TCA 实现了可靠连接或不可靠连接服务,并且检测到无效的 LID,则应静默丢弃数据包。对于 RC 和 UC 服务,此检查由发送或接收队列执行。o9-28:如果 CA 实现了可靠数据报或 XRC 服务,并且检测到无效的 LID,则应静默丢弃数据包。对于 RD 服务,此检查由 EE 上下文执行。主 SLID 和 DLID 存储在 QP 或 EE 上下文中。如果给定的通道适配器支持透明迁移,则备用 SLID 和 DLID 也将作为备用路径的一部分存储在 QP 或 EE 上下文中。是否将入站 SLID 和 DLID 与主 LID 或备用 LID 进行比较取决于自动路径迁移状态机的当前状态以及 BTH 中 MigReq 位的状态。 lid_check • good:LRH 中包含的 SLID 和 DLID 分别与 QP 或 EE 上下文中存储的 SLID 和 DLID 匹配。 • bad:LRH 中包含的 SLID 或 DLID 分别与 QP 或 EE 上下文中存储的 SLID 和 DLID 不匹配。
C9-58:如果目标 QP 为 0xFFFFFF,则数据包被声明为 IBA 不可靠多播数据包。要被视为有效,它必须具有以下三个特征:数据包必须包含 GRH,DGID 必须是有效的多播 GID,并且必须至少有一个为多播操作配置的本地管理队列对。如果其中任何一个条件不成立,则该数据包不是有效的多播数据包,应被静默丢弃。C9-59:应使用 DGID 将入站数据包映射到特定的本地管理 QP。 multicast_check • good:多播数据包满足上述所有有效多播数据包的标准。 • bad:多播数据包不满足上述所有有效多播数据包的标准
IB Spec1.6 卷1第9章
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。