用户空间 Verbs 访问¶
通过启用 CONFIG_INFINIBAND_USER_VERBS 构建的 ib_uverbs 模块,允许用户空间通过“verbs”直接访问 IB 硬件,如 InfiniBand 体系结构规范第 11 章所述。
要使用 verbs,需要 libibverbs 库,可从 https://github.com/linux-rdma/rdma-core 获取。 libibverbs 包含一个与设备无关的 API,用于使用 ib_uverbs 接口。 libibverbs 还需要适用于您的 InfiniBand 硬件的、适当的设备相关的内核和用户空间驱动程序。 例如,要使用 Mellanox HCA,您需要安装 ib_mthca 内核模块和 libmthca 用户空间驱动程序。
用户-内核通信¶
用户空间通过 /dev/infiniband/uverbsN 字符设备与内核进行慢速路径、资源管理操作通信。 快速路径操作通常通过直接写入 mmap() 到用户空间的硬件寄存器来执行,而无需系统调用或上下文切换到内核。
命令通过对这些设备文件进行 write() 操作发送到内核。 ABI 在 drivers/infiniband/include/ib_user_verbs.h 中定义。 需要内核响应的命令的结构包含一个 64 位字段,用于传递指向输出缓冲区的指针。 状态作为 write() 系统调用的返回值返回到用户空间。
资源管理¶
由于所有 IB 资源的创建和销毁都是通过传递到文件描述符的命令完成的,因此内核可以跟踪哪些资源附加到给定的用户空间上下文。 ib_uverbs 模块维护 idr 表,用于在内核指针和不透明的用户空间句柄之间进行转换,因此内核指针永远不会暴露给用户空间,并且用户空间无法欺骗内核以跟踪伪造的指针。
这也允许内核在进程退出时进行清理,并防止一个进程接触另一个进程的资源。
内存锁定¶
直接用户空间 I/O 要求作为潜在 I/O 目标的内存区域保持在相同的物理地址。 ib_uverbs 模块通过 get_user_pages() 和 put_page() 调用来管理内存区域的锁定和解锁。 它还计算进程的 pinned_vm 中锁定的内存量,并检查非特权进程是否超过其 RLIMIT_MEMLOCK 限制。
多次锁定的页面每次锁定都会被计数,因此 pinned_vm 的值可能高估了进程锁定的页面数。
/dev 文件¶
要使用 udev 自动创建适当的字符设备文件,可以使用如下规则:
KERNEL=="uverbs*", NAME="infiniband/%k"这将创建名为
/dev/infiniband/uverbs0等等的设备节点。 由于 InfiniBand 用户空间 verbs 应该可以安全地供非特权进程使用,因此向 udev 规则添加适当的 MODE 或 GROUP 可能很有用。