DOCA 文档 v2.10.0

DOCA 存储零拷贝目标 RDMA 应用程序指南

DOCA 存储零拷贝目标 RDMA (target_rdma) 充当模拟存储服务,准备与 doca_storage_zero_copy_initiator_comch (initiator_comch) 创建的块大小相等的内存区域。此应用程序等待来自 doca_storage_zero_copy_comch_to_rdma (comch_to_rdma) 的 IO 消息,并执行必要的 RDMA 读取或写入操作,以满足发起者的读取或写入请求(即,对于读取 IO 消息的 RDMA 写入,对于写入 IO 消息的 DMA 读取)。

DOCA 存储零拷贝目标 RDMA 使用 TCP 套接字进行带外控制消息,然后使用两个 DOCA RDMA 连接

  • 一个用于数据路径,以接收和回复 IO 消息;以及

  • 另一个用于执行 RDMA 读取和写入操作,这些操作实际上将数据移动到或从 initiator_comch 创建的内存

target_system_design-version-1-modificationdate-1734470142640-api-v2.png

DOCA 存储零拷贝目标 RDMA 在三个阶段执行

  1. 准备.

  2. 数据路径.

  3. 拆卸.

准备阶段

在此阶段,应用程序执行以下操作

  1. 创建 TCP 服务器套接字。

  2. 等待 comch_to_rdma 连接。

  3. 等待来自 comch_to_rdma 的配置数据路径控制消息(缓冲区计数、缓冲区大小、doca_mmap 导出详细信息)。

    1. 导入接收到的 doca_mmap。

    2. 创建本地内存区域。

    3. 创建本地 doca_mmap。

    4. 创建 doca_buf_inventory

    5. 向 comch_to_rdma 发送配置数据路径控制消息响应。

  4. 等待来自 comch_to_rdma 的 N 个“创建 RDMA 连接”控制消息。

    1. 创建 RDMA 上下文。

    2. 导出连接详细信息。

    3. 使用提供的远程连接详细信息开始连接。

    4. 向 comch_to_rdma 发送创建 RDMA 连接控制消息响应。

  5. 等待来自 comch_to_rdma 的“启动数据路径连接”控制消息。

    1. 验证所有 RDMA 连接是否准备就绪。

    2. 向 comch_to_rdma 发送启动数据路径连接控制消息响应。

  6. 等待来自 comch_to_rdma 的启动存储控制消息。

    1. 启动数据路径线程。

    2. 向 comch_to_rdma 发送启动存储控制消息响应。

target_preparation_stage-version-1-modificationdate-1734470142300-api-v2.png

数据路径阶段

在此阶段,数据路径线程启动。每个线程首先提交接收 RDMA 任务,然后执行一个紧密循环并尽可能快地轮询 进度引擎 (PE),直到收到“数据路径停止”IO 消息。

处理 IO 消息的过程涉及以下步骤

  1. 确定用于解码 IO 消息的内存位置。

  2. 提交 RDMA 读取/RDMA 写入操作。

  3. 在 RDMA 读取/写入完成后,向 BlueField 发送响应 IO 消息。

  4. 重新提交 RDMA 接收任务。

拆卸阶段

在此阶段,应用程序执行以下操作

  1. 等待来自的销毁对象控制消息。

  2. 销毁数据路径对象。

  3. 向 comch_to_rdma 发送销毁对象控制消息响应。

  4. 销毁控制路径对象。

此应用程序利用以下 DOCA 库

此应用程序作为存储零拷贝应用程序集的一部分进行编译。有关编译说明,请参阅 NVIDIA DOCA 存储零拷贝

应用程序执行

DOCA 存储零拷贝 Comch to RDMA 以源代码形式提供。因此,在执行应用程序之前需要进行编译。

  • 应用程序使用说明

    复制
    已复制!
                

    Usage: doca_storage_zero_copy_target_rdma [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 level for the program <10=DISABLE, 20=CRITICAL, 30=ERROR, 40=WARNING, 50=INFO, 60=DEBUG, 70=TRACE>   --sdk-log-level                   Set the SDK (numeric) log level for the program <10=DISABLE, 20=CRITICAL, 30=ERROR, 40=WARNING, 50=INFO, 60=DEBUG, 70=TRACE>   -j, --json <path>                 Parse all command flags from an input json file   Program Flags:   -d, --device                      Device identifier   -r, --representor                 Device host side representor identifier   --listen-port                     TCP Port on which to listen for incoming connections   --cpu                             CPU core to which the process affinity can be set

    信息

    此用法打印输出可以使用 -h(或 --help)选项打印到命令行

    复制
    已复制!
                

    ./ doca_storage_zero_copy_target_rdma -h

    有关更多信息,请参阅“命令行标志”部分。

  • 在 BlueField 上运行应用程序的 CLI 示例

    复制
    已复制!
                

    ./doca_storage_zero_copy_target_rdma -d 03:00.0 --listen-port 12345 --cpu 12

    信息

    DOCA 设备 PCIe 地址 3b:00.0 应与所需 PCIe 设备的地址匹配。

  • 该应用程序还支持基于 JSON 的部署模式,其中所有命令行参数都通过 JSON 文件提供

    复制
    已复制!
                

    ./doca_storage_zero_copy_target_rdma --json [json_file]

    例如

    复制
    已复制!
                

    ./doca_storage_zero_copy_target_rdma --json doca_storage_zero_copy_comch_to_rdma_params.json

    注意

    在执行之前,请确保使用的 JSON 文件包含正确的配置参数,尤其是部署所需的 PCIe 地址。

命令行标志

标志类型

短标志

长标志/JSON 键

描述

JSON 内容

通用标志

h

help

打印帮助摘要

N/A

v

version

打印程序版本信息

N/A

l

log-level

设置应用程序的日志级别

  • DISABLE=10

  • CRITICAL=20

  • ERROR=30

  • WARNING=40

  • INFO=50

  • DEBUG=60

  • TRACE=70(需要使用 TRACE 日志级别支持进行编译)

复制
已复制!
            

"log-level": 60

N/A

sdk-log-level

设置程序的日志级别

  • DISABLE=10

  • CRITICAL=20

  • ERROR=30

  • WARNING=40

  • INFO=50

  • DEBUG=60

  • TRACE=70

复制
已复制!
            

"sdk-log-level": 40

j

json

从输入 JSON 文件解析所有命令标志

N/A

程序标志

d

device

DOCA 设备标识符。以下之一

  • PCIe 地址 – 3b:00.0

  • InfiniBand 名称 – mlx5_0

  • 网络接口名称 – en3f0pf0sf0

注意

这是一个强制性标志。

复制
已复制!
            

"device": "03:00.0"

N/A

--listen-port

用于侦听传入连接的 TCP 端口

注意

这是一个强制性标志。

复制
已复制!
            

"lister-port": 12345

N/A

--cpu

要使用的 CPU 索引。每个 CPU 衍生一个数据路径线程。索引从 0 开始。

注意

用户可以多次指定此参数以创建更多线程。

注意

这是一个强制性标志。

复制
已复制!
            

"cpu": 6


故障排除

有关 DOCA 应用程序的安装或执行中遇到的任何问题,请参阅 DOCA 故障排除

控制线程流程

  1. 解析应用程序参数

    复制
    已复制!
                

    auto const cfg = parse_cli_args(argc, argv);

    1. 准备解析器 (doca_argp_init)。

    2. 注册参数 (doca_argp_param_create)。

    3. 解析参数 (doca_argp_start)。

    4. 销毁解析器 (doca_argp_destroy)。

  2. 显示配置

    复制
    已复制!
                

    print_config(cfg);

  3. 创建应用程序实例

    复制
    已复制!
                

    g_app.reset(storage::zero_copy::make_storage_application(cfg));

  4. 运行应用程序

    复制
    已复制!
                

    g_app->run()

    1. 查找并打开指定的设备

      复制
      已复制!
                  

      m_dev = storage::common::open_device(m_cfg.device_id);

    2. 启动 TCP 服务器并等待 comch_to_rdma 连接

      复制
      已复制!
                  

      start_listening(); wait_for_tcp_client();

    3. 等待来自 comch_to_rdma 的“配置存储”控制消息。

    4. 配置存储

      复制
      已复制!
                  

      configure_storage(configuration);

      1. 创建线程上下文

        1. 创建事务上下文。

        2. 创建 IO 消息。

        3. 创建 PE。

        4. 为 IO 消息缓冲区创建 mmap。

    5. 向 comch_to_rdma 发送配置存储控制消息响应。

    6. 等待来自 comch_to_rdma 的 N 个“创建 RDMA 连接”控制消息

      1. 创建 RDMA 上下文。

      2. 导出连接详细信息。

      3. 使用接收到的远程连接详细信息启动连接。

      4. 向 comch_to_rdma 发送“创建 RDMA 连接”控制消息响应(包含来自 target_rdma RDMA 上下文的 RDMA 连接详细信息)。

    7. 等待来自 comch_to_rdma 的“启动数据路径”控制消息

      1. 验证所有连接是否准备就绪(comch 和 RDMA)

        复制
        已复制!
                    

        establish_rdma_connections();

    8. 向 comch_to_rdma 发送“启动存储”控制消息响应。

    9. 等待来自 comch_to_rdma 的启动存储控制消息

      1. 创建数据路径线程。

      2. 启动数据路径线程。

    10. 向 comch_to_rdma 发送“启动存储”控制消息响应。

    11. 运行所有线程直到完成。

    12. 等待“销毁对象”控制消息。

    13. 销毁数据路径对象。

    14. 向 BlueField 发送销毁对象控制消息响应。

  5. 显示统计信息

    复制
    已复制!
                

    printf("+================================================+\n"); printf("| Stats\n"); printf("+================================================+\n"); for (uint32_t ii = 0; ii != stats.size(); ++ii) { printf("| Thread[%u]\n", ii); auto const pe_hit_rate_pct = (static_cast<double>(stats[ii].pe_hit_count) / (static_cast<double>(stats[ii].pe_hit_count) + static_cast<double>(stats[ii].pe_miss_count))) * 100.; printf("| PE hit rate: %2.03lf%% (%lu:%lu)\n", pe_hit_rate_pct, stats[ii].pe_hit_count, stats[ii].pe_miss_count);   printf("+------------------------------------------------+\n"); } printf("+================================================+\n");

  6. 销毁控制路径对象。

性能数据路径线程流程

数据路径涉及尽可能快地轮询 PE 以接收来自 BlueField 的 IO 消息。

  1. 运行直到 BlueField 发送停止 IO 消息

    复制
    已复制!
                

    while (hot_data->running_flag) { doca_pe_progress(pe) ? ++(hot_data->pe_hit_count) : ++(hot_data->pe_miss_count); }

  2. 处理 BlueField IO 消息

    1. 计算用于本地和远程内存的内存地址。

    2. 将缓冲区地址和大小设置到源缓冲区和目标缓冲区到 RDMA 任务中。

    3. 启动 RDMA 读取/写入任务。

    4. 在 RDMA 任务完成后,响应 BlueField。

    5. 重新提交 RDMA 接收任务。

  • /opt/mellanox/doca/applications/storage/

© 版权所有 2025 NVIDIA。 最后更新于 2025 年 2 月 12 日。