源码版本:lustre-release 2.15.55

介绍

LNet是Lustre的网络模块,代码目录分为了lnet和lnd

  • lnet提供了统一的接口
  • lnd封装了底层驱动,有socklnd(TCP/IP),iblnd(RDMA)

分析代码的主要目的是为了研究其如何实现RDMA大规模组网(5万+客户端)。RDMA大规模组网的瓶颈在于服务器的内存,如BeeGFS需要为每个连接分配1M的发送缓存(物理内存)和1M的接收缓存,并映射到dma,这样一算支持1万客户端就需要占用超过20G的内存。

先写结论
LNet通过两阶段收发数据的方式避免了为每个连接预申请内存,以发送数据为例

  • 第一阶段:发送端将待发送的数据映射到dma,并通过预映射的内存通过RDMA告知接收端待发送的数据信息(长度、类型等),接收端申请内存并映射到dma,并告知发送端映射后的信息(address、key)
  • 第二阶段:发送端将数据通过RDMA发送给接收端

虽然两阶段发送增加了通讯成本,但使得内存不会成为大规模组网的瓶颈。

初始化

iblnd初始化函数kiblnd_startup(),主要的是创建pool set。pool set分为fmr pool set和tx pool set。至少会创建cpt个pool set,每个pool set初始包含一个pool,一个pool最多包含256个fmr/tx,每个mr可映射256个page,每个tx可保存256个page地址,每个tx会预映射一个page到dma,为rdma通讯所用。

cpt含义是cpu partition,值与cpu核数以及numa的节点个数有关。

传输数据时,需要

  • 从tx pool set获取一个tx,填写消息信息(长度、类型等),以预映射的page与接收端通讯
  • 从fmr pool set从获取一个mr,将待发送数据的内存映射到这块mr中

当没有tx或mr可用时,会创建新的pool。每个pool都有一个deadline,当归还tx时,如果该pool空闲且已经到deadline,则会回收该pool。

创建连接

创建连接在发送数据的流程中触发,其过程与常规rdma创建流程无异,需要注意的是iblnd中创建流程通过rdma的事件回调触发下一阶段,可能有些费解。创建连接时会预先申请18个page,并映射到dma,作为RQE(receive queue entry)。18是根据连接的队列深度和协议版本确定的。每个连接固定占用的内存资源很少。

收发数据

因为tx预映射了一个page,所以当发送的数据小于4K时,则可以立即发送。当发送的数据大于4K时,则需要走两阶段发送。当接收端收到第一阶段的消息后,会申请内存准备接收数据。这些内存是上层服务在注册时申请的,可以复用于多个连接。第二阶段时,一旦接收端收到全部数据后,就会通过事件回调的方式通知上层。发送端也是如此,一旦全部发送成功后,会通过事件回调的方式通知上层。

家里竟然下不了源码,只能简单写写了。

版权声明:本文为yizui原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yizui/p/11148033.html