news 2026/5/16 11:27:21

从零读懂RDMA内存注册

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零读懂RDMA内存注册

在RC、RD、UC、UD操作的背后,有一个非常容易被忽略的基石——内存注册,每一个操作都依赖内存注册才能运转。

那么,为什么RDMA非要搞内存注册这套东西?答案很简单,传统的TCP程序里,你直接往send()里扔一个用户缓冲区就行,CPU的MMU会帮你把虚拟地址翻译成物理地址。但RDMA网卡不认识这套系统页表——每个CPU架构的页表格式都不一样,硬件没法通用。而且页表是核心系统资源,不能随便暴露给外部设备。 所以网卡必须有一套自己认得的路和钥匙。

一、先从入口开始:ibv_reg_mr的调用

应用程序调用ibv_reg_mr,参数有以下信息:

  1. pd:所属的protection domain(安全域);
  2. addr:起始虚拟地址;
  3. length:注册长度;
  4. access:访问权限(本地写、远程读、远程写、原子操作等);

这里有一些关键点需要注意,权限必须在注册时一次性声明完毕,运行时无法动态提升。驱动将参数发送给硬件,此时执行完毕。

二、页锁定(Pin):禁止操作系统“动”这片内存

应用程序调用ibv_reg_mr之后,驱动会遍历该虚拟地址范围内的页表,在遍历的过程中会做两件事,首先是强制触发所有缺页异常,确保物理内存被真正分配出来,其次将这些页标记为“锁住”状态,阻止内核将它们交换到磁盘或迁移到其他位置。

那么为什么要做这一步呢?

答案很简单,就是不能换页。

在传统的TCP协议栈中,软件感知的是虚拟地址,CPU中有一个MMU,会帮你把虚拟地址翻译成物理地址。所以TCP协议栈在发送数据时,CPU是全程参与的。

但是RDMA不能这么做,因为网卡是独立硬件,它只知道物理地址,并且网卡不认识CPU的页表,因为不同CPU架构的页表格式不一样,网卡也没法通用,所以网卡必须在注册时把虚拟地址到物理地址的映射关系一次性确定下来,硬编码在硬件可访问的表里。映射确定之后,物理地址就不能再变了;如果内核在注册后偷偷把页换走,网卡拿到老的物理地址去DMA,就会写进别人的内存——这是灾难性的安全问题。

三、MTT(Memory Translation Table):硬件的“页表”

锁页完成后,驱动面临一个问题,那就是网卡不认识虚拟地址。传统的CPU访问内存靠MMU查系统页表,但RDMA网卡不能直接访问系统页表,每个CPU架构的页表格式都不一样,而且页表是内核核心资源,不能随便暴露给外部设备。所以网卡必须有一套自己专用的页表结构,至此MTT(Memory Translation Table,内存翻译表)便诞生了。

每个MTT表项固定8字节,存放一个物理页的起始地址。MTT本质上是一张以页为单位的大表:注册2GB内存、4KB页大小,就需要2,097,152÷4,096≈512K个表项。但问题随之而来——MTT本身也要存放在内存里。512K个表项占用约4MB内存,这还不是最大的问题。真正的问题是:当注册的内存特别大(比如64GB),MTT表项的数量膨胀到1600万个,占用超过128MB内存,那么单级页表就非常不划算了。

为了解决这个问题,目前一般使用多级MTT结构,这和CPU的多级页表异曲同工,接下来我们来介绍一下多级页表都是干嘛的:

  1. 一级页表:存储多个物理页地址,共同构成一个空间,假设是一个2MB的空间,那么里面便会存储512个物理页地址。
  2. 二级页表:存储多个一级页表地址,共同构成一个空间,假设是一个1GB的空间,那么里面便会存储512个一级页表地址。

三级、四级依次类推,不过一般三级页表就已经可以支持很大的灵活空间了,通过这种多级链表方式进行存储后,主机内存的MTT表项的存放位置就非常灵活了。

目前linux内核中的erdma驱动已经实现了支持三级MTT,最大可注册64GB的内存区域。虽然多一级页表会多一次硬件查表开销,但换来的是可以支持任意大小的MR,而不受单页表大小的硬约束。

四、MPT(Memory Protection Table):地址簿+门禁卡

MTT解决了“怎么找到物理地址”的问题,但是还有一个问题没解决,那就是对方访问我们的内存给的是虚拟地址,那么如何映射,权限是否正确便是MPT所做的事。

MPT是硬件中的另一个核心结构,每一个注册成功的MR,硬件都会在MPT表中创建一个条目,条目里记录四样东西:这片内存的起始虚拟地址、长度、访问权限(本地写/远程读/远程写/原子操作等),以及最关键的信息——指向对应MTT的指针。

五、L_Key与R_Key:硬件生成的“门禁卡”

这是内存注册最后一步,也是最有意思的一步:硬件生成两把密钥——L_Key(本地密钥)和R_Key(远程密钥)。

L_Key用于本端SEND操作中认证本地内存的访问权限,R_Key则需要通过带外方式告知对端,用于远程RDMA访问时的权限校验。它们本质是一个整数序列,硬件内部可以用它去索引MPT表。

那为什么需要这种“门禁卡”式的设计呢,因为我们不能假设所有的操作都是合法的,通过L_Key与R_Key屏蔽全部非法操作。

当远端的请求包到达时,包里携带R_Key,接收端硬件拿着这个R_Key去查MPT,校验该R_Key对应的权限和地址是否匹配。如果攻击者截获了你的虚拟地址但没有对应的R_Key,网卡会直接拒绝访问。 硬件甚至不需要软件参与就能完成整个校验过程,这也是RDMA单边操作能绕过CPU的核心原因之一。

六、完整流程:从软件传参到硬件落表

我们将上面的流程串起来,那么这个过程就非常清晰了:

  1. 软件发起:应用程序调用ibv_reg_mr,传入起始虚拟地址、长度和访问权限;
  2. 驱动锁页:锁定物理内存,阻止操作系统将该内存换出;
  3. 构建MTT:驱动遍历虚拟地址对应的物理页,生成MTT表项,存入硬件可访问的内存中。若注册内存较大,则使用多级MTT结构;
  4. 创建MPT:硬件分配MPT条目,将VA、长度、权限和MTT地址一并写入该条目,返回L_Key和R_Key;

七、总结

RDMA内存注册的本质,是在软件虚拟地址和硬件物理地址之间架起两座桥:MTT负责“翻译”,MPT负责“保护+关联”。

如果没有这套机制,RDMA的单边操作就不可能绕过CPU。理解了MTT和MPT,你就真正理解了RDMA如何做到“硬件自己管自己”——从地址翻译到权限校验,全都卸载到网卡硬件里,CPU只负责在最开始递一下钥匙。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 11:26:20

FPGA 算法实战手册

从定点运算、CORDIC、FIR/FFT、图像处理、通信编解码到神经网络推理,覆盖 FPGA 算法实现全链路的工程实战手册 阅读说明 本手册聚焦如何在 FPGA 上高效实现各类算法——从数学运算基础到具体的信号处理、图像处理、通信、控制和人工智能算法。每个算法都提供:算法原理→硬件…

作者头像 李华
网站建设 2026/5/16 11:21:19

从数据同步工具往后看,NineData 社区版 V5.0.0 这次补齐了什么

从数据同步工具和 ChatDBA 这类能力往后看,V5.0.0 更像一次连续补强,而不是单点加功能。再结合异构数据库迁移工具这类需求,链路扩展、迁移评估和智能诊断一起往前推,社区版的可用边界也随之往前走了一步。落地之前先看这套能力框…

作者头像 李华
网站建设 2026/5/16 11:18:30

TVA 在宠物混合监护场景中的创新应用(6)

重磅预告:本专栏将独家连载新书《智能体视觉技术与应用》(系列丛书)部分精华内容,该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著,特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。…

作者头像 李华