OFA定义了一组标准的Verbs,并提供了一个标准库libibvers。在用户态实现NVMe over RDMA的Host(i.e. Initiator)和Target, 少不了要跟OFA定义的Verbs打交道。但是,仅仅有libibverbs里的API是不够的,还需要对应的RDMA硬件的用户态驱动支持。本着“知其然更知其所以然”的精神,本文将以mlx5卡为例,分析用户态Verb API ibv_post_send()的实现原理。 分析用到的源码包有:
在用户态的libibverbs中, ibv_post_send()的源代码片段如下:
- /* libibverbs-1.2.1/include/infiniband/verbs.h#1860 */
-
- 1860 /**
- 1861 * ibv_post_send - Post a list of work requests to a send queue.
- ....
- 1865 */
- 1866 static inline int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr,
- 1867 struct ibv_send_wr **bad_wr)
- 1868 {
- 1869 return qp->context->ops.post_send(qp, wr, bad_wr);
- 1870 }
从L1869我们可以看出,post_send()是一个回调(callback)函数,跟RDMA硬件驱动密切相关。
而在mlx5卡的用户态驱动libmlx5的REDME中,我们可以看到libmlx5是一个为libibverbs准备的plug-in模块,允许应用程序在用户空间直接访问Mellanox的硬件mlx5 HCA卡。 当应用程序开发人员使用libibverbs的时候,用户态驱动libmlx5被自动加载。但是,必须首先加载mlx5卡的内核驱动(mlx5_ib.ko)以发现和使用HCA设备。那么,为什么必须率先加载mlx5_ib.ko模块?这是一个值得深究的问题。 (难道libmlx5用户态驱动没有发现HCA卡的能力?)
- $ cat -n libmlx5-1.2.1/README
- 1 Introduction
- 2 ============
- 3
- 4 libmlx5 is a userspace driver for Mellanox ConnectX InfiniBand HCAs.
- 5 It is a plug-in module for libibverbs that allows programs to use
- 6 Mellanox hardware directly from userspace. See the libibverbs package
- 7 for more information.
- 8
- 9 Using libmlx5
- 10 ==============
- 11
- 12 libmlx5 will be loaded and used automatically by programs linked with
- 13 libibverbs. The mlx5_ib kernel module must be loaded for HCA devices
- 14 to be detected and used.
要搞清楚ibv_post_send()是如何将工作请求send_wr发送到mlx5硬件上去的,我们需要搞清楚下面4个问题。