DOCA DMA
本指南提供有关构建和开发需要使用直接内存访问 (DMA) 复制内存的应用程序的说明。
DOCA DMA 提供 API,以使用硬件加速在 DOCA 缓冲区之间复制数据,支持本地和远程内存区域。
该库提供了一个 API,用于在 DOCA 缓冲区上执行 DMA 操作,这些缓冲区可以驻留在本地内存(即,在同一主机内)或 DPU 可访问的主机内存中。有关内存子系统的更多信息,请参阅DOCA Core。
使用 DOCA DMA,可以以优化的硬件加速方式轻松执行复杂的内存复制操作。
本文档适用于希望加速其应用程序内存 I/O 操作并访问非主机本地内存的软件开发人员。
此库遵循 DOCA Core Context 的架构,建议在之前阅读以下部分
基于 DOCA DMA 的应用程序可以在主机或 NVIDIA® BlueField® DPU 目标上运行。
从主机复制到 DPU 以及反之亦然仅适用于配置为在 DPU 模式下运行的 DPU,如BlueField 操作模式中所述。
DOCA DMA 是 DOCA Core 定义的 DOCA Context。有关更多信息,请参阅DOCA Core Context。
DOCA DMA 利用 DOCA Core 架构来公开异步任务/事件,这些任务/事件被卸载到硬件。
DMA 可用于按如下方式复制数据
从本地内存复制到本地内存
使用 DPU 在主机和 DPU 之间复制内存
使用主机在主机和 DPU 之间复制内存
对象
设备和设备表示
DMA 库需要 DOCA 设备才能运行。该设备用于访问内存并执行实际复制。请参阅DOCA Core 设备发现。
对于同一 BlueField DPU,使用哪个设备(PF/VF/SF)并不重要,因为所有这些设备都使用相同的硬件组件。如果有多个 DPU,则可以为每个 DPU 创建一个 DMA 实例,为每个实例提供来自不同 DPU 的设备。
要访问非本地内存(从主机到 DPU 或反之亦然),应用程序的 DPU 端必须选择具有适当表示器的设备。请参阅DOCA Core 设备表示器发现。
设备必须在 DMA 实例未被销毁的情况下保持有效。
内存缓冲区
内存复制任务需要两个 DOCA 缓冲区,其中包含目标和源。根据缓冲区的分配模式,请参阅“库存类型”部分中的表。要查找支持的内存类型,请参阅“缓冲区支持”部分中的表。
在内存复制操作期间,不得修改或读取缓冲区。
要开始使用该库,用户必须经历一个配置阶段,如DOCA Core Context 配置阶段中所述。
本节介绍如何配置和启动上下文,以允许执行任务和检索事件。
配置
可以配置上下文以匹配应用程序用例。
要查找是否支持配置,或其最小/最大值是多少,请参阅“设备支持”部分。
强制配置
这些配置是强制性的,必须由应用程序在尝试启动上下文之前设置
设备支持
DOCA DMA 需要设备才能运行。要选择设备,请参阅“DOCA Core 设备发现”。
由于设备功能可能会更改(请参阅DOCA Core 设备支持),建议使用以下方法选择设备
doca_dma_cap_task_memcpy_is_supported
某些设备可以允许不同的功能,如下所示
最大任务数
最大缓冲区大小
缓冲区支持
任务支持具有以下功能的缓冲区
缓冲区类型 | 源缓冲区 | 目标缓冲区 |
本地 mmap 缓冲区 | 是 | 是 |
来自 PCIe 导出的 mmap 缓冲区 | 是 | 是 |
来自 RDMA 导出的 mmap 缓冲区 | 否 | 否 |
链表缓冲区 | 是 | 否 |
本节介绍如何使用 DOCA Core Progress Engine 在 CPU 上执行。
任务
DOCA DMA 公开异步任务,这些任务根据 DOCA Core 架构利用 DPU 硬件。请参阅DOCA Core 任务。
内存复制任务
内存复制任务允许将内存从一个位置复制到另一个位置。使用缓冲区支持中描述的缓冲区。
任务配置
描述 | 用于设置配置的 API | 用于查询支持的 API |
启用任务 |
|
|
任务数 |
|
|
最大缓冲区大小 | – |
|
最大缓冲区列表大小 | – |
|
任务输入
与DOCA Core 任务中描述的通用输入相同。
名称 | 描述 | 注释 |
源缓冲区 | 指向要复制的内存的缓冲区 | 仅复制数据段中驻留的数据 |
目标缓冲区 | 指向内存复制位置的缓冲区 | 数据被复制到尾部段,从而扩展数据段 |
任务输出
与DOCA Core 任务中描述的通用输出相同。
任务完成成功
任务成功完成后
数据从源复制到目标
目标缓冲区数据段被扩展以包含复制的数据
任务完成失败
如果任务中途失败
如果发生致命错误,上下文可能会进入停止状态
源和目标
doca_buf
对象未被修改目标缓冲区内容可能会被修改
任务限制
操作不是原子性的
一旦提交了任务,就不应读取/写入源和目标
源和目标不得重叠
其他限制在DOCA Core 任务中描述
事件
DOCA DMA 公开异步事件,以根据DOCA Core 架构通知意外发生的更改。
DMA 公开的唯一事件是DOCA Core 事件中描述的通用事件。
DOCA DMA 库遵循DOCA Core Context 状态机中描述的 Context 状态机。
以下部分描述如何移动状态以及每个状态允许的操作。
空闲
在此状态下,应用程序应
销毁上下文
启动上下文
允许的操作
根据“配置”部分配置上下文
启动上下文
可以通过以下方式达到此状态
先前状态 | 转换操作 |
无 | 创建上下文 |
运行中 | 在确保所有任务都已释放后调用 stop |
停止中 | 调用 progress 直到所有任务都已完成并释放 |
启动中
无法达到此状态。
运行中
在此状态下,应用程序应
分配和提交任务
调用 progress 以完成任务和/或接收事件
允许的操作
分配先前配置的任务
提交任务
调用 stop
可以通过以下方式达到此状态
先前状态 | 转换操作 |
空闲 | 配置后调用 start |
停止中
在此状态下,应用程序应
调用 progress 以完成所有正在进行的任务(任务完成失败)
释放任何已完成的任务
允许的操作
调用 progress
可以通过以下方式达到此状态
先前状态 | 转换操作 |
运行中 | 调用 progress 且发生致命错误 |
运行中 | 在未释放所有任务的情况下调用 stop |
DOCA DMA 允许在 CPU 或 GPU 上运行数据路径。
对于 CPU 数据路径,请参阅执行阶段。
GPU 数据路径
DOCA 提供 DOCA GPUNetIO 库,该库为将通信编排卸载到 GPU CUDA 内核提供了编程模型。
用户可以通过以下方式配置应用程序使用的 DOCA DMA 上下文,从而在 GPU 数据路径上运行 DMA 操作
通过调用
doca_dma_as_ctx()
获取 DOCA CTX。通过调用
doca_ctx_set_datapath_on_gpu()
将上下文的数据路径设置为 GPU。有关更多信息,请参阅DOCA Core 替代数据路径。通过调用
doca_ctx_start()
完成上下文配置并启动上下文。有关更多信息,请参阅DOCA Core Context。
配置数据路径后,用户可以通过调用 doca_dma_get_gpu_handle()
获取 DOCA RDMA 上下文的 GPU 句柄。GPU 句柄必须传递给 GPU CUDA 内核,以便 DOCA GPUNetIO CUDA 设备功能可以执行数据路径操作。有关更多信息,请参阅 DOCA GPUNetIO 库文档下的“GPU 功能 – RDMA”部分。
本节介绍基于 DOCA DMA 库的 DOCA DMA 示例。
这些示例说明了如何使用 DOCA DMA API 执行以下操作
将本地缓冲区的内容复制到另一个缓冲区
使用 DPU 将主机上的缓冲区内容复制到本地缓冲区
本节中描述的所有 DOCA 示例均受 BSD-3 软件许可协议管辖。
运行示例
请参阅以下文档
DOCA Linux 安装指南,了解有关如何安装 BlueField 相关软件的详细信息。
DOCA 故障排除,了解您在 DOCA 示例的安装、编译或执行中可能遇到的任何问题。
要构建给定的示例
cd
/opt/mellanox/doca/samples/doca_dma/dma_local_copy meson /tmp/build ninja -C /tmp/build二进制文件
doca_dma_local_copy
在/tmp/build/
下创建。示例(例如,
doca_dma_local_copy
)用法Usage: doca_<sample_name> [DOCA Flags] [Program Flags] DOCA Flags: -h, --help Print a help synopsis -
v
, --version Print program version information -l, --log-level Set the (numeric) log levelfor
the program <10=DISABLE, 20=CRITICAL, 30=ERROR, 40=WARNING, 50=INFO, 60=DEBUG, 70=TRACE> -j, --json <path> Parse allcommand
flags from an input jsonfile
Program Flags: -p, --pci_addr <PCI-ADDRESS> PCI device address -t, --text Text to DMA copy有关每个示例的更多信息,请使用
-h
选项/tmp/build/<sample_name> -h
示例
DMA 本地复制
本示例说明如何使用 DMA 将内存从 DPU 上的一个缓冲区本地复制到另一个缓冲区。此示例应在 DPU 上运行。
示例逻辑包括
定位 DOCA 设备。
初始化所需的 DOCA core 结构。
使用两个相关缓冲区填充 DOCA 内存映射。
为每个缓冲区在 DOCA 缓冲区清单中分配元素。
初始化 DOCA DMA 内存复制任务对象。
提交 DMA 任务。
处理任务完成(完成后)。
检查任务结果。
销毁所有 DMA 和 DOCA core 结构。
参考
/opt/mellanox/doca/samples/doca_dma/dma_local_copy/dma_local_copy_sample.c
/opt/mellanox/doca/samples/doca_dma/dma_local_copy/dma_local_copy_main.c
/opt/mellanox/doca/samples/doca_dma/dma_local_copy/meson.build
DMA 复制 DPU
本示例应仅在 DMA 复制主机 运行后以及所需的配置文件(描述符和缓冲区)已复制到 DPU 后运行。
本示例说明如何使用 DMA 将内存(其中包含用户定义的文本)从 x86 主机复制到 DPU。此示例应在 DPU 上运行。
示例逻辑包括
定位 DOCA 设备。
初始化所需的 DOCA core 结构。
读取配置文件并将它们的内容保存到本地缓冲区中。
分配本地目标缓冲区,主机文本将保存在其中。
使用目标缓冲区填充 DOCA 内存映射。
使用导出描述符文件创建远程内存映射。
创建到远程缓冲区的内存映射。
为每个缓冲区在 DOCA 缓冲区清单中分配元素。
初始化 DOCA DMA 内存复制任务对象。
提交 DMA 任务。
处理任务完成(完成后)。
检查 DMA 任务结果。
如果 DMA 任务成功结束,则将已复制的文本打印到日志。
打印到日志,主机端示例可以关闭。
销毁所有 DMA 和 DOCA core 结构。
参考
/opt/mellanox/doca/samples/doca_dma/dma_copy_dpu/dma_copy_dpu_sample.c
/opt/mellanox/doca/samples/doca_dma/dma_copy_dpu/dma_copy_dpu_main.c
/opt/mellanox/doca/samples/doca_dma/dma_copy_dpu/meson.build
DMA 复制主机
本示例应首先运行。用户有责任将两个配置文件(描述符和缓冲区)传输到 DPU,并将它们的路径提供给 DMA 复制 DPU 示例。
本示例说明如何允许使用 DMA 将内存从 x86 主机复制到 DPU。此示例应在主机上运行。
示例逻辑包括
定位 DOCA 设备。
初始化所需的 DOCA core 结构。
使用源缓冲区填充 DOCA 内存映射。
导出内存映射。
将导出描述符和本地 DMA 缓冲区信息保存到文件中。这些文件应在运行 DPU 示例之前传输到 DPU。
等待直到 DPU DMA 示例完成。
销毁所有 DMA 和 DOCA core 结构。
参考
/opt/mellanox/doca/samples/doca_dma/dma_copy_host/dma_copy_host_sample.c
/opt/mellanox/doca/samples/doca_dma/dma_copy_host/dma_copy_host_main.c
/opt/mellanox/doca/samples/doca_dma/dma_copy_host/meson.build