函数说明

原文:ibv_reg_mr() - RDMAmojo RDMAmojo

struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr,size_t length, enum ibv_access_flags access);

描述

ibv_reg_mr() 注册与Protection Domain关联的内存区域 (MR)。通过这样做,允许 RDMA 设备向该内存读取和写入数据。执行此注册需要一些时间,因此当需要快速响应时,不建议在数据路径中执行内存注册。

每次成功注册都会产生一个 MR((在特定 RDMA 设备内)具有唯一lkey 和 rkey 值)。
MR 的起始地址是 addr,它的大小是 length。可以注册的块的最大大小限制为 device_attr.max_mr_size。调用它的进程的虚拟空间中的每个内存地址都可以注册,包括但不限于:

  • 本地内存(变量或数组)
  • 全局内存(变量或数组)
  • 动态分配的内存(使用 malloc() 或 mmap())
  • 共享内存
  • 来自文本段的地址

注册的内存缓冲区不必是页面对齐的。
没有任何方法可以知道能为特定设备注册总大小是多少的内存。

参数 access 描述了 RDMA 设备所需的内存访问属性。它是 0 或以下一个或多个标志的按位或:

IBV_ACCESS_LOCAL_WRITE 启用本地写访问:内存区域可用于接收请求或 IBV_WR_ATOMIC_CMP_AND_SWP 或
IBV_WR_ATOMIC_FETCH_AND_ADD 在本地写入远程内容值
IBV_ACCESS_REMOTE_WRITE 启用远程写访问。可以使用IBV_WR_RDMA_WRITE或IBV_WR_RDMA_WRITE从远程环境中访问内存区域。
IBV_ACCESS_REMOTE_READ 启用远程读取访问:可以使用 IBV_WR_RDMA_READ 从远程环境中访问内存区域
IBV_ACCESS_REMOTE_ATOMIC 启用远程原子操作访问(如果支持)。可以使用IBV_WR_ATOMIC_CMP_AND_SWP或IBV_WR_ATOMIC_CMP_AND_SWP从远程环境访问内存区域。
 
IBV_ACCESS_MW_BIND 启用内存窗口绑定

如果设置了 IBV_ACCESS_REMOTE_WRITE 或 IBV_ACCESS_REMOTE_ATOMIC,那么IBV_ACCESS_LOCAL_WRITE也必须被设置,因为只有在允许本地写入的情况下才允许远程写入。

MR 始终enabled 本地读取访问,即可以使用 IBV_WR_SEND、IBV_WR_SEND_WITH_IMM、IBV_WR_RDMA_WRITE、IBV_WR_RDMA_WRITE_WITH_IMM 在本地读取内存区域。

内存注册请求的权限可以是该内存块在操作系统下的权限的全部或子集。例如:操作系统下只读内存不能注册有写权限(本地或远程)。

一个特定的进程可以注册一个或多个内存区域。

参数

Name Direction Description
pd in

从 ibv_alloc_pd() 返回的Protection Domain

addr in

虚拟连续内存块的起始地址

length in 要注册的内存块的大小,以字节为单位。该值必须至少为 1 且小于 dev_cap.max_mr_size
access in 请求的内存区域访问权限

返回值

Value Description
MR Pointer to the newly allocated Memory Region.
This pointer also contains the following fields:

lkey The value that will be used to refer to this MR using a local access
rkey The value that will be used to refer to this MR using a remote access

Those values may be equal, but this isn't always guaranteed.

NULL On failure, errno indicates the failure reason:

EINVAL Invalid access value
ENOMEM Not enough resources (either in operating system or in RDMA device) to complete this operation

例子

注册一个 MR 以只允许本地读写访问并注销它:

struct ibv_pd *pd;
struct ibv_mr *mr;mr = ibv_reg_mr(pd, buf, size, IBV_ACCESS_LOCAL_WRITE);
if (!mr) {fprintf(stderr, "Error, ibv_reg_mr() failed\n");return -1;
}if (ibv_dereg_mr(mr)) {fprintf(stderr, "Error, ibv_dereg_mr() failed\n");return -1;

注册一个 MR 以允许对其进行远程读写:

mr = ibv_reg_mr(pd, buf, size, IBV_ACCESS_LOCAL_WRITE |IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ);
if (!mr) {fprintf(stderr, "Error, ibv_reg_mr() failed\n");return -1;
}

常见问题

为什么 MR 有好处?

MR 注册是一个过程, RDMA 设备获取内存缓冲区并准备将其用于本地和/或远程访问。

我可以多次注册同一个内存块吗?

是的。可以多次注册同一个内存块或其中的一部分。甚至可以使用不同的访问标志来执行这些内存注册。

可以注册的总内存大小是多少?

没有任何方法可以知道可以注册的内存总大小是多少。理论上,这个值没有任何限制。但是,如果您希望注册大量内存(数百 GB),那么low-level drivers的默认值可能还不够;查看"Device Specific"部分以了解如何更改默认参数值以解决此问题。

我是否可以用比操作系统允许的更多的权限访问使用RDMA设备的内存?

否。在内存注册期间,驱动程序会检查内存块的权限,并检查请求的权限超出系统分配给该内存块的权限。

我可以在没有此注册的情况下在 RDMA 中使用内存块吗?

基本上不行。但是,有些 RDMA 设备可以在不需要内存注册(内联数据发送)的情况下读取内存。

ibv_reg_mr() 失败,这是什么原因?

由于以下原因,ibv_reg_mr() 可能会失败:

  • 错误的属性:错误的权限或错误的内存缓冲区
  • 没有足够的资源来注册此内存缓冲区

如果这是您注册的第一个缓冲区,则可能是第一个原因。如果已经注册了很多缓冲区后内存注册失败,可能是因为没有足够的资源来注册这个内存缓冲区:大多数时候,RDMA设备中用于虚拟地址转换的资源=>实际地址。在这种情况下,您可能需要检查如何增加此 RDMA 设备可以注册的内存量。

我可以在我的进程中注册多个 MR 吗?

是的你可以。

Device Specific

Mellanox Technologies

ibv_reg_mr() failed, what is the reason for this?

If you are using one of the ConnectX HCAs family, it is a matter of configuration; you should increase the total size of memory that can be registered. This can be accomplished by setting the value of the parameter log_num_mtt of the module mlx4_core.

Adding the following line to the file /etc/modprobe.conf or to /etc/modprobe.d/mlx4_core.conf (depends on the Linux distribution that you are using) should solve this problem:
options mlx4_core log_num_mtt=24

理解内存注册(Memory Registration)

摘自:[SPDK/NVMe存储技术分析]015 - 理解内存注册(Memory Registration) - vlhn - 博客园

使用RDMA, 必然关系到内存区域(Memory Region)的注册问题。在本文中,我们将以mlx5 HCA(HCA:在Infiniband/RoCE规范中,将RDMA网卡称为HCA,全称为Host Channel Adapter)卡为例回答如下几个问题:

  1. 为什么需要注册内存区域?
  2. 注册内存区域有嘛好处?
  3. 注册内存区域的实现过程

1. 为什么需要注册内存区域?

RDMA引擎也是一种DMA引擎,由于DMA设备只访问物理内存地址,因此,DMA引擎需要主机系统内存的物理地址连续,这一点无可非议,因为如果物理地址不连续,即便DMA引擎知道buffer开始的地址(虚拟地址)和buffer长度,也不知道怎么搬数据。

试想一下,如果让DMA引擎知道如何将主机系统内存的虚拟地址(VA)如何翻译成对应的物理地址(PA),先姑且不论设计和实现DMA引擎的固件(firemware)有多么复杂,从常理上讲也说不通,本来是应该由操作系统的驱动干的事情,为啥让固件去干?设计网卡及I/O卡固件的人哪管你操作系统是Linux还是Windows?! 而且,各种I/O卡的DMA引擎相对于主机(Host)的CPU和系统内存(System Memory)来说,不过就是一帮打杂的伙计而已,让伙计们知道主人怎么管理系统内存虚拟地址与物理地址的映射关系,从宏观设计的角度讲,完全没有那个必要。

        当然,RDMA对内存区域的使用还有特殊要求。

  • 01 - 在数据传输过程中,应用程序不得修改相应的内存buffer里的内容,因为工作请求(WR)放知道工作队列上,其完成状态就完全受控于RDMA网卡了;
  • 02 - 内存buffer的物理地址与虚拟地址映射关系必须是固定的,在数据传输过程中,对应的内存页不得被操作系统交换出去。

换句话说,一旦注册了某个内存区域,该区域就将被RDMA硬件所访问。那么,内存注册意味着发生了如下两件事情:

  • 01 - 内存区域被操作系统内核锁定,防止物理地址(内存里存放的数据)被交换到硬盘上。(在Linux操作系统中,使用mlock调用来执行这一操作)
  • 02 - (系统执行)RDMA硬件的驱动(的程序)将虚拟内存地址转换为物理内存地址,然后将这一对应关系交给RDMA硬件去使用。

特别说明: 虚拟地址连续 != 物理地址连续,下面引用IBTA技术规范中给出的一张图(注册之后的虚拟内存缓冲区与物理内存页的映射关系),一目了然!

2. 注册内存区域有嘛好处?

注册内存区域本质上就是Memory Pinning(内存固定),因为典型的DMA操作通常就需要Memory Pinning。

被注册的内存区域在数据传输完成之前不被打扰,最大的好处就是保证了RDMA数据传输的高吞吐量。

注: 关于Pinned and Non-Pinned Memory的论述, 请参考这里。

... pinned memory is much more expensive to allocate and deallocate but
provides higher transfer throughput for large memory transfers.

3. 注册内存区域的实现过程

对于应用来说,注册一段内存区域的函数是ibv_reg_mr()。让我们从这个函数开始。

[SPDK/NVMe存储技术分析]015 - 理解内存注册(Memory Registration) - vlhn - 博客园

【vbers】ibv_reg_mr|RDMA相关推荐

  1. 【vbers】ibv_poll_cq()|RDMA

    目录 描述 参数 返回值 例子 常见问题 原文:https://www.rdmamojo.com/2013/02/15/ibv_poll_cq/  (强烈建议去看原文) 描述 ibv_poll_cq( ...

  2. 【vbers】ibv_get_async_event()

    原文:ibv_get_async_event() - RDMAmojo RDMAmojo 描述 ibv_get_async_event() 读取 RDMA 设备上下文context的下一个异步事件. ...

  3. 【vbers】ibv_req_notify_cq()

    ibv_req_notify_cq() - RDMAmojo RDMAmojo 描述 ibv_req_notify_cq() 在完成队列 (CQ) 上请求完成通知. 当一个请求的下一个WC添加到 CQ ...

  4. 【verbs】ibv_get_cq_event|ibv_ack_cq_events()

    目录 ibv_get_cq_event 概要 描述 返回值 提示 ibv_ack_cq_events 描述 参数 返回值 例子 常见问题 ibv_get_cq_event ibv_get_cq_eve ...

  5. 【Shell】awk命令--输出某列,列求和,列求平均值,列最大值,列去重复,取倒列,过滤行,匹配,不匹配,内置变量|定义分隔符|多个分隔符...

    目录 awk基本语法 awk输出某几列 awk遍历文件行处理 awk中运行shell命令 方法1:awk 内置函数system 方法2 通过awk  print 交给bash awk中运行shell命 ...

  6. 【Linux】centOS 错误记录|无法启动网络Failed to start LSB: Bring up/down networking

    目录 Failed to start LSB: Bring up/down networking Failed to mount /sysroot解决方法 Failed to start LSB: B ...

  7. 树莓派ZeroW学习笔记【0】wiringPi安装和测试

    一.wiringPi简介 [1]wiringPi是仅应用于树莓派平台的GPIO控制库函数,遵循GNU LGPLv3开源协议,并由GIT工具维护,任何人都可以免费使用该软件包.wiringPi使用C或者 ...

  8. 【网络】UCX(Unified Communication X )|统一抽象通信接口

    目录 UCX 的意义 UCX 通信接口简介 支持的传输(协议) UCX社区 UCX 编程模型简介 建立连接 内存注册 异步任务处理(重点) 使用UCX 编译debug版本 构建RPM包 构建DEB 包 ...

  9. 【测试】 FIO:ceph/磁盘IO测试工具 fio(iodepth深度)

    目录 随看随用 NAS文件系统测试 块系统测试 FIO用法 FIO介绍 FIO 工具常用参数: FIO结果说明 I/O 的重放('录'下实际工况的IO,用fio'重放') fio工作参数可以写入配置文 ...

  10. 【PFC】PFC使能 H3C交换机设置和主机设置--编辑中

    目录 交换机设置 主机设置 mellonx网卡(驱动) 配置简述 H3C交换机设置 主机设置 mellonx RDMA网卡 intel RDMA网卡 PFC和ECN 流量标记设置 本文原始连接:[PF ...

最新文章

  1. 用户列表-投资记录sql
  2. 线段树 + 树形换根 + dfs序 ---- 离线启发式求解 (有点像树上启发式合并答案) F. Nearest Leaf
  3. [elixir观察] GenStage 与 Flow
  4. go预防CSRF攻击
  5. WPF实现物理效果 拉一个小球
  6. MongoDB基本管理命令
  7. eclipse中monokai插件的安装
  8. 卡顿严重_微软Win 10游戏模式致《使命召唤:战区》等游戏出现严重卡顿现象
  9. 亚洲新首富出炉!富豪榜单大洗牌,马云3年来首次跌出中国前三
  10. SC2012 Orchestrator - 文档及资源链接
  11. 利用fat jar插件生成可执行jar文件
  12. layui table 表格两种赋值方式下,data分页效果有效, url分页效果的失效 问题的解决。
  13. 如何禁止TextBox的记忆功能
  14. 【语音去噪】基于matlab改进谱减法语音去噪【含Matlab源码 569期】
  15. Hibernate 5 详解!
  16. 「缠师课后回复精选」第15课:没有趋势,没有背驰。
  17. 扦插机器人_如何看待我国农业采摘机器人发展趋势?
  18. Texture Haven Spider
  19. 复制粘贴-实现动态爱心 网页版
  20. docker一个镜像启动多个容器的操作

热门文章

  1. java中小数点位数_Java中限制小数位数问题
  2. 针孔相机模型和相机内参矩阵K
  3. 书中自有黄金屋系列4:读《一课经济学》
  4. JPEG图片存储格式及原理
  5. 天大《电子商务网站设计与管理》大作业期末考核
  6. 如何做好电商平台的内容运营?
  7. APICloud框架——获取本地图片信息
  8. JavaScript中getYear,getMonth,getDate()
  9. win10自动更新修复与关闭
  10. 远程调试监视器 已在计算机上关闭,错误:“Microsoft Visual Studio 远程调试监视器”(MSVSMON.EXE) 似乎没有在远程计算机上运行。...