域名 空间 建网站商务网站建设与维护 ppt
- 作者: 五速梦信息网
- 时间: 2026年04月20日 06:55
当前位置: 首页 > news >正文
域名 空间 建网站,商务网站建设与维护 ppt,品牌线上营销策划,网站建设速成作者#xff1a;羽京 一、前言 随着数据中心的飞速发展#xff0c;高性能网络不断挑战着带宽与时延的极限#xff0c;网卡带宽从过去的 10 Gb/s 、25 Gb/s 到如今的 100 Gb/s、200 Gb/s 再到下一代的 400Gb/s 网卡#xff0c;其发展速度已经远大于 CPU 发展的速度。 为了… 作者羽京 一、前言 随着数据中心的飞速发展高性能网络不断挑战着带宽与时延的极限网卡带宽从过去的 10 Gb/s 、25 Gb/s 到如今的 100 Gb/s、200 Gb/s 再到下一代的 400Gb/s 网卡其发展速度已经远大于 CPU 发展的速度。 为了满足高性能网络下的通信需求阿里云不仅自研了高性能用户态协议栈 Luna、Solar 也大规模使用了 RDMA 技术以充分利用高性能网络。尤其是在存储和 AI 领域RDMA 被广泛使用。相比于 Kernel TCP 提供的 Socket 接口RDMA 的抽象更为复杂为了更好的使用 RDMA了解其工作原理和机制是必不可少的。 本文以 NVIDIA 原 Mellanox的 RDMA 网卡为例分析其工作原理和软硬件交互的机制。 二、RDMA 是什么 RDMA (Remote Direct Memory Access) 技术全称远程直接内存访问是为了解决网络传输中服务器端数据处理的延迟而产生的。RDMA 通过网络将数据从一个系统快速移动到另一个系统中而不需要消耗计算机的处理能力。它消除了内存拷贝和上下文切换的开销因而能解放内存带宽和 CPU 周期用于提升系统的整体性能。 先看看最常见的 Kernel TCP其收数据的流程主要要经过以下阶段 网卡驱动从内核分配 dma buffer填入收队列 网卡收到数据包发起 DMA写入收队列中的 dma buffer 网卡产生中断 网卡驱动查看收队列取出 dma buffer交给协议栈 协议栈处理报文 操作系统通知用户态程序有可读事件 用户态程序准备 buffer发起系统调用 内核拷贝数据至用户态程序的 buffer 中 系统调用结束 可以发现上述流程有三次上下文切换中断上下文切换、用户态与内核态上下文切换有一次内存拷贝。虽然内核有一些优化手段比如通过 NAPI 机制减少中断数量但是在高性能场景下 Kernel TCP 的延迟和吞吐的表现依然不佳。 使用 RDMA 技术后收数据的主要流程变为以 send/recv 为例 1用户态程序分配 buffer填入收队列 2网卡收到数据包发起 DMA写入收队列中的 buffer 3网卡产生完成事件可以不产生中断 4用户态程序 polling 完成事件 5用户态程序处理 buffer 上述流程没有上下文切换没有数据拷贝没有协议栈的处理逻辑卸载到了 RDMA 网卡内也没有内核的参与。CPU 可以专注处理数据和业务逻辑不用花大量的 cycles 去处理协议栈和内存拷贝。 三、RDMA 的软件架构 从上述分析可以看出RDMA 和传统的内核协议栈是完全独立的因此其软件架构也与内核协议栈很不一样包含以下部分 1用户态驱动libibverbs、libmlx5 等这些库都属于 rdma-core 项目https://github.com/linux-rdma/rdma-core。为用户提供各种 Verbs API另外也有一些厂商的特有 API。之所以这层被称为“用户态驱动”是因为 RDMA 要在用户态直接和硬件打交道传统在内核态实现 HAL 的方式不满足 RDMA 的需求因此需要在用户态感知硬件细节。 2内核态 IB 软件栈内核态的一层抽象对应用提供统一的接口。这些接口不仅用户态可以调用内核态也可以调用。 3 内核态驱动各个厂商实现的网卡驱动直接和硬件交互。 四、RDMA 的内存管理 由于 RDMA 要直接让硬件读写用户态程序的内存这带来了很多问题 1安全问题用户态程序能否利用网卡读写任意物理内存 2地址映射问题用户态程序使用的是虚拟地址实际的物理地址是操作系统管理的。网卡怎么知道虚拟地址和物理地址的映射关系 3地址映射会变化操作系统可能会对内存做 swap、压缩操作系统还有一些复杂的机制比如 Copy-On-Write。这些情况下怎么保证网卡访问的地址的正确性 为了解决上述问题RDMA 引入了两个概念 1PDProtection Domain在 RDMA 中PD 是一个容纳了各种资源的“容器”类似一个租户 ID将这些资源纳入自己的保护范围内避免他们被未经授权的访问。一个进程中可以创建多个 PD各个 PD 所容纳的资源彼此隔离无法一起使用。 2MRMemory RegistrationRDMA 中对内存保护的一种措施只有将要操作的内存注册到 MR 中这段内存才能被 RDMA 使用。MR 包括了 PD、lkey、rkey、地址、长度、权限这几个属性。PD 是这个 MR 所属的保护域其他保护域的上下文是不能访问这个 MR 的避免了暴力遍历内存访问其他进程内存的可能。lkey、rkey 统称为 mkey 是一个访问内存的凭据分别对应本地访问和远程访问RDMA 的所有操作都要有 mkey 才能进行。 这样讲可能会有一些抽象以一个实际的例子来看看 RDMA 是怎么注册内存的 // 扫描 RDMA 设备找到我们要用的设备int num_devices 0, i;struct ibv_device ** device_list ibv_get_device_list(num_devices);struct ibv_device *device NULL;for (i 0; i num_devices; i) { if (strcmp(mlx5_bond_0, ibv_get_device_name(device_list[i])) 0) { device device_list[i]; break; }} // 打开设备产生一个 contextstruct ibv_context ibv_ctx ibv_open_device(device); // 分配一个 PDstruct ibv_pd pd ibv_alloc_pd(ibv_ctx); // 分配 8k 内存, 按照 page 对齐4kvoid alloc_region NULL;posix_memalign(alloc_region, sysconf(_SC_PAGESIZE), 8192); // 注册内存struct ibv_mr reg_mr ibv_reg_mr(pd, alloc_region, mr_len, IBV_ACCESS_LOCAL_WRITE); 打开内核模块的 debug 信息 echo file mr.c p /sys/kernel/debug/dynamic_debug/controlecho file mem.c p /sys/kernel/debug/dynamic_debug/control输出的日志 infiniband mlx5_0: mlx5_ib_reg_user_mr:1300:(pid 100804): start 0xdb1000, virt_addr 0xdb1000, length 0x2000, access_flags 0x100007infiniband mlx5_0: mr_umem_get:834:(pid 100804): npages 2, ncont 2, order 1, page_shift 12infiniband mlx5_0: get_cache_mr:484:(pid 100804): order 2, cache index 0infiniband mlx5_0: mlx5_ib_reg_user_mr:1369:(pid 100804): mkey 0xdd5dinfiniband mlx5_0: __mlx5_ib_populate_pas:158:(pid 100804): pas[0] 0x3e07a92003infiniband mlx5_0: __mlx5_ib_populate_pas:158:(pid 100804): pas[1] 0x3e106a6003 1用户态程序调用 ibv_reg_mr通过 uverbs 接口发到内核实际用的系统调用为 ioctl 或者 write操作的文件是 /dev/infiniband/uverbsX 2经过 uverbs 层的转换后最终调用到设备驱动的代码NVIDIA 网卡上是 mlx5_ib_reg_user_mr 这个函数 这个函数主要做了两件事情通过 mr_umem_get 将用户态内存 pin 住并拿到物理地址。以及通过 reg_create 向网卡发送创建 mkey 的命令。mr_umem_get 最终会调用到 ib_core.ko 中的 ib_umem_get 函数 这个函数会通过内核的 pin_user_pages_fast 接口防止用户内存的映射关系发生意外的改变比如 swap。 reg_create 会按照网卡开发手册定义的命令格式发送创建 mkey 的命令 经过上述流程最终会在网卡中创建一个 mkey 对象 mkey 0xdd5dvirt_addr 0xdb1000, length 0x2000, access_flags 0x100007pas[0] 0x3e07a92003pas[1] 0x3e106a6003网卡收到虚拟地址的时候就能够知道实际的物理页是什么并且可以做权限控制。 现在可以回答上面的问题了 安全问题用户态程序能否利用网卡读写任意物理内存 不能RDMA 通过 PD 和 MR 机制做了严格的内存保护。 地址映射问题用户态程序使用的是虚拟地址实际的物理地址是操作系统管理的。网卡怎么知道虚拟地址和物理的映射关系 驱动会告诉网卡映射关系后续数据流中网卡自己转换。 地址映射会变化操作系统可能会对内存做 swap、压缩操作系统还有一些复杂的机制比如 Copy-On-Write。这些情况下怎么保证网卡访问的地址的正确性 通过驱动调用 pin_user_pages_fast 保障。另外用户态驱动会给注册的内存打上 DONT_FORK 的标志避免 Copy-On-Write 发生。 五、RDMA 的软硬交互 RDMA 的软硬交换的基础单元是 Work Queue。Work Queue 是一个单生产者单消费者的环形队列。Work Queue 根据功能不同主要分为 SQ发送、RQ接收、CQ完成和 EQ事件等。 发送一个 RDMA 请求的大致流程为 软件构造 WQE Work Queue Element提交至 Work Queue 中 软件写 Doorbell 通知硬件 硬件拉取 WQE处理 WQE 硬件处理完成产生 CQE写入 CQ 硬件产生中断可选 软件 Polling CQ 软件读取硬件更新后的 CQE得知 WQE 完成 还是以一个实际的例子进行分析这样才能深入理解全流程 uint32_t send_demo(struct ibv_qp *qp, struct ibv_mr *mr){ struct ibv_send_wr sq_wr {}, *bad_wr_send NULL; struct ibv_sge sq_wr_sge[1];// 把 mr 的数据发送出去 sq_wr_sge[0].lkey mr-lkey; sq_wr_sge[0].addr (uint64_t)mr-addr; sq_wr_sge[0].length mr-length;sq_wr.next NULL; sq_wr.wr_id 0x31415926; // 请求的ID, 收到 WC 的时候可以对应上 sq_wr.send_flags IBV_SEND_SIGNALED; // 告诉网卡这个请求给我产生 CQE sq_wr.opcode IBV_WR_SEND; sq_wr.sg_list sq_wr_sge; sq_wr.num_sge 1;ibv_post_send(qp, sq_wr, bad_wr_send); // 提交请求到网卡struct ibv_wc wc {}; while (ibv_poll_cq(qp-send_cq, 1, wc) 0) { continue; }if (wc.status ! IBV_WC_SUCCESS || wc.wr_id ! 0x31415926) { exit(LINE__); }return 0;}这段代码的核心是 ibv_post_send 和 ibv_poll_cqibv_post_send 的用途是向网卡提交请求ibv_poll_cq 的用途是轮询 CQ看看是否有请求完成。 另外IB 规范定义了很多抽象 ibv_send_wr 这个是 SQ 的 WQE 的抽象不同厂商的网卡 WQE 格式不同 ibv_sge 是数据的抽象包含 addrlenlkey 三个字段 ibv_wc 是 CQE 的抽象通过 wr_id 和 ibv_send_wr 对应起来 rdma-core 的 debug 打开可以看到这样的两条日志 dump wqe at 0x7fc59b3570000000000a 00115003 00000008 0000000000000000 c0000000 00000000 000000000000022a 00008a0b 00007fc5 9a5b2000 mlx5_get_next_cqe:565: dump cqe for cqn 0x4c2:00000000 00000000 00000000 0000000000000000 00000000 00000000 0000000000000000 00000000 00000000 0000000000004863 2a39b102 0a001150 00003f00第一条就是我们调用 ibv_post_send 后rdma-core 事件向网卡提交的 WQE。 第二条是我们调用 ibv_poll_cq 后收到网卡给我们的 CQE。 在 NVIDIA 网卡上ibv_post_send 最终调用的是 _mlx5_post_send 这个函数的核心功能是 1把 ibv_send_wr 翻译为 NVIDIA 网卡的 WQE 格式 2Doorbell 通知网卡 5.1 填充 WQE 根据 NVIDIA 的手册一个 Send 请求的 WQE 包含两个部分 控制段 数据段 根据手册的定义我们解析一下上面日志中的 WQE 可以看到和我们软件填的 ibv_send_wr 是相似的。注意到一个细节我们填的 wr_id 没有出现在 WQE 中实际上这个 wr_id 是存在 rdma-core 里的。因为 WQE 是按序处理的收到 CQE 的时候可以找到当初提交的 ibv_send_wr。 5.2 Doorbell 通知网卡 post_send_db 这个函数很简单但是细节非常多 首先这个函数会加一个内存屏障保证 Doorbell 到达硬件时前面构建的 WQE 已经可见。 然后更新 QP 的 Doorbell 信息其实就是队列的 tail 最后通过 mmio_write64_be 写网卡的寄存器告诉网卡我准备好了你可以发了。 mmio_write64_be 使用的是 sse 指令x86 上WQE 的第一部分上文的控制段写入网卡的寄存器 实际上就是一个赋值操作等效于 *(uint64_t)(bf-reg bf-offset) *(uint64_t *)ctrl; 使用 SSE 主要是为了保证原子性避免网卡先收到前 4 字节再收到后 4 字节。 看来所有的魔法都在 bf-reg 上这个 buffer 是什么为什么软件往这个 buffer 写一个 uint64网卡就能收到事件 gdb 中可以看到这个 bf-reg 看起来是一个平平无奇的虚拟地址但是 gdb 读取会失败。 看看进程的 maps 信息 这段内存被映射成 Write Only 了所以读取失败。那这段内存是什么呢 用 crash 看看页表吧 物理地址是 1bffc020800通过 /proc/iomem 可以看到这个物理地址是属于 0000:3b:00.0 这个 PCI 设备的 这个设备正是我们用的 RDMA 网卡这个地址位于 BAR0 根据 NVIDIA 的手册软件写的这个地址区域被称为 UARUser Access Region。UAR 是 PCI 地址空间的一部分被网卡驱动直接映射至应用的内存中。当软件往 UAR 写 Doorbell 后网卡会从 PCI 上收到报文从而获知软件需要发送数据了这件事情。 随后网卡会经过调度和仲裁拉取 WQE 进行执行。在执行过程中网卡会先从 WQE 中提取 mkey 和地址然后送进 TPT Translation and Protection单元中查询 mkey 的信息拿到地址和权限校验通过后进行 DMA最后把数据发送至物理接口。 当数据发送完成且被对端确认后网卡会产生 CQE 通知软件。软件收到 CQE 后才可以进行资源的回收。这点和 Socket 接口不同Socket 接口是有拷贝的软件调用 write 结束后就可以把资源回收而 RDMA 是零拷贝的资源的生命周期管理会更加复杂。 六、总结 至此RDMA 基本的工作原理和软硬件交互的机制就介绍完了。RDMA 技术的出发点很简单就是能不能饶过一切限制直接把数据送到用户手中。在此之上做了非常多的工作成为了一个非常复杂的技术。 RDMA 也不是银弹有着编程复杂、调试复杂、硬件依赖重、不能长传等问题。对于 IO 密集型的业务RDMA 可以节约很多 CPU获得高吞吐低延迟的性能而对于计算密集的业务或者追求硬件无关的业务TCP 是更合适的选择。 参考资料 [01] IB 规范 https://www.infinibandta.org/ibta-specification/ [02] NVIDIA 网卡手册 https://network.nvidia.com/files/doc-2020/ethernet-adapters-programming-manual.pdf
- 上一篇: 域名 就一个网站广告企业网站模板
- 下一篇: 域名 网站财税公司做网站
相关文章
-
域名 就一个网站广告企业网站模板
域名 就一个网站广告企业网站模板
- 技术栈
- 2026年04月20日
-
域名 备案 网站企业网站建设一条龙服务内容
域名 备案 网站企业网站建设一条龙服务内容
- 技术栈
- 2026年04月20日
-
域客式单页网站能申请域名吗做网站流量是什么
域客式单页网站能申请域名吗做网站流量是什么
- 技术栈
- 2026年04月20日
-
域名 网站财税公司做网站
域名 网站财税公司做网站
- 技术栈
- 2026年04月20日
-
域名备案记录查询咸阳seo培训
域名备案记录查询咸阳seo培训
- 技术栈
- 2026年04月20日
-
域名不变 新网站西安做网页的公司
域名不变 新网站西安做网页的公司
- 技术栈
- 2026年04月20日
