rdma 连接管理器驱动程序模式

rdma connection manager driver pattern

我正在为我的应用程序使用 Infiniband 驱动程序的 OFED 3.18r2 实现。特别是我正在使用 rdma 连接管理器包装函数。为了更好地理解幕后发生的事情,我习惯于查看源代码。这样做我遇到了一些看起来像模式但我无法理解的东西。让我们举个例子。 rdma 连接管理器函数在 cma.c 中。查看 rdma_listen 调用的示例(这对库中定义的几乎所有以 "rdma_" 开头的函数都很常见):

int rdma_listen(struct rdma_cm_id *id, int backlog)
{
    struct ucma_abi_listen cmd;
    struct cma_id_private *id_priv;
    int ret;

    CMA_INIT_CMD(&cmd, sizeof cmd, LISTEN);
    id_priv = container_of(id, struct cma_id_private, id);
    cmd.id = id_priv->handle;
    cmd.backlog = backlog;

    ret = write(id->channel->fd, &cmd, sizeof cmd);
    if (ret != sizeof cmd)
        return (ret >= 0) ? ERR(ENODATA) : -1;

    if (af_ib_support)
        return ucma_query_addr(id);
    else
        return ucma_query_route(id);
}

在这里你可以看到我之前提到的模式:

ret = write(id->channel->fd, &cmd, sizeof cmd);

write 调用的第一个参数是与 /dev/infiniband/rdma_cm 关联的文件描述符,但我无法理解 cmd 的用法 个参数。我深入研究源代码才发现 cmd 是一个结构,用于 rdma cm 函数调用的 ABI 定义。我真的不明白这是否是执行设备驱动程序调用的常见模式及其工作原理,与 cmd 参数关联的真实代码在哪里。 你能帮帮我吗?

使用write()系统调用执行命令是RDMA子系统中执行命令的常用方法。 rdma_ucm 模块和 ib_uverbs 模块使用它。与 rdma_ucm 关联的内核代码可以在 drivers/infiniband/core/ucma.c 文件中找到。具体来说,这个设备的write()系统调用是在ucma_write()函数中实现的。

我认为没有很多文档介绍这种调用驱动程序的方法。内核文档中的 user_verbs.txt 文档指出:

Commands are sent to the kernel via write()s on these device files.
The ABI is defined in drivers/infiniband/include/ib_user_verbs.h.
The structs for commands that require a response from the kernel
contain a 64-bit field used to pass a pointer to an output buffer.
Status is returned to userspace as the return value of the write()
system call.

我认为这可能是对 write() 系统调用的一种小滥用,它实现了更类似于 ioctl() 的东西。

编辑:请注意,我在上游内核模块中添加了一个 link,但 OFED 源代码结构类似。 编辑:添加了一些文档指针。