我正在为我的应用程序使用 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 参数关联的真实代码在哪里。请你帮助我好吗?