我正在为我的应用程序使用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);
的
写调用的第一个参数是与 / dev / infiniband / rdma_cm 关联的文件描述符,但是我无法理解 cmd 参数的用法。我深入研究了源代码,发现 cmd 是为rdma cm函数调用的ABI定义而来的结构。我真的不明白这是执行设备驱动程序调用的常见模式及其工作原理,与cmd参数关联的实际代码在哪里。 你能帮我吗?
答案 0 :(得分:1)
使用write()
系统调用来执行命令是在RDMA子系统中执行命令的常用方法。它由rdma_ucm模块和ib_uverbs模块使用。可以在drivers/infiniband/core/ucma.c文件中找到与rdma_ucm关联的内核代码。具体而言,此设备的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()
更相似的内容。
编辑:请注意,我添加了一个指向上游内核模块的链接,但OFED源结构类似。 编辑:添加了一些文档指针。