RDMA 关键技术研究:MR Memory Region

最后更新: 2026-04-07, 作者: HAO022

为什么需要 Memory Region

首先这是一块内存,且该内存主要用于RDMA 收发数据的通信场景,实际上RDMA 硬件绕过了操作系统内核直接访问这块内存。因此需要解决如下问题:

  • 安全性和权限隔离:控制对本地、远程内存的读写,原子操作权限。Memory Region 提供秘钥机制,保存,验证由 HCA 硬件生成的本地、远程访问秘钥。
  • 物理地址映射:将进程虚拟地址 VA 转化为 HCA 硬件可访问的IOVA、PV。 即 Memory Region MTT(Memory Translation Table)机制。
  • 物理地址管理:要确保这块用于硬件读写的内存,不能被操作系统回收释放,换页,因此需要对物理页进行锁页。
  • 总结:Memory Region 为后续的所有的内存操作提供条件。

如何使用

ibverbs api:
struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, enum ibv_access_flags access);
  • pd 指定注册内存域所在的保护域
  • addr length 进程虚拟地址和长度
  • access 访问权限
    • IBV_ACCESS_LOCAL_WRITE
    • IBV_ACCESS_REMOTE_WRITE
    • IBV_ACCESS_REMOTE_READ
    • IBV_ACCESS_REMOTE_ATOMIC
    • IBV_ACCESS_MW_BIND
  • 进程的任何虚拟地址都是可以注册的,例如:
    • Local memory (either variable or array)
    • Global memory (either variable or array)
    • Dynamically allocated memory (using malloc() or mmap())
    • Shared memory
    • Addresses from the text segment
  • 该函数执行存在耗时,不适合在快速转发的数据平面使用

核心实现

  • ibv_reg_mr 最终调用到 HCA ib_device_ops.reg_user_mr

    struct ib_device_ops mlx5_ib_dev_ops = {
            .reg_user_mr = mlx5_ib_reg_user_mr,
    };
    
    mlx5_ib_reg_user_mr
            ...
            umem = ib_umem_get(&dev->ib_dev, start, length, access_flags);
            return create_real_mr(pd, umem, iova, access_flags);
    
    reg_create
            // 填充 MTT
            mlx5_ib_populate_pas(...)
    
            // 填写 MKey Context
            MLX5_SET(mkc, mkc, free, !populate);
            MLX5_SET(mkc, mkc, access_mode_1_0, access_mode);
            MLX5_SET(mkc, mkc, umr_en, 1);
            MLX5_SET64(mkc, mkc, len, umem->length);
            MLX5_SET(mkc, mkc, translations_octword_size,
            MLX5_SET(mkc, mkc, log_page_size, mr->page_shift);
            ...
    
  • mlx5_ib_reg_user_mr 函数主要完成:

    • ib_umem_get - pin and dma map userspace memory.
    • 注册内存区域,创建填写 VA to IOVA/PA 映射表 MTT
    • 创建 ib_mr,其中 lkey 为由硬件生成本地访问密钥
  • ib_umem_get

    • pin_user_pages 锁页防止换页(该函数遍历页表触发缺页异常、分配物理内存)
    • ib_dma_map_sgtable 物理页和 iommu 地址映射
    • 映射的组织图如下:
  • reg_create

    • 构建 MKey Context 并发送到 HCA。MKey Context 详细描述了 VA 信息、MTT 属性以及可以翻译成 IOVA/PA 的 MTT 表
    • 返回硬件生成的 lkey, rkey
  • MLX5_IB_UPD_XLT_ENABLE

    • 是否启用硬件网卡对内存地址转换表(如MTT表或间接表)的动态更新能力(动态更新而非删除再创建memory region mtt)
    • Mellanox MTT/MKey 硬件配置

MTT

  • IOMMU 关系:系统启用IOMMU的情况下,MTT 表存储的是IOVA,IOMMU 完成 IOVA 到 PA的转化。若未启用IOMMU,MTT表直接存储物理地址
  • Mellanox HCA 硬件: 在注册内存域的场景使用的 Direct MKey

思考

  • Memory Region 锁页

    • 如果不把进程VA对应物理地址锁页,那么在系统内存资源紧张时,这块物理内存很容易被回收掉。此后如果执行DMA写操作,那么极大可能会写到其他进程空间或者系统内存空间,导致系统不可用。
    • Memory Region 内存是长期的并且是重复使用的,因此长期通信的过程,锁页也是一种性能的考虑。
  • 内核协议栈

    • 内核协议栈负责具体的数据包收发,接收流程一般使用 dev_alloc_pages,发送流程 skb_page_frag_refill alloc_pages
    • MIGRATE_UNMOVABLE 内存不会被回收
  • 用户态协议栈 收发数据是否需要锁页?

    • 如果基于 DPDK 实现的用户态协议栈,且使用的默认大页内存,则不需要锁页,大页不支持swap。
    • 如果 DPDK 配置小页申请内存,则需要考虑锁页。

篇尾:

  • HUATUO 华佗是由滴滴开源并依托 CCF 孵化的操作系统深度观测项目。
  • 关注微信公众号,或扫码加微信,邀请你加入用户群(请备注姓名+单位):

微信