Memory Region & Memory Window (五)

文章转载知乎《6. RDMA之Memory Region》:https://zhuanlan.zhihu.com/p/156975042

以及知乎《14. RDMA之Memory Window》:https://zhuanlan.zhihu.com/p/353590347

在此基础上补充和完善,如有描述不准确之处,欢迎指出。

Memory Region

假设一种场景,同时也顺便温习一下RDMA WRITE操作的流程:

如下图所示,A节点(左侧)想要通过IB协议向B节点(右侧)的内存中写入一段数据,上层应用给本节点的RDMA网卡下发了一个WQE,WQE中包含了源内存地址、目的内存地址(提前交互信息得到)、数据长度和秘钥等信息,然后硬件会从本端内存中取出数据,组包发送到对端网卡。B节点的网卡收到数据后,解析到其中的目的内存地址,把数据写入到本节点的内存中。
在这里插入图片描述

注意,上图des_adds地址是B节点app的虚拟地址,而不是连续的物理地址!那么问题来了,B节点的RDMA网卡如何根据虚拟地址des_addr(VA)来找到物理地址PA呢?

CPU访问虚拟地址,需要经过MMU之后才能访问到真实的物理内存,所以容易推论到RDMA网卡内部也有类似MMU的部件。既然RDMA拥有类似MMU的部件,那定然需要执行某种操作去配置它,这个操作便称为注册MR(Register memory region)。

MR全称为Memory Region,指的是由RDMA软件层在内存中规划出的一片区域,用于存放收发的数据。IB协议中,用户在申请完用于存放数据的内存区域之后,都需要通过调用IB框架提供的API注册MR,才能让RDMA网卡访问这片内存区域。由下图可以看到,MR就是一片特殊的内存而已:
在这里插入图片描述

注册MR会发生什么

调用IB框架提供的注册MR接口,将会调用到RDMA网卡厂商提供的注册MR函数,函数中无非就是3件事:

1)获取用户态连续虚拟内存va_addr对应的离散物理内存地址,并将物理内存pin住防止换页;

2)申请一块连续的DMA内存,起始地址为mtt_addr,将上面获取的一系列物理内存地址填充在里面,其实就是MTT表(一级页表形式);

3)产生一组key(L_KEY/R_KEY),再根据key的高24bit作为索引找到某个空间某个位置,将va_addr、len、mtt_addr填充到这个空间中。

如下图所示。
在这里插入图片描述

上图中RDMA所知晓的内存可能是HOST DDR、RDMA网卡中SRAM、RDMA网卡中DDR中一种,具体需要看厂商实现。

注意,注册MR必须要陷入内核态。

为什么注册MR

为什么IB框架要提供MR注册接口?注册MR有什么好处?

注册MR以实现虚拟地址与物理地址(或IOVA)转换

我们都知道APP只能看到虚拟地址,而且会在WQE中直接把VA传递给HCA(既包括本端的源VA,也包括对端的目的VA)。现在的CPU都有MMU和页表这一“利器”来进行VA和PA之间的转换,而HCA要么直接连接到总线上,要么通过IOMMU/SMMU做地址转换后连接到总线上,它是“看不懂”APP提供的VA所对应的真实物理内存地址的。

所以注册MR的过程中,硬件会在内存(HOST DDR或RDMA网卡中SRAM或RDMA网卡中DDR)中创建并填写一个VA to PA(或IOVA)的映射表,这样需要的时候就能通过查表把VA转换成PA(或IOVA)了。还是提供一个具体的例子来讲一下这个过程:
在这里插入图片描述

注意,HCA(RDMA网卡)中的VA->PA(IOVA)映射表画在HCA内部只是表示HCA查表这个动作,并不是指这个MTT表就在HCA内部,它可能存在HOST DDR、RDMA网卡中SRAM、RDMA网卡中DDR当中任何一个位置。对于未开启IOMMU的HOST来说,这个MTT表查出来的就是内存物理(PA)地址。对于HOST开启了IOMMU来说,这个MTT表查出来的就是IOVA,再由RC中的IOMMU再次翻译才能得到PA。

由上图举例,假设左边的节点向右边的节点发起了RDMA WRITE操作,即直接向右节点的内存区域中写入数据。假设图中两端都已经完成了注册MR的动作,MR即对应图中的“数据Buffer”,同时也创建好了VA->PA(IOVA)的映射表。

  • 首先本端APP(左侧)会下发一个WQE给HCA,告知HCA,用于存放待发送数据的本地Buffer的虚拟地址(左侧数据Buffer),以及即将写入的对端数据Buffer(右侧)的虚拟地址。
  • 本端HCA(左侧)查询VA->PA(IOVA)映射表,得知待发数据的物理地址(或IOVA),然后从内存中拿到数据,组装数据包并发送出去。
  • 对端HCA(右侧)收到了数据包,从中解析出了目的VA。
  • 对端HCA(右侧)通过存储在本地内存中的VA->PA(IOVA)映射表,查到真实的物理地址,核对权限无误后,将数据存放到内存中(右侧数据Buffer)。

再次强调一下,对于右侧节点来说,无论是地址转换还是写入内存,完全不用HOST CPU的参与

MR可以控制HCA访问内存的权限

因为HCA访问的内存地址来自于用户,如果用户传入了一个非法的地址(比如系统内存或者其他进程使用的内存),HCA对其进行读写可能造成信息泄露或者内存覆盖。所以需要一种机制来确保HCA只能访问已被授权的、安全的内存地址。IB协议中,APP在为数据交互做准备的阶段,需要执行注册MR的动作。

而用户注册MR的动作会产生两把钥匙——L_KEY(Local Key)和R_KEY(Remote Key),说是钥匙,它们的实体其实就是一串序列而已。它们将分别用于保障对于本端和远端内存区域的访问权限。下面两张图分别是描述L_Key和R_Key的作用的示意图:
在这里插入图片描述
在这里插入图片描述

这里大家可能会有疑问,本端是如何知道对端节点的可用VA和对应的R_Key的?其实两端的节点在真正的RDMA通信之前,都会通过某些方式先建立一条链路(可能是Socket连接,也可能是CM连接)并通过这条链路交换一些RDMA通信所必须的信息(VA,Key,QPN等),称这一过程叫做“建链”和“握手”。

MR可以避免换页

因为物理内存是有限的,所以操作系统通过换页机制来暂时把某个进程不用的内存内容保存到硬盘中。当该进程需要使用时,再通过缺页中断把硬盘中的内容搬移回内存,这一过程几乎必然导致VA-PA的映射关系发生改变。

由于HCA经常会绕过CPU对用户提供的VA所指向的物理内存区域进行读写,如果前后的VA-PA映射关系发生改变,那么VA->PA映射表将失去意义,HCA将无法找到正确的物理地址。

为了防止换页所导致的VA-PA映射关系发生改变,注册MR时会"Pin"住这块内存(亦称“锁页”),即锁定VA-PA的映射关系。也就是说,MR这块内存区域会长期存在于物理内存中不被换页,直到完成通信之后,用户主动注销这片MR。

注册MR配置的权限

这里的权限,指的是本端/对端节点,对于本端内存的读/写权限,它们两两组合形成了四种权限:

本端对端
Local ReadRemote Read
Local WriteRemote Write

除了这四种权限之外,还有Atomic权限等,不在本文讨论范围内。

上表中这四种权限中最低的是本地读(Local Read),是用户必须赋予MR的权限,因为如果一块内存本地的用户都无法访问的话,那就失去意义了;另外还有个限制,如果某个MR需要配置远端写(Remote Write)或者原子操作权限(Remote Atomic),那么也一定要配置本地写(Local Write)权限。

在此约束之下,每个MR都可以按需配置权限,比如我们注册的一个MR需要允许远端节点写入数据,而不允许读,那么我们就打开Remote Write权限,关闭Remote Read权限。这样HCA(网卡)收到对端发起的对这个MR范围内的某个地址的WRITE请求之后,就可以予以放行;而HCA收到对端对这个MR的READ操作时,就会拒绝这个请求,并返回错误信息给对端。

Memory Key

Key是一串数字,由两部分组成:24bit的Index以及8bit的Key:
在这里插入图片描述

其中,Index用于RDMA网卡快速索引到本地的虚拟-物理地址转换表等MR相关的信息,而Key用于校验整个字段的合法性,以防止未授权的用户任意传递Index。

Memory Key按照用途分为两种,Local Key和Remote Key。

L_Key

即Local Key,关联到一个MR上,用于本端RDMA网卡来访问内存。当本端的某个进程通过QP下发一个请求,试图使用一个已经注册的MR的内存时,RDMA网卡会校验其传递的L_Key。并且利用L_Key中的索引查找地址转换表(MTT table),把虚拟地址翻译成物理地址然后访问内存。需要注意的是,QP和MR必须同属于一个PD域中才能校验成功。
在这里插入图片描述

RDMA网卡从QP SQ buf中取下WQE entry1解析,根据L_KEY高24bit找到MR对应的MTT表,再校验PD域以及L_KEY低8bit,确认无误之后再将va_1翻译成物理地址,从而获取数据组包发出去。

R_Key

即Remote Key,关联到一个MR上,用于远端节点访问本端内存。当远端节点试图访问本端的内存时,一方面本端的HCA会校验R_Key是否合法,另一方面会利用R_Key中的索引查地址转换表,把虚拟地址翻译成物理地址然后访问内存。

凡是RDMA操作(即Write/Read/Atomic),用户都要在WR中携带远端内存区域的R_Key。
在这里插入图片描述

A网卡发送一个报文(RDMA操作或原子操作)到B网卡,由B网卡根据R_KEY高24bit找到MR对应的MTT表,然后校验dest QP和MR的PD域以及校验R_KEY低8bit,确认无误之后再将va翻译成物理地址,从而将data数据写入到va对应的一些列物理内存中。

用一个比喻来总结下MR权限控制相关的内容:

A给自己的房间(MR)配了两把钥匙(Memory Key),一把留作自用(L_Key),另一把钥匙(R_Key)邮寄(可以是任何通信方式)给了B。B可以在A不在家的时候(本端CPU不感知远端节点对本地内存的RDMA操作),通过钥匙(R_Key)打开门。打开门之后,可能B只能隔着玻璃查看房间的摆设(A只给了这个MR远程读权限),或者进入房间内发现漆黑一片什么也看不到,但是可以向房间里放物品(A只给了这个MR远程写权限),当然也有可能没有玻璃也开了灯(同时给了远程读写权限)。

MR支持虚拟地址类型

MR支持两种虚拟地址访问方式:Virtual Addresses 和Zero Based Virtual Addresses 。

Virtual Addresses:这种方式就是注册时使用app真实虚拟地址(假设0x100),本端使用时也使用app虚拟地址(0x100),远端RDMA操作本端内存时,也使用真实虚拟地址(0x100)。
Zero Based Virtual Addresses:这种方式就是注册时使用app真实虚拟地址(假设0x100),本端使用时,使用0 base的偏移(0x0),远端RDMA操作本端内存时,也使用0 base的偏移(0x0)。

使用Zero Based Virtual Addresses无疑更加安全,让远端知晓信息越少越好。

Memory Window

Memory Window简称MW,中文就翻译成内存窗口吧。是一种由用户申请的,用于让远端节点访问本端内存区域的RDMA资源。每个MW都会绑定(称为bind)在一个已经注册的MR上,但是它相比于MR可以提供更灵活的权限控制。MW可以粗略理解为是MR的子集,一个MR上可以划分出很多MW,每个MW都可以设置自己的权限。MW和MR的关系如下图所示:
在这里插入图片描述
注意,上面的MW1、MW2、MW3之间是可以重叠的。

MW的权限控制与MR一样,产生的R_KEY用途也一样,注意,MW没有L_KEY。

为什么要有MW

简而言之,设计MW的目的就是想更灵活的控制内存的远程访问权限。

在前面介绍Memory Region中介绍过用户注册MR的过程,需要从用户态陷入内核态,调用内核提供的函数pin住内存(防止换页),然后制作虚拟-物理地址映射表并下发给硬件。

因为MR是由内核管理的,如果用户想修改一个已经存在的MR的信息,比如想收回某个MR的远端写权限,只保留远端读权限;或者想要使一个之前已经授权给远端节点的R_Key失效,那么用户需要通过重注册MR(Reregister MR)接口来进行修改,该接口等价于先取消注册MR(Deregister MR),然后注册MR(Register MR)。上述流程需要陷入内核态来完成,而这个过程是耗时较长的

不同于需要通过控制路径修改权限的MR**,MW在创建好之后,可以通过数据路径(即通过用户态直接下发WR到硬件的方式)动态的绑定到一个已经注册的MR上,并同时设置或者更改其访问权限,这个过程的速度远远超过重新注册MR的过程。**

那么现在为了使一片内存能够被远端节点进行RDMA WRITE/READ操作,我们就拥有了注册MR以及注册MW然后绑定到一个已注册的MR两种方式,它们都会产生一个R_Key来提供给远端节点。前一种方式准备阶段的步骤简单,但是不够灵活,一旦注册之后修改起来会比较麻烦;后一种方式相比前一种多了注册MW和绑定MW到MR两种操作,但是可以方便迅速的控制远端访问权限。

MW和MR权限的关系

也许有的读者会想到,MR申请时配置了自己的权限,MW绑定到MR时也会配置自己的权限,这两者的权限是什么关系呢?IB规范在10.6.7.2.2节有专门介绍:

When binding a Memory Window, a Consumer can request any combination of remote access rights for the Window. However, if the associated Region does not have local write access enabled and the Consumer requests remote write or remote atomic access for the Window, the Channel Interface must return an error either at bind time or access time.

总结来说,如果想要给MW配置远程写或者远程原子操作(Atomic)权限,那么它绑定到的MR必须有本地写权限(厂商有责任在MW绑定接口中判断),其他情况下两者权限互不干扰:远端用户用MW,就要遵循MW的权限配置;远端用户用MR,就要遵循MR的权限配置。

也就是说,只要MR拥有本地写权限,即使没有远程写权限,也可以赋予绑定MW远程写权限。

MW的类型

根据实现和应用场景的不同,IB规范对MW进行了分类:

Type 1

Type 1的MW通过PD和一个QP关联,不会绑定到一个QP上,所以也不会影响销毁同一个PD下的QP。

Type 1的MW的R_Key的key域段由驱动和硬件掌握,这里“掌握”的意思是,由驱动和硬件分配key,而不是上层用户。这也是前文中说Type 1的MW不能被执行Invalidate操作的原因。如果Type 1 MW的用户想要使一个R_Key失效,那么重新通过Bind MW接口绑定一次这个MW,硬件或者驱动就回自动分配一个新的R_Key的key域段,原有的R_Key也就失效了。

此外,如果用户暂时想要使一个MW不再绑定到任何MR,但是又想保留相关的资源而不是销毁这个MW,那么可以通过调用Bind MW接口,并将MW长度设置为0来实现。

IB规范允许多个Type 1 MW绑定到同一个MR上,范围可以相互覆盖。

对于Type1类型MW来说,其调用接口流程应该如下(用户态为例):

mr = ibv_reg_mr(pd, addr, len, access);//注册MR,注意权限,如果后续绑定的MW需要赋予R_WRITE,则这里必须服务L_WRITE
mw = ibv_alloc_mw(pd, IBV_MW_TYPE_1);//Type1类型,将陷入内核态,产生R_Key的index字段,即R_Key的高24bit
struct ibv_mw_bind bind = {.wr_id = xxx, .send_flags = xxx,
                           .bind_info = {.mr = mr, .addr = x, .length = y, .mw_access_flags = READ/WRITE}, };
ibv_bind_mw(qp, mw, bind);//将MW绑定到MR中,并产生一个R_Key的key域段,即R_Key的低8bit

Type1类型的MW只支持一种虚拟地址访问类型:Virtual Addresses。

Type 2

Type 2的MW赋予了用户更大的自由度,其R_Key的key域段由用户掌握,即用户想怎么分配就怎么分配。用户必须记住Allocate MW时的index(即R_KEY高24bit),并且和其选择的8 bit key组成R_Key并发送给对端。

对于Type2类型的MW,通过Invalidate操作来使一个R_Key无效,如果想要分配一个新的R_Key到MW上,必须先通过Invalidate操作无效之前的R_Key。之后才能改变R_Key的key域段,并通过Post send操作重新绑定MR。

与Type 1不同,Type 2的MW不支持0长度的绑定。

IB规范同样也允许多个Type 2绑定到同一个MR上,范围可以相互覆盖。

此外,根据绑定关系不同,Type 2还可以分为两种实现方式,它们的差异仅在于和QP的绑定关系上。

对于Type2类型MW来说,其调用接口流程应该如下(用户态为例):

mr = ibv_reg_mr(pd, addr, len, access);//注册MR,注意权限,如果后续绑定的MW需要赋予R_WRITE,则这里必须服务L_WRITE
mw = ibv_alloc_mw(pd, IBV_MW_TYPE_2);//Type1类型,将陷入内核态,产生R_Key的index字段,即R_Key的高24bit
wr.opcode = IBV_WR_BIND_MW;
wr.next = NULL;
wr.wr_id = xxx;
wr.send_flags = xxx;
wr.bind_mw.bind_info = xxx;
wr.bind_mw.mw = mw;
wr.bind_mw.rkey = mw->rkey | (key && 0xff);//其中key是用户自定义的(8bit),注意,如果之前已经绑定过,则必须Invalidate操作无效R_KEY之后才能再次绑定
post_send(qp, &wr, &bad_wr);

Type2型的MW不能调用Bind MW函数(用户态为 ibv_bind_mw),只能通过Post send方式Bind MW。

Type2类型的MW支持两种虚拟地址访问类型:Virtual Addresses和Zero Based Virtual Addresses。

Type 2A

通过QPN和一个QP关联,也就是说远端访问这个MW范围内的内存时候,除了R_Key之外,还必须指定正确的QPN。如果一个QP上还有绑定的Type 2A的MW,那么这个QP不可以被销毁

此外,如果还有Type 2A的MW绑定在QP上,那么这个QP就不能通过Modify接口更改状态到Reset状态。

Type 2B

通过QPN和PD与一个QP关联,比Type 2A多了个PD的校验,即远端通过RDMA操作访问MW的内存时,除了QPN要正确之外,其指定的本端QP的PD要与绑定这个MW时的PD相同。另外,与Type 2A不同,QP如果还有Type 2B MW绑定关系时是可以被销毁的

类型总结

这里IB规范中原有的介绍就比较分散,简单总结一下几种MW的异同:

Type 1Type 2AType 2B
关联关系PDQPPD + QP
R_Key的key域段归属驱动+硬件用户用户
绑定方式Bind MW 绑定后之前的R_Key自动失效Post Send Bind MW WR 绑定前需要先使之前的R_Key无效化Post Send Bind MW WR 绑定前需要先使之前的R_Key无效化
是否支持零长度
是否支持Invalidate
关联的QP是否可以被销毁-

此外,IB规范中对上述几种类型还有如下描述:HCA必须实现Type 1的MW,另外可以选择实现Type 2A和2B中的一种。Type 1和Type 2的MW可以同时关联到同一个MR上。

注意,对于 Type 2 内存窗口,允许Invalidate操作,但对于 Type 1 内存窗口,则不允许Invalidate操作。因此,本端用户应该与远端用户协商关联的 MW 的 R_Key 是否可以被作废。

MW的R_KEY状态

每个Memory Window R_Key都有三种可能的状态:

  • Invalid State — 没有为R_Key分配资源。R_Key状态为“无效”时,不能访问主机内存。处于Invalid状态的R_Key不能通过带Invalidate的Send来失效。
  • Free State — R_Key与内存区域没有关联,不能用于访问主机内存。处于Free状态的R_Key可以通过带Invalidate的Send来失效。注意:Free状态可能不会在Type 1内存窗口上实现(见表72)。
  • Valid State — R_Key与内存区域相关联。处于有效状态的R_key可用于访问主机内存。处于Valid状态的R_Key可以通过带Invalidate的Send命令使其失效。

下表总结了Type 1 Memory Windows R_Keys的状态以及每种状态下允许的操作:
在这里插入图片描述

下表总结了Type 2 Memory Windows R_Keys的状态以及每种状态下允许的操作:
在这里插入图片描述

此外,对于Type2类型MW的R_KEY,其状态转换可通过以下verbs接口或远程操作来触发(非verbs接口用斜体标记):
在这里插入图片描述

MW绑定

Bind(ing)意为“绑定”,指的是将一个MW“关联”到一个已经注册的MR的指定范围上,并配置一定的读写权限。绑定的结果会产生一个R_key,用户可以把这个R_Key传递给远端节点用于远程访问。注意一个MW可以被多次绑定,一个MR上也可以绑定多个MW。如果一个MR还有被绑定的MW,那么这个MR是不能被取消注册的。
在这里插入图片描述

Bind有两种方式,一种是调用Post Send接口下发Bind MW WR,一种是调用Bind MW接口。

Post Send Bind MW WR

相比于MR,MW最大的优势就是可以从数据路径快速的配置权限。Post Send Bind MW WR操作,指的就是用户通过post send接口(比如ibv_post_send())下发一个WR到SQ中,这个WR的操作类型(比如SEND/RDMA WRITE/RDMA READ)被指定为BIND MW,此外WR中还携带有权限和要绑定到的MR的范围信息。与其他WR不同,下发Bind MW的WR之后,硬件并不会发送任何数据包,而是将MW绑定到了指定MR上。

注意,只有Type2支持这个绑定方式。

Bind MW

虽然这是一个独立的接口,但是实际是在Post Send Bind MW WR外面又封装了一层。用户传入MW绑定的相关信息,包括权限及要绑定的MR的信息,驱动程序负责组装和下发WR到硬件中。该接口成功后,会将新生成的R_Key返回给用户。

注意,只有Type1支持这个绑定方式。

两者关系

两种操作的关系是这样的:
在这里插入图片描述

以mlx5为例,看看Bind MW的代码,如下:

int mlx5_bind_mw(struct ibv_qp *qp, struct ibv_mw *mw,
		 struct ibv_mw_bind *mw_bind)
{
	struct ibv_mw_bind_info	*bind_info = &mw_bind->bind_info;
	struct ibv_send_wr wr = {};
	struct ibv_send_wr *bad_wr = NULL;
	int ret;

	if (bind_info->mw_access_flags & IBV_ACCESS_ZERO_BASED) {
		errno = EINVAL;
		return errno;
	}

	if (bind_info->mr) {
		if (verbs_get_mr(bind_info->mr)->mr_type != IBV_MR_TYPE_MR) {
			errno = ENOTSUP;
			return errno;
		}

		if (to_mmr(bind_info->mr)->alloc_flags & IBV_ACCESS_ZERO_BASED) {
			errno = EINVAL;
			return errno;
		}

	}

	wr.opcode = IBV_WR_BIND_MW;
	wr.next = NULL;
	wr.wr_id = mw_bind->wr_id;
	wr.send_flags = mw_bind->send_flags;
	wr.bind_mw.bind_info = mw_bind->bind_info;
	wr.bind_mw.mw = mw;
	wr.bind_mw.rkey = ibv_inc_rkey(mw->rkey);

	ret = _mlx5_post_send(qp, &wr, &bad_wr);
	if (ret)
		return ret;

	mw->rkey = wr.bind_mw.rkey;

	return 0;
}

其实就是将post send封装了一层,但需要注意的是:每次调用Bind MW操作,其R_Key均会改变。

无效化——Invalidate

Invalidate意为无效化,指的是用户通过下发一个带有Invalidate操作码的WR到硬件而使一个R_Key无效的操作。

需要强调的是,Invalidate操作的对象是R_Key而不是MW本身,即Invalidate之后的效果是:远端用户无法再使用这个R_Key访问对应的MW,而MW资源仍然存在,以后仍然可以生成新的R_Key给远端使用。

Invalidate操作只能用于Type 2的MW。

按照Invalidate操作的发起方不同,又可以进一步分成两种:Local Invalidate 和 Remote Invalidate。

Local Invalidate

本地无效操作。上层用户如果想在不回收MW资源的情况下,收回某个远端的用户的R_Key的权限。那么就可以下发一个Local Invalidate操作到SQ中,硬件收到之后会对相应的MR的配置进行修改。成功执行之后,如果持有这个R_Key的远端用户想要对MW进行RDMA操作,将会被本地的硬件拒绝并返回错误。

因为是本地操作,所以硬件收到这个WR之后也不会发送消息到链路上。
在这里插入图片描述

Remote Invalidate

远端无效操作。当一个远端用户不再使用一个R_Key之后,可以主动发送消息,让本端回收这个R_Key。远端用户下发一个带有此操作码的WR到SQ中,其硬件收到后,将会组装一个报文并发送到本端。本端硬件收到远端的Remote Invalidate操作之后,将会把对应的R_Key置为不可用状态。同Local Invalidate一样,此后对端将无法使用这个R_Key对对应的MW进行RDMA操作。
在这里插入图片描述

Invalidate操作也可以用在一些特殊的MR类型身上(并非常规用户通过ibv_reg_mr()注册的MR),但超出了本文讨论范围,暂且不表。

MW使用场景

IB协议中解释到:当消费者需要更灵活地控制对其内存的远程访问时,消费者可以使用Memory Window。Memory Window用于以下情况:

  • 希望以动态方式授予和撤销对已注册区域的远程访问权限,并且希望比使用注销/注册或重新注册MR的性能损失更小。
  • 希望向不同的远程代理授予不同的远程访问权限和/或在注册区域内的不同范围内授予这些权限。

暂时未找到使用MW的例程。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值