OFED组件框架
OFED
全称为OpenFabrics Enterprise Distribution,是一个开源软件包集合,其中包含内核框架和驱动、用户框架和驱动、以及各种中间件、测试工具和API文档。
开源OFED由OFA组织负责开发、发布和维护,它会定期从rdma-core和内核的RDMA子系统取软件版本,并对各商用OS发行版进行适配。除了协议栈和驱动外,还包含了perftest等测试工具。
除了开源OFED之外,各厂商也会提供定制版本的OFED软件包,比如华为的HW_OFED和Mellanox的MLNX_OFED。这些定制版本基于开源OFED开发,由厂商自己测试和维护,会在开源软件包基础上提供私有的增强特性,并附上自己的配置、测试工具等。
以上三者是包含关系。无论是用户态还是内核态,整个RDMA社区非常活跃,框架几乎每天都在变动,都是平均每两个月一个版本。而OFED会定期从两个社区中取得代码,进行功能和兼容性测试后发布版本,时间跨度较大,以年为单位计。
基于xilinx的rdma组件调用关系图
根据多个流程(rdma_accept ,创建qp,创建cm_id,创建cp等)整理出组件关系图:
其中各个不同颜色的箭头代表几种不同的流程的组件调用过程:
绿色箭头:app使用xilinx用户态驱动so库的流程(RDMA读写)
蓝色箭头:app不使用cm的rdma控制面流程(如通过socket建链)
黄色箭头:rdma_accept 改变qp状态的流程(cm建链)
红色箭头:创建qp的流程
黑色箭头:创建cm_id流程
淡蓝色箭头:创建cp流程和reg mr流程
首先从上往下看:
用户空间
- Application
各种RDMA应用程序(比如xperf、rping工具、spdk等)
- so
RDMA软件栈用户态核心动态链接库,作用:
- 实现并且向上层应用提供各种Verbs API
- 在各种Verbs API的逻辑中调用到各厂商驱动注册的钩子函数
- 提供进入内核态的接口
- so
xilinx网卡的用户态驱动,也是个动态链接库,实现厂商的驱动逻辑。
内核空间
- 中间交互模块
负责通过ABI(应用二进制接口)来处理用户态的系统调用请求,用户态verbs陷入内核,需要通过这一层的ib_uverbs模块来解析命令。
- ko
内核RDMA子系统核心模块,作用:
- 向使用内核态Verbs的应用程序提供内核态Verbs API
- 在各种Verbs API的逻辑中调用到各厂商驱动注册的钩子函数
- 管理各种RDMA资源,为用户态提供服务
- ko
xilinx网卡的内核态驱动模块,负责直接和硬件交互,对硬件寄存器进行编程。
- 硬件
指xilinx网卡。
然后我们以红色虚线为界分左右来看这张图,左侧是用户态应用程序的层次结构,右侧为内核态应用程序的层次结构。其中用户态应用又分为左右两条路,左边绕过内核的是指数据路径,右边需要通过内核的是指控制路径。
快路径:不走内核,效率高,一般走数据面的流程(RDMA read/write: ibv_post_send ibv_poll_cq, APP将wr提交给硬件后,硬件就直接处理了,读写数据的过程中内核不用参与)。
慢路径:都要通过内核,效率相对较低,一般走控制面的流程(建链、收发工作任务等)。
基于mlnx的rdma组件调用关系图
首先从上往下看:
用户空间
- Application
各种RDMA应用程序(比如perftest)、中间件(比如UCX)等。spdk.
- so
RDMA软件栈用户态核心动态链接库,作用:
- 实现并且向上层应用提供各种Verbs API
- 在各种Verbs API的逻辑中调用到各厂商驱动注册的钩子函数
- 提供进入内核态的接口
- so
Mellanox ConnectX-5网卡的用户态驱动,也是个动态链接库,实现厂商的驱动逻辑。
内核
- 中间交互模块
负责通过ABI(应用程序二进制接口)来处理用户态的系统调用请求,用户态verbs陷入内核,需要通过这一层的ib_uverbs模块来解析命令;另外右侧的xxx.ko指的是使用内核verbs接口(比如ib_post_send)的上层应用程序所需要的处理系统调用的自定义模块。
- ko
内核RDMA子系统核心模块,作用:
- 向使用内核态Verbs的应用程序提供内核态Verbs API
- 在各种Verbs API的逻辑中调用到各厂商驱动注册的钩子函数
- 管理各种RDMA资源,为用户态提供服务
- ko
Mellanox ConnectX-5网卡的内核态驱动模块,负责直接和硬件交互。
- 硬件
指Mellanox ConnectX-5网卡。
数据路径
绕过内核(快路径);
不需要陷入内核的Verbs接口走的是左边红色箭头的”快路径“:
控制路径
控制路径上,用户态和内核态主要是通过系统调用来对/dev/infiniband/uverbsN字符设备文件进行操作的,从而实现交流信息的。最近的协议栈也支持了ioctl()系统调用需要陷入内核态的接口,走的是标红色箭头的“慢路径”: