在 Linux 内核模块中为 RDMA 注册大缓冲区

register large buffer for RDMA in Linux kernel module

我是一个在内核模块中使用 rdma (ib_verbs) 试验项目的新手。我从 krping 中获得了示例代码并对其进行了修补。系统 运行 在 64 位 Linux Centos 上带有自定义 3.10 Linux 内核,需要禁用透明大页面。 我想要一个大的(4GB 以上)RDMA read/write 能够 space,它不必是连续的,因为我很可能 write/read 一次来自远程方的最多 1MB(随机访问)。

问题:

  1. 我应该做一千次 4MB kmalloc 并注册 DMA 区域吗?使用 kmalloc 而不是 vmalloc 来分配大量内存的设计有多糟糕?我听说不应该这样做,大内存只能通过 vmalloc 检索。但是来自 vmalloc 的地址不适合 DMA。
  2. 如果不是,那么有什么好的替代方法可以让远程方随机访问 4GB 缓冲区?
  3. user-space rdma 是如何管理这种缓冲区的?我记得我只 malloc 4GB 内存并调用 ibv_reg_mr 就可以使用了。

只要您没有使用覆盖整个物理内存的内存(不推荐用于启用写入的 MR),您应该使用 IB_WR_REG_MR 工作请求来注册您的内存区域.为此,您可以使用接受散点列表和页面大小的 ib_map_mr_sg 函数。所以基本上,您可以注册一个由您选择的固定大小的块构建的 MR。

这里有一个权衡:使用较小的分配大小将使内核更容易在碎片化的系统上找到空闲内存,但另一方面它可能会降低性能,因为它会增加 NIC 的 IOTLB 上的负载。

User-space 通过调用 get_user_pages 并使用系统的页面大小(通常为 4kb)来处理大型 MR 注册。尽管某些驱动程序进行了优化以尝试在内部检测更大的页面大小,但如果 user-space 内存恰好以这种方式对齐。