[RDMA]QP相关介绍(二)——QP State Machine

1 QP State Machine

QP状态机示意图如下所示,注意事项如下:

  • 实线箭头表示software执行Modify QP verb引起状态改变。
  • 虚线箭头表示检测到错误时发生自定状态更改。
  • 使用Modify QP verb,software可以命令QP从任何其他状态进入Reset状态。
  • 使用Modify QP verb,software可以命令QP从任何其他状态进入Error状态。

QP在任何给定时间可能处于的状态有:

  • Reset:基本QP已创建,但未配置。software可通过Modify QP verb命令QP返回Reset状态。
  • Initialized(Init):

        —RQ WR发布,但不处理RQ WR。如果QP接收任何入站请求包,应将其丢弃。

        —禁止SQ WR发布与处理。

  • RTR(Ready to Receive):

        —RQ 发布与处理。RQ Logic可以处理入站message。如果是RC或RD QP,将生成远端QP的SQ Logic将接收的请求包的响应。

        —禁止SQ WR发布与处理。

  • RTS(Ready to Send):完全可操作的状态

        —WR可同时发布到SQ与RQ。

        —两个队列上的WR都会被处理。SQ Logic可以处理SQ WQE,并生成向远端QP的RQ Logic发送的出站请求包。

  • SQD(SQ Drain):software打算修改一个运行的QP特性时,它命令QP进入SQD状态。进入此状态后,QP的SQ完成所有正在进行的message传输,为QP修改做准备。
  • SQE(SQ Error):当SQ WQE错误完成时进入。software处理错误后,software可以重新发布更正后的失败WQE以及额外的SQ WQE,然后将QP转换为RTS状态。除RC QP外,所有类型的QP都实现此状态,RD EEC也不能实现。原因如下:

        —当遇到某种类型的错误时,RC QP的SQ Logic以及RD EEC的Send Logic会自动retry纠正错误。

        —如果Retry机制不能纠正错误,RC QP或RD EEC将直接从RTS状态转换为Error状态。

  • Error:QP遇到不可恢复的错误时进入该状态。QP停止处理SQ与RQ上的WQE。

        —SQ Logic不处理SQ WQE,也不生成发送至向远端QP的RQ Logic的出站请求包。

        —RQ Logic停止响应远端QP的SQ Logic传输的入站请求包。

2 QP Creation

2.1 Create QP‘s CQ

software创建QP之前,须先创建一个或两个CQ,以便与将要创建的QP的SQ与RQ相关联。可以通过调用一次或两次Create QP verb来实现。

2.2 Create QP

创建CQ后,software通过执行Create QP verb创建QP。

2.3 Create QP Verb Results

verb调用的结果将是下列结果之一:

  • 操作成功完成。
  • 资源不足,无法完成。
  • 无效HCA句柄。
  • 无效CQ句柄。
  • 请求的最大工作请求数超过了HCA的能力。
  • 请求的scatter/gather元素的数量超过了HCA的能力。
  • 无效保护域。
  • QP的服务类型无效。
  • 无效的RDD(仅适用RD)。

3 Software Control of QP State

software可通过执行Modify QP verb来更改QP的当前状态。根据QP的当前状态和要转换到的状态,协议将一些输入参数定义为必需,其他定义为可选的。

4 QP Setup Is Performed in a Defined Sequence

创建QP的初期(或如果QP已通过Modify QP verb被命令进入Reset状态),software将通过一系列定义的状态逐步推进,直到完全可操作:

① 创建后,QP立即处于Reset状态。既没有足够的消息发送消息,也没有足够的信息接收消息。

② 使用Modify QP verb,software为QP提供额外的信息,并将其状态转换为Init状态。

—发布RQ WR,但不处理RQ WQE。

—禁止SQ WR发布与处理。

③ 使用Modify QP verb,software向QP提供附加信息,将其转换为RTR状态。

—WR可同时发布到SQ与RQ。

—两个队列上的WQE都可以被处理。

5 Reset State

创建QP时进入Reset状态,当software执行Create QP verb时,verb命令HCA Logic创建(或保留)QP操作所需的基本资源,此时QP尚未准备好进行某种操作。使用Modify QP verb,software可以命令QP从任何其他状态进入Reset状态。

QP处于Reset状态时,具有以下特征:

  • QP的SQ与RQ以及它们各自的CQ都是空的。若该QP与其他QP共享其CQ,这些CQ可能包含其他QP的CQE。
  • 在SQ或RQ上发布WR是违法的,这样做会立即返回错误。
  • 禁止处理两个队列上的WQE。
  • 如果任何传入的数据包以此QP为目标,它将被静默丢弃。

从Reset状态开始,software可以将QP转换到的唯一有效状态是Init状态。因此,software执行Modify QP verb,下表为输入参数。

Input ParameterApplication QP TypesRequiredDescription
HCA Handle

All

Yes由调用向前的Open HCA verb返回。
QP HandleAllYes由调用向前的Create QP verb返回。
Next StateAllYesInit状态。

Enable or disable the ability of the RQ Logic to handle incoming RDMA Reads

RC、RDYesSelf-explanatory。

Enable or disable the ability of the RQ Logic to handle incoming RDMA Writes

RC、RD、UDYesSelf-explanatory。

Enable or disable the ability of the RQ Logic to handle incoming Atomic requests

RC、RDYesSelf-explanatory。
Primary P_Key index

RC、UC、UD

Yes

● 出站请求包的使用:每当此QP的SQ Logic生成到其关联的HCA端口的出站请求包时,它都会提供此值作为端口的P_KeyTable属性的索引。

● 入站请求包的使用:当与QP相关的端口接收到一个入站请求包时,将该请求包的BTH:P_Key与存储在目的QP的QPC中的Primary P_key索引值所选端口的P_KeyTable属性的条目作比较。

不适用非IBA QP或RD QP。

Q_KeyUD、RDYes

● 出站请求包的使用:当WR发布到RD/UD QP的SQ时,software提供分配给目标QP的Q_Key。Q_Key插入到出站请求包中。

● 入站请求包的使用:数据包BTH:Q_Key与目的地QP的Q_Key比较。

HCA port number

RC、UC、UDYes物理HCA端口QP将用来发送和接收message。

6 Initialized State

software使用Modify QP verb将QP从Reset状态转换到Initialized状态。

当QP处于Initialized状态时,它具有以下操作特征:

  • WR可发布到RQ,但不进行处理。
  • 以QP的RQ为目标,传入的数据包被静默丢弃。
  • 向SQ发布WR将导致返回Immediate Error。
  • SQ上的WQE不被处理。
  • 除了执行Destory QP verb,verb调用Modify QP是唯一转换Init状态的方法,且下一个状态必须是RTR状态。
  • 如果是RD QP,software试图向RD QP的SQ发送当前处于Init状态的EEC的WR,则该WR错误的完成。

从Init状态开始,software可以将QP转换到唯一有效的状态RTR状态,为此software执行verb调用的Modify QP。注意,使用Modify QP,software可命令QP进入Reset或Error状态。下表为定义的输入参数。

Input ParameterApplication QP TypesRequiredDescription
HCA Handle

All

Yes由调用向前的Open HCA verb返回。
QP HandleAllYes由调用向前的Create QP verb返回。
Next StateAllYesRTR状态。
RQ‘s Start ePSNRC、UCYesRQ Logic的Start ePSN必须设置为远程QP的SQ Logic的Start PSN。在连接建立过程中,它在REP message中提供。

Queue depth for inbound RDMA Read/Atomic operations

RC、RDYesRQ Logic特殊队列的深度,入站RDMA Read和Atomic operation请求被提交该队列中。
Remote Node Address VectorRC、UCYes

software为QP提供向目标QP所在远端CA端口发送请求包所需的所有地址信息。包括:

● Service Level。

● Send GRH Flag。如果设置,则表示远端CA在不同的子网中,发送给它的报文必须包含GRH,softwate还提供以下功能:

-Traffic Class。

-Flow Label。

-Hop Limit。

-Source GID index。

-DGID。

● DGID。如果目标CA在同一子网中,则DLID=目标CA端口的LID,否则DLID=路由器入端口的LID。

● PMTU。

● Maximum Static Rate。

● Local ACK Timeout(仅RC)。

● Retry Count(仅RC)。

● RNR Retry Count(仅RC)。

● Source Path Bits。

注,尽管Retry Count和RNR Retry Count都显示备用路径的地址信息,规范中将它们从列表中删除已被批准用于下一个规范修订。

Destination QPNRC、UCYesSelf-explanatory。
Alternate Path Address InfortionRC、UCNo

如果HCA支持自动路径迁移,software可选择性支持:

● 备用路径的P_Key索引。

● 用于此QP的备用路径的HCA端口。

● 备用路径的地址向量,包括该表中对远程节点地址向量的描述中指定的所有信息(用于不同路径)。

Enable/disable incoming RDMA and Atomic Operations

RC、RD、UCNo

● 使能/禁用该QP上的incoming RDMA Read(仅RC、RD)。

● 使能/禁用该QP上的incoming RDMA Write。

● 使能/禁用该QP上的incoming Atomic operation(仅RC、RD)。

Primary P_Key indexRC、UC、UDNo见上表。
Q_KeyUD、RDNo见上表。
New SQ and/or RQ sizeAllNo

如果HCA支持调整SQ与RQ大小:

● software预期发布给SQ的未完成WR的最大数量。

● software预期发布给RQ的未完成WR的最大数量。

Minimum RNR Nak Timer FieldRC、RDNo如果入站的Send或RDMA Write With Immediate message到达,而没有WQE发布至RQ,则RQ Logic返回一个RNR Nak。这是放置在Nak的RNR Nak Timer字段的值。重传该请求包之前,请求方需等待指定的时间。

 7 Ready to Receive State

software使用verb调用Modify QP,将QP从Init状态转换成RTR状态。

当QP处于RTR状态时,具有的特征如下:

  • WR可以发布至RQ。
  • 可以处理入站message,传输请求包。
  • 该QP的Send的第一个请求包或RDMA Write with Immediate可被下一个RQ WQE正常处理。如果是RC或RD QP,也包括为接收到的请求包生成一个Ack(或Nak)。
  • 只有通过verb调用Modify QP,才能将Init状态转换为RTR状态。
  • RTR状态可通过执行Destory QP verb或命令它(通过Modify QP verb)转换为RTS、Error或Reset状态退出。
  • 如果HCA支持RD,RD QP处于RTR状态,且software向QP的SQ发送一个指定当前处于RTR状态的本地EEC的WR,那么WR会错误的完成(因为EEC尚未准备好发送任何客户端RD QP的数据包)。
  • 禁止处理SQ WQE。将WR发布至SQ会返回Immediate Error。

software通常会将QP从RTR状态转换到RTS状态,如果software只打算通过这个QP接收message而不发送,可以让QP始终处于RTR状态,否则执行Modify QP,输入参数如下表:

Input ParameterApplication QP TypesRequiredDescription
HCA Handle

All

Yes由调用向前的Open HCA verb返回。
QP HandleAllYes由调用向前的Create QP verb返回。
Next StateAllYesRTS状态。

Local Ack Timeout

RC

YesQP的SQ Logic重传相应的请求包之前等待Ack的时间。
SQ Start PSNRC、UC、UDYessoftware分配给该QP的SQ Logic的Start PSN。它被插入到由SQ Logic生成的第一个请求包中的BTH:PSN字段中。
Retry CountRCYes

QP的SQ Logic由于超时或Nak-Sequence error导致重传的次数。

RNR Retry CountRCYes两个QP建链时,远端CA的CM提供。定义远端QP的RQ Logic接收RNR Nak请求包的重传次数。如果无法接收请求包,远端QP的RQ Logic返回RNR Nak。
Depth of remote QP‘s special queue for RDMA Read/Atomic operationsRC、RDYesRQ Logic接收入站RDMA Read和Atomic operation请求的特殊队列的深度。

Enable/disable incoming RDMA and Atomic Operations

RC、RD、UCNo

● 使能/禁用该QP上的incoming RDMA Read(仅RC、RD)。

● 使能/禁用该QP上的incoming RDMA Write。

● 使能/禁用该QP上的incoming Atomic operation(仅RC、RD)。

Q_KeyRD、UDNo见上表。
Alternate Path address informationRC、UCNo见上表。
Path Migration StateRC、UC、RDNo表示迁移状态。
New SQ and/or RQ sizeAllNo

如果HCA支持调整SQ与RQ大小:

● software预期发布给SQ的未完成WR的最大数量。

● software预期发布给RQ的未完成WR的最大数量。

Minimum RNR Nak Timer FieldRC、RDNo见上表。

 8 Ready to Send State

QP处于RTS状态时,message可以被接收和发送。software使用verb调用Modify QP从RTS状态转换成RTR、SQD或SQE状态。

QP处于RTS状态时,具有以下特征:

  • 对于RC、UC和RD:

        —在发起建链的CA上,将此QP转换为RTS状态之前,必须发送REQ message来接收相应的REP message。

        —在发送REP message的CA上,RTU message必须将其QP转换为RTS状态之前被接收(它也将收到来自远端QP的SQ Logic的第一个请求包时自动跳转到RTS转态)。

  • software执行Modify QP,只能从RTR、SQE和SQD状态转换到RTS状态。
  • 除了执行Destory QPModify QP是使QP退出RTS状态的唯一方法,且可将下一个状态设置为SQD、Error或Reset。
  • WR可以同时发布到SQ与RQ。
  • 两个队列上的WQE都可被正常处理。
  • QP的传入message(Send或RDMA Write with Immediate)由下一个RQ WQE正常处理。如果是RC或RD,包括为收到的请求包生成Ack(或Nak)。

software可以将QP从RTS状态转换为SQD状态,为修改QP的操作特性做准备。使用Modify QP verb,software可以命令QP进入Reset或Error状态。为此,software执行Modify QP verb,输入参数如下。注意,不允许使用可选参数。

Input ParameterApplication QP TypesRequiredDescription
HCA Handle

All

Yes由调用向前的Open HCA verb返回。
QP HandleAllYes由调用向前的Create QP verb返回。
Next StateAllYesSQD状态。
Affiliated Asynchronous Event notificationAllNosoftware告诉verb层每当关联异步事件发生时要调用的处理程序的起始地址。当software稍后使用Modify QP verb将QP转换为SQD状态时,它可以指定一旦QP的SQ完成所有正在进行的消息传输就生成关联异步事件。在完成所有正在进行的消息传输后,HCA将通知verb层(通常通过中断)要调用异步事件处理程序及其原因。调用处理程序,确定QP的SQ现在处于静止状态,并在更改QP的操作特征之前通知正在等待此通知的software实体。software可以使用一次Modify QP verb来改变QP的操作特征,将其更改为RTS状态。

9 SQ Drain(SQD) State

software使用Modify QP verb将QP从SQD状态转换为RTS状态。

software可能需要改变已完全运行的QP的操作特征(如它处于RTS状态)。当QP仍有一个或多个message发送到远端QP时,这样做是危险的。命令一个运行的QP进入SQD状态会导致QP:

  • 完成所有正在进行的message传输。
  • 一直等待直到所有的期望响应被接收。
  • 退役所有正在进行的WQE。
  • 创建各自的CQE。
  • 暂停。

没有传输新的message,software可以安全地使用Modify QP verb来改变QP的操作特性,然后将QP恢复至完全运行状态。此时,QP的SQ Logic使用SQ上的下一个WQE解除暂停并回复message传输。

当QP进入SQD状态时,具有以下操作特征:

  • 当QP处于SQD时,可以将新的WR发布到两个队列。
  • 当QP进入SQD状态时,QP:

        —不得在其SQ上开始处理任何尚未开始传输的WR。

        —必须完成任何先前启动的消息传输。

        —必须处理正在进行的消息传输(RC和RD)相关请求包返回的Ack。

  • 目标QP的传入message(Send或RDMA Write With Immediate)由下一个RQ WQE正常处理。如果是RC或RD,要为收到的请求包生成Ack(或Nak)。
  • 当所有预期的Ack都被接收到,并且所有正在进行的WR的处理完成后,如果请求了事件通知,则生成Affiliated Asynchronous Event。software可以使用Affiliated Asynchronous Event来确定何时可以进行状态转换(从SQD转换为RTS)。
  • QP特征可能会在SQD状态转换为RTS状态的过程中被修改(通过Modify QP verb),但是与本端和远端QP相关联的software实体必须接收Affiliated Asynchronous Event,以便安全地改变QP的特征。
  • 如果HCA支持从SQD状态转换到RTS状态时更改与QP关联的端口,则在转换回RTS状态之前,将新端口与QP关联。
  • software可以通过执行Destroy QP verb或Modify QP verb导致QP退出SQD(转换为RTS、Reset或Error状态)。
  • 当RD QP处于SQD状态时,WR可能会被发布到其SQ。如果WR指定的EEC当前处于SQD状态,则不处理WR,但仍可发布。

在较早的时候,software会执行Set Asynchronous Event Handler verb,以告诉verb层每当Asynchronous Event发生时要调用的处理程序的起始地址。

当software稍后使用Modify QP verb将QP转换为SQD状态时,它可以选择一旦QP的SQ完成所有正在进行的message传输就生成Affiliated Asynchronous Event。

完成所有正在进行的message传输后,HCA将通知verb层(通常通过中断)要调用Asynchronous Event Handler及其原因。调用Handler,确定QP的SQ现在处于静止状态,并在更改QP的操作特征之前通知正在等待此通知的software实体。然后,software可以调用一次Modify QP verb来改变QP的操作特征,并将其更改回RTS状态。

当使用Modify QP verb将QP从SQD状态转换回RTS状态时可能提供的输入参数如下表。

Input ParameterApplication QP TypesRequiredDescription
HCA Handle

All

Yes由调用向前的Open HCA verb返回。
QP HandleAllYes由调用向前的Create QP verb返回。
Next StateAllYesRTS状态。
Remote Node Address VectorRC、UCNo见上表。
Alternate Path address informationRC、UCNo见上表。
Path Migration State-No见上表。
Depth of remote QP‘s special queue for RDMA Read/Atomic operationsRC、RDNoRQ Logic接收入站RDMA Read和Atomic operation请求的特殊队列的深度。

Queue depth for inbound RDMA Read/Atomic operations

RC、RDYesRQ Logic特殊队列的深度,入站RDMA Read和Atomic operation请求被提交该队列中。
Q_KeyRD、UDNo见上表。
P_Key indexRC、UC、UDNo见上表。

Local Ack Timeout

RC

NoQP的SQ Logic重传相应的请求包之前等待Ack的时间。
Retry CountRCYes

QP的SQ Logic由于超时或Nak-Sequence error导致重传的次数。

RNR Retry CountRCYes两个QP建链时,远端CA的CM提供。定义远端QP的RQ Logic接收RNR Nak请求包的重传次数。如果无法接收请求包,远端QP的RQ Logic返回RNR Nak。
New SQ and/or RQ sizeAllNo

如果HCA支持调整SQ与RQ大小:

● software预期发布给SQ的未完成WR的最大数量。

● software预期发布给RQ的未完成WR的最大数量。

Minimum RNR Nak Timer FieldRC、RDNo见上表。

HCA port number

RCNo物理HCA端口QP将用来发送和接收message。

10 SQ Error State

10.1 SQ Error Entry Conditions

除RC QP外,所有类型的QP都实现此状态,但RD EEC无法实现。

在message传输的过程中,当SQ WQE遇到错误时,自动转换为SQE状态。既可以由RTS状态进入,也可由SQD状态进入。

10.2 How Do the SQE and Error States Differ

当QP转换为Error状态时,QP将完全无效。它同时停止处理SQ与RQ的WQE,停止向远端QP的RQ Logic发送请求包,同样RQ Logic停止处理任何由远端QP的SQ Logic传输的传入请求包,请求包将被静默丢弃。

当QP处于SQE状态时(从RTS状态或SQD状态),SQ Logic停止处理SQ WQE,没有新的请求包被传输到远端QP的RQ Logic。另一方面,QP的RQ Logic保持完整的功能。在进入SQE状态之前发布到RQ的RQ WQE会被处理,QP的RQ Logic响应由远端QP的SQ Logic传输的传入请求包。虽然新的WQE可以发布到QP的RQ,但规范似乎暗示,在QP转换回RTS状态之前,请求包不会被处理。协议规定如下:

"C10-38: Receive Work Requests which were submitted to a Receive Queue prior to that queue's transition into the SQEr state shall continue to be processed normally. New Receives must be able to be posted to such a Receive Queue."

10.3 SQE State Qperational Characteristics

QP进入SQE状态时,具有以下操作特征:

  • Error CQE created。当QP处于RTS或SQD状态,执行当前SQ WQE描述的message传输出现错误时,进入SQE状态。SQ Logic在SCQ上为该message传输创建一个错误的CQE。
  • Subsequent WQEs are flushed。在导致错误的WQE之后发布到该SQ的WQE全部退役,并在SCQ中创建CQE,表明它们都是由于较早的SQ WQE上的错误而“flushed”。
  • Completion Error Types:

        —Interface Check。提供给HCA的WR信息中有错误。这种情况下,任何message放入链路前会检测到错误。

        —Processing Error。SQ Logic在处理WQE时出现错误。

  • The remote QP's RQ state isn't known。对于除了RD以外的所有QP类型,SQ Logic可以在当前WQE的消息传输完成之前开始处理下一个SQ WQE。对于RD,QP的SQ Logic只允许在单个SQ WQE上工作,不能继续进行下一个消息传输,直到当前消息传输完成并接收到远端QP返回的相应响应包。若SQ Logic检测到错误时(如接收到Nak),SQ Logic已发送了一个或多个后续消息传输相关的请求包,并且远端的RQ Logic可能已经接收或处理。这种情况下,可能会影响远端QP的RQ Logic状态:

        —Send操作可能已部分或全部被RQ Logic完成,并且RQ CQE可能已生成或还未生成。

        —RDMA Read操作可能已部分完成(即,一个或多个RDMA Read响应包可能已返回请求方,可能已经或者还未写入本地内存),所以其WR所指向的Scatter Buffers的内容是不确定的。

        —RDMA Write操作可能已部分完成,目标CA的本地内存的内容不确定。如果该操作指定在message的最后一个数据包中传递即时数据,则RQ CQE不确定是否已创建。

        —原子操作可能已经或者还未在远端的CA内存中,WR的远端地址所指向的内存内容可能包含原始或已更新的数据。在请求方的QP端,为保存返回的读数据而分配的内存缓冲区的内容是不确定的。

  • RQ remains functional。在QP转换到SQE状态之前发布到本地QP的RQ WQE继续正常处理,但不会处理新发布到RQ的RQ WQE。
  • Verb used to leave this state。Modify QP verb用于将QP从SQE状态转换为RTS状态、Error状态或Reset状态。
  • Detection of another error leads to Error state。当QP处于SQE状态时,检测到RQ错误或异步错误会导致QP转换为Error状态。
  • SQE doesn't apply to RC。SQE状态适用于处RC QP外的所有QP。

10.4 Software Actions When SQE State Entered

转换到SQE状态时,software可能采取以下行为:

  1. 检查与失败的SQ WQE相关的错误CQE,确定错误的原因。
  2. 决定是否修改WR,这将决定消息传输是否成功。如果不能通过修改和重新发布WR来解决问题,software将把QP转换为Error状态,并向请求消息传输的应用程序返回hard-failure通知。
  3. 假设对WR的修订可以解决问题,software将修改后的WR重新发布到SQ。如果在错误发生时有额外的WR发布到SQ,它们将被“flushed”,software也会重新发布这些WR。
  4. software可以使用Modify QP verb将QP回退到完全可操作的RTS状态。

11 Error State

  • You're dead。停止处理SQ和RQ上的WR。
  • Error CQE created。产生错误导致转换为Error状态的SQ或RQ的WQE将退役,并在各自队列的CQ上创建一个错误的CQE。
  • Subsequent WQEs are flushed。在出现完成错误并导致进入Error状态之后,在有问题的队列上发布WQE,包括转为Error状态之后发布的将全部退役,并在相应队列的CQ上创建CQE,表明它们都是由于之前WQE的错误而“flushed”。
  • Verb can cause swith to Error state。注意,使用Modify QP verb,software可以命令QP从任何状态转换为Error状态。
  • Verb can only swith to Reset state。使用Modify QP verb可以将QP从Error状态转换为Reset状态。
  • The remote QP's RQ state isn't known。对于除RD以外的所有QP类型,SQ Logic可以在当前WQE的消息传输完成之前开始处理下一个SQ WQE。而RD QP的SQ Logic一次只允许单个SQ WQE,并且在当前消息传输完成并从远端QP接收到相应的响应包之前,不能进行下一个消息传输。若SQ Logic检测到错误时(如接收到Nak),SQ Logic已发送了一个或多个后续消息传输相关的请求包,并且远端的RQ Logic可能已经接收或处理。这种情况下,可能会影响远端QP的RQ Logic状态:

        —Send操作可能已部分或全部被RQ Logic完成,并且RQ CQE可能已生成或还未生成。

        —RDMA Read操作可能已部分完成(即,一个或多个RDMA Read响应包可能已返回请求方,可能已经或者还未写入本地内存),所以其WR所指向的Scatter Buffers的内容是不确定的。

        —RDMA Write操作可能已部分完成,目标CA的本地内存的内容不确定。如果该操作指定在message的最后一个数据包中传递即时数据,则RQ CQE不确定是否已创建。

        —原子操作可能已经或者还未在远端的CA内存中,WR的远端地址所指向的内存内容可能包含原始或已更新的数据。在请求方的QP端,为保存返回的读数据而分配的内存缓冲区的内容是不确定的。

  • 如果将WR发布到RD QP的SQ中,指定当前处于错误状态的EEC,则该WR被错误完成并且RD QP被置于SQE状态。
  • 如果发生关联异步错误,QP可能无法继续处理WQE,未完成的WQE无法完成。
  • 在处理错误通知时,software有责任确保在通过Modify QP verb将QP强制到Reset状态之前完成所有错误处理。
  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RDMA HCA/TCA是一种高速网络适配器,它使用RDMA技术来提高数据传输的效率和性能。HCA代表Host Channel Adapter,而TCA代表Target Channel Adapter。HCA通常安装在主机上,而TCA通常安装在存储设备上。这两种适配器都支持RDMA技术,可以通过RDMA协议进行高速数据传输。 RDMA技术是一种零拷贝技术,它可以直接在内存中传输数据,而不需要将数据从内存复制到网络适配器的缓冲区中。这种技术可以显著提高数据传输的效率和性能,减少CPU的负载,降低网络延迟和网络拥塞。 RDMA HCA/TCA通常使用InfiniBand或者RoCE(RDMA over Converged Ethernet)网络来进行高速数据传输。这些网络可以提供非常低的延迟和高的带宽,适用于高性能计算、云计算、大数据分析等领域。 以下是一个使用RDMA Write with Immediate Data的例子: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <infiniband/verbs.h> #define MSG_SIZE 1024 #define RDMA_BUF_SIZE 1024 struct rdma_context { struct ibv_context *ctx; struct ibv_pd *pd; struct ibv_mr *mr; struct ibv_cq *cq; struct ibv_qp *qp; struct ibv_comp_channel *comp_channel; struct ibv_port_attr port_attr; char *rdma_buf; uint32_t rkey; uint64_t remote_addr; }; int main(int argc, char *argv[]) { struct rdma_context ctx; struct ibv_device **dev_list; struct ibv_device *ib_dev; struct ibv_qp_init_attr qp_init_attr; struct ibv_qp_attr qp_attr; struct ibv_wc wc; int num_devices; int ret; int i; /* 获取IB设备列表 */ dev_list = ibv_get_device_list(&num_devices); if (!dev_list) { perror("ibv_get_device_list"); return -1; } /* 选择第一个IB设备 */ ib_dev = dev_list[0]; if (!ib_dev) { fprintf(stderr, "No IB devices found\n"); return -1; } /* 打开IB设备 */ ctx.ctx = ibv_open_device(ib_dev); if (!ctx.ctx) { perror("ibv_open_device"); return -1; } /* 创建PD */ ctx.pd = ibv_alloc_pd(ctx.ctx); if (!ctx.pd) { perror("ibv_alloc_pd"); return -1; } /* 分配内存 */ ctx.rdma_buf = malloc(RDMA_BUF_SIZE); if (!ctx.rdma_buf) { perror("malloc"); return -1; } /* 注册内存 */ ctx.mr = ibv_reg_mr(ctx.pd, ctx.rdma_buf, RDMA_BUF_SIZE, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE); if (!ctx.mr) { perror("ibv_reg_mr"); return -1; } /* 创建CQ */ ctx.cq = ibv_create_cq(ctx.ctx, 1, NULL, NULL, 0); if (!ctx.cq) { perror("ibv_create_cq"); return -1; } /* 创建QP */ memset(&qp_init_attr, 0, sizeof(qp_init_attr)); qp_init_attr.send_cq = ctx.cq; qp_init_attr.recv_cq = ctx.cq; qp_init_attr.qp_type = IBV_QPT_RC; qp_init_attr.cap.max_send_wr = 1; qp_init_attr.cap.max_recv_wr = 1; qp_init_attr.cap.max_send_sge = 1; qp_init_attr.cap.max_recv_sge = 1; ctx.qp = ibv_create_qp(ctx.pd, &qp_init_attr); if (!ctx.qp) { perror("ibv_create_qp"); return -1; } /* 修改QP状态 */ memset(&qp_attr, 0, sizeof(qp_attr)); qp_attr.qp_state = IBV_QPS_INIT; qp_attr.pkey_index = 0; qp_attr.port_num = 1; qp_attr.qp_access_flags = IBV_ACCESS_REMOTE_WRITE; ret = ibv_modify_qp(ctx.qp, &qp_attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS); if (ret) { perror("ibv_modify_qp"); return -1; } /* 获取端口属性 */ ret = ibv_query_port(ctx.ctx, 1, &ctx.port_attr); if (ret) { perror("ibv_query_port"); return -1; } /* 创建Completion Channel */ ctx.comp_channel = ibv_create_comp_channel(ctx.ctx); if (!ctx.comp_channel) { perror("ibv_create_comp_channel"); return -1; } /* 将CQ绑定到Completion Channel */ ret = ibv_req_notify_cq(ctx.cq, 0); if (ret) { perror("ibv_req_notify_cq"); return -1; } /* 等待CQ事件 */ ret = ibv_get_cq_event(ctx.comp_channel, &ctx.cq, &ctx.ctx); if (ret) { perror("ibv_get_cq_event"); return -1; } /* 请求下一个CQ事件 */ ret = ibv_req_notify_cq(ctx.cq, 0); if (ret) { perror("ibv_req_notify_cq"); return -1; } /* 获取远程节点的rkey和地址 */ ctx.rkey = 0x12345678; ctx.remote_addr = 0xdeadbeef; /* 向远程节点发送数据 */ memset(ctx.rdma_buf, 0, RDMA_BUF_SIZE); strcpy(ctx.rdma_buf, "Hello RDMA!"); struct ibv_send_wr wr, *bad_wr; struct ibv_sge sge; memset(&wr, 0, sizeof(wr)); wr.wr_id = 0; wr.opcode = IBV_WR_RDMA_WRITE_WITH_IMM; wr.send_flags = IBV_SEND_SIGNALED; wr.imm_data = 0x1234; wr.wr.rdma.remote_addr = ctx.remote_addr; wr.wr.rdma.rkey = ctx.rkey; wr.sg_list = &sge; wr.num_sge = 1; sge.addr = (uintptr_t)ctx.rdma_buf; sge.length = strlen(ctx.rdma_buf) + 1; sge.lkey = ctx.mr->lkey; ret = ibv_post_send(ctx.qp, &wr, &bad_wr); if (ret) { perror("ibv_post_send"); return -1; } /* 等待发送完成 */ do { ret = ibv_poll_cq(ctx.cq, 1, &wc); if (ret < 0) { perror("ibv_poll_cq"); return -1; } } while (ret == 0); /* 检查发送状态 */ if (wc.status != IBV_WC_SUCCESS) { fprintf(stderr, "Send failed with status %d\n", wc.status); return -1; } /* 关闭QP */ ret = ibv_destroy_qp(ctx.qp); if (ret) { perror("ibv_destroy_qp"); return -1; } /* 关闭Completion Channel */ ret = ibv_destroy_comp_channel(ctx.comp_channel); if (ret) { perror("ibv_destroy_comp_channel"); return -1; } /* 关闭CQ */ ret = ibv_destroy_cq(ctx.cq); if (ret) { perror("ibv_destroy_cq"); return -1; } /* 注销内存 */ ret = ibv_dereg_mr(ctx.mr); if (ret) { perror("ibv_dereg_mr"); return -1; } /* 释放内存 */ free(ctx.rdma_buf); /* 释放PD */ ret = ibv_dealloc_pd(ctx.pd); if (ret) { perror("ibv_dealloc_pd"); return -1; } /* 关闭IB设备 */ ret = ibv_close_device(ctx.ctx); if (ret) { perror("ibv_close_device"); return -1; } /* 释放IB设备列表 */ ibv_free_device_list(dev_list); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值