目录
IBV_WC_RNR_RETRY_EXC_ERR(13/0xd)
原文:https://blog.csdn.net/weixin_33978451/article/details/112398245
什么是Verbs
Verbs直译过来是“动词”的意思,它在RDMA领域中有两种含义:
1) 由IB规范所描述的一组抽象定义
规定了各厂商的软硬件在各种Verbs下应该执行的动作或者表现出的行为,IB规范并未规定如何编程实现这些Verbs,在这种含义下,Verbs是与操作系统无关的。
举个例子,IB规范要求所有RDMA设备必须支持Create QP的行为(IB 规范11.2.5.1):
描述:
为指定的设备创建一个QP。
用户必须指定一组用于初始化QP的属性。
如果创建QP所需的属性有非法值或者缺失,那么应该返回错误,该QP不会被创建;如果成功, 那么返回该QP的指针和QPN。
……
输入:
设备指针;
SQ关联到的CQ;
RQ关联到的CQ,如果是XRC的INI QP,则可以不携带此参数;
……
输出:
新创建的QP的指针;
QP Number;
SQ的最大WR容量。
……
可以看出IB规范中的Verbs是对一个概念进行定义,讲的是“需要支持什么,但具体怎么实现我不做规定”。
2) 由OpenFabrics推动实现的一组RDMA应用编程接口(API)
既然是API,那么必然和运行的操作系统相关。Verbs API有Linux版本以及Windows版本(Windows版很久没有更新了)。
以Create QP为例,下文引用自Linux用户态Verbs API的帮助文档(ibv_create_qp(3): create/destroy queue pair):
名称:
ibv_create_qp - create a queue pair (QP)
概要:
#include <infiniband/verbs.h>
struct ibv_qp ibv_create_qp(struct ibv_pd pd, struct ibv_qp_init_attr *qp_init_attr);
描述:
ibv_create_qp()通过一个关联的PD创建一个QP,参数qp_init_attr是一个ibv_qp_init_attr类型的结构体,其定义在<infiniband/verbs.h>中。
struct ibv_qp_init_attr {
struct ibv_cq *send_cq; /* CQ to be associated with the Send Queue (SQ) */
struct ibv_cq *recv_cq; /* CQ to be associated with the Receive Queue (RQ) */
struct ibv_srq *srq; /* SRQ handle if QP is to be associated with an SRQ, otherwise NULL */
struct ibv_qp_cap cap; /* QP capabilities */
enum ibv_qp_type qp_type; /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, or IBV_QPT_UD */
...
};
函数ibv_create_qp()会更新qp_init_attr->cap struct的内容,返回创建的QP所真正支持的规格……
返回值:
ibv_create_qp()返回被创建的QP的指针,或者在失败时返回NULL。QPN将在返回的指针所指向的结构体中。
可见Verbs API即是对IB规范中的Verbs定义的具体软件实现。
Verbs的第一种语义直接查阅IB规范的第11章即可,里面做了非常详细的描述。
本文介绍的是第二种语义,包含Verbs API是什么,如何和硬件产生交互,我们如何通过Verbs API来编写RDMA程序。如无特殊说明,下文中的Verbs均特指Verbs API。
相关名词解释
指开源RDMA用户态软件协议栈,包含用户态框架、各厂商用户态驱动、API帮助手册以及开发自测试工具等。
rdma-core在github上维护,我们的用户态Verbs API实际上就是它实现的。https://github.com/linux-rdma/rdma-core
指开源的Linux内核中的RDMA子系统,包含RDMA内核框架及各厂商的驱动。
RDMA子系统跟随Linux维护,是内核的的一部分。一方面提供内核态的Verbs API,一方面负责对接用户态的接口。
- OFED
全称为OpenFabrics Enterprise Distribution,是一个开源软件包集合,其中包含内核框架和驱动、用户框架和驱动、以及各种中间件、测试工具和API文档。
开源OFED由OFA组织负责开发、发布和维护,它会定期从rdma-core和内核的RDMA子系统取软件版本,并对各商用OS发行版进行适配。除了协议栈和驱动外,还包含了perftest等测试工具。
下图为OFA给出的OFED的概览:

除了开源OFED之外,各厂商也会提供定制版本的OFED软件包,比如华为的HW_OFED和Mellanox的MLNX_OFED。这些定制版本基于开源OFED开发,由厂商自己测试和维护,会在开源软件包基础上提供私有的增强特性,并附上自己的配置、测试工具等。
以上三者是包含关系。无论是用户态还是内核态,整个RDMA社区非常活跃,框架几乎每天都在变动,都是平均每两个月一个版本。而OFED会定期从两个社区中取得代码,进行功能和兼容性测试后发布版本,时间跨度较大,以年为单位计。
Verbs API
Verbs API是什么
Verbs API是一组用于使用RDMA服务的最基本的软件接口,也就是说业界的RDMA应用,要么直接基于这组API编写,要么基于在Verbs API上又封装了一层接口的各种中间件编写。
Verbs API向用户提供了有关RDMA的一切功能,典型的包括:注册MR、创建QP、Post Send、Poll CQ等等。
对于Linux系统来说,Verbs的功能由rdma-core和内核中的RDMA子系统提供,分为用户态Verbs接口和内核态Verbs接口,分别用于用户态和内核态的RDMA应用。
结合上一部分的内容,我们给出一个OFED的全景:

广义的Verbs API主要由两大部分组成:
1、IB_VERBS
接口以ibv_xx(用户态)或者ib_xx(内核态)作为前缀,是最基础的编程接口,使用IB_VERBS就足够编写RDMA应用了。
比如:
- ibv_create_qp() 用于创建QP
- ibv_post_send() 用于下发Send WR
- ibv_poll_cq() 用于从CQ中轮询CQE
2、RDMA_CM
以rdma_为前缀,主要分为两个功能: