当前位置: 首页 > article >正文

RDMA之从userspace verbs 到kernel verbs

用户态RDMA(userspace verbs)RDMA是一种高性能网络协议一般用在GPU集群的高速通信库如NCCL、NVSHMEM等这些都是用户态通信库我们熟知的RDMA大部分都是用户态RDMA。比如如下一个简单的RDMA程序int main() { ​ // 1. 打开 RDMA Device ctx ibv_open_device(); ​ // 2. 创建 Protection Domain pd ibv_alloc_pd(ctx); ​ // 3. 创建 Completion Queue cq ibv_create_cq(ctx); ​ // 4. 创建 Queue Pair qp ibv_create_qp(pd, cq); ​ // 5. 注册 Memory Region mr ibv_reg_mr(pd, buffer); ​ // 6. 连接对端 QP connect_qp(qp); ​ // 7. 构造 Send WR wr.opcode IBV_WR_SEND; wr.sg_list sge; ​ // 8. 发起 RDMA Send ibv_post_send(qp, wr); ​ // 9. 等待 Completion ibv_poll_cq(cq, cqe); ​ printf(Send Complete\n); }我们使用了一堆ibv_xxx api去建立RDMA连接这些用户态程序本质上都是通过libibverbs库调用rdma verbs api然后通过uverbs进入内核Userspace App ↓ libibverbs ↓ uverbs ↓ ib_core ↓ driver ↓ NIC因为涉及到底层的dmaRDMA使用的时候是一定要陷入内核态的那么问题来了可不可以只在内核态使用RDMA内核态RDMA(kernel verbs)在RDMA中除了ibv_xx 这些用户态api其实还有一套ib_xx api称之为kernel verbs api例如Userspace VerbsKernel Verbsibv_alloc_pdib_alloc_pdibv_create_cqib_create_cqibv_create_qpib_create_qpibv_post_sendib_post_sendibv_poll_cqib_poll_cq可以看到kernel verbs 与userspace verbs 在设计上高度对应这也是linux RDMA栈设计很有意思的一点同一套RDMA抽象同时服务于用户态与内核态, userspace verbs 和 kernel verbs的区别基本上在于调用入口不同这些i b_xx api可以直接在 Linux kernel module 中调用调用栈如下Kernel Module ↓ ib_core ↓ Driver ↓ NIC但是kernel和userspace RDMA使用上还是有一些不同的userspace buffermalloc申请的buffer是va无法直接用于dma因此必须ibv_reg_mr() ↓ pin pages ↓ 建立 MTT/PBL ↓ DMA mapping但是kernel bufferkmalloc() ​ dma_alloc_coherent() ​ __get_free_pages()很多情况下已经是kernel direct mapping更容易拿到pa更容易dma因此kernel RDMA更适合driverpage managementDMA subsystempeer memorydma_bufGPU direct内核态RDMA的应用为什么我们需要内核态RDMA因为很多高性能场景中的数据本就存在于linux内核中例如。文件系统缓存块设备请求网络协议栈 bufferDMA bufferGPU peer memory如果将这些内核态的数据拷贝到用户态再调用userspace verbs api这和RDMA零拷贝、低延迟的宗旨不符。内核态RDMA的目标很简单就是让linux内核能够直接发起DMA通信避免用户态拷贝、syscall、多余的数据路径等。!--kernel RDMA数据路径--Kernel Memory ↔ RDMA NICNVME over Fabrics(NVME-of)在NVME-of中远端NVME SSD会通过RDMA暴露给另一台机器NVMe Driver ↓ Block Layer ↓ RDMA整个过程本身就运行在linux内核中如果再经过用户态不仅增加context switch还会破坏存储系统的低延迟属性因此NVME-of会直接在kernel中使用RDMA。NFS-RDMA传统NFS需要经过TCP/IP协议栈而NFS-RDMA直接通过RDMA传输文件数据由于linux VFS 和NFS client本身就运行在内核态因此使用kernel verbs能够避免socket buffer copy、kernel/userspace往返开销、TCP协议开销其他应用场景Software RNICSoft-RDMA Emulator.....一些软件模拟RDMA设备的场景中会直接在kernel中创建 QP处理 WQE生成 CQE管理 DMA buffer这种场景下kernel verbs 更接近RDMA硬件控制接口而不仅仅是普通的通信apikernel case 实践kernel RDMA case长什么样如何运行我们现在来实践一下环境mlx CX8 doca3.0如下是一个最小化的demo框架ib_alloc_pd() ↓ ib_create_cq() ↓ ib_create_qp() ↓ ib_destroy_qp() ↓ ib_destroy_cq() ↓ ib_dealloc_pd()case源码#include linux/module.h #include linux/kernel.h ​ #include rdma/ib_verbs.h ​ #define DRV_NAME kernel_rdma_resource_smoke ​ static char *rdma_dev_name mlx5_0; module_param(rdma_dev_name, charp, 0444); MODULE_PARM_DESC(rdma_dev_name, RDMA device name, e.g. mlx5_0); ​ struct krdma_ctx { struct ib_device *dev; struct ib_pd *pd; struct ib_cq *cq; struct ib_qp *qp; }; ​ static struct krdma_ctx g_ctx; static bool g_created; ​ static void krdma_cq_comp_handler(struct ib_cq *cq, void *ctx) { pr_info(DRV_NAME : CQ completion callback\n); } ​ static void krdma_cq_event_handler(struct ib_event *event, void *ctx) { pr_info(DRV_NAME : CQ event %d\n, event-event); } ​ static void krdma_qp_event_handler(struct ib_event *event, void *ctx) { pr_info(DRV_NAME : QP event %d\n, event-event); } ​ static void krdma_destroy_resources(void) { if (g_ctx.qp) { ib_destroy_qp(g_ctx.qp); pr_info(DRV_NAME : ib_destroy_qp success\n); g_ctx.qp NULL; } ​ if (g_ctx.cq) { ib_destroy_cq(g_ctx.cq); pr_info(DRV_NAME : ib_destroy_cq success\n); g_ctx.cq NULL; } ​ if (g_ctx.pd) { ib_dealloc_pd(g_ctx.pd); pr_info(DRV_NAME : ib_dealloc_pd success\n); g_ctx.pd NULL; } ​ g_ctx.dev NULL; g_created false; } ​ static int krdma_create_resources(struct ib_device *dev) { struct ib_cq_init_attr cq_attr {}; struct ib_qp_init_attr qp_attr {}; int ret; ​ memset(g_ctx, 0, sizeof(g_ctx)); g_ctx.dev dev; ​ pr_info(DRV_NAME : matched RDMA device %s\n, dev_name(dev-dev)); ​ /* * 1. ib_alloc_pd() */ g_ctx.pd ib_alloc_pd(dev, 0); if (IS_ERR(g_ctx.pd)) { ret PTR_ERR(g_ctx.pd); g_ctx.pd NULL; pr_err(DRV_NAME : ib_alloc_pd failed, ret%d\n, ret); goto err; } ​ pr_info(DRV_NAME : ib_alloc_pd success\n); ​ /* * 2. ib_create_cq() */ cq_attr.cqe 16; cq_attr.comp_vector 0; ​ g_ctx.cq ib_create_cq(dev, krdma_cq_comp_handler, krdma_cq_event_handler, g_ctx, cq_attr); if (IS_ERR(g_ctx.cq)) { ret PTR_ERR(g_ctx.cq); g_ctx.cq NULL; pr_err(DRV_NAME : ib_create_cq failed, ret%d\n, ret); goto err; } ​ pr_info(DRV_NAME : ib_create_cq success\n); ​ /* * 3. ib_create_qp() * * 这里只创建 RC QP不 modify_qp不 post_send。 * 目标只是验证 kernel verbs 资源创建/销毁路径。 */ memset(qp_attr, 0, sizeof(qp_attr)); qp_attr.event_handler krdma_qp_event_handler; qp_attr.qp_context g_ctx; qp_attr.send_cq g_ctx.cq; qp_attr.recv_cq g_ctx.cq; qp_attr.qp_type IB_QPT_RC; qp_attr.sq_sig_type IB_SIGNAL_REQ_WR; ​ qp_attr.cap.max_send_wr 16; qp_attr.cap.max_recv_wr 16; qp_attr.cap.max_send_sge 1; qp_attr.cap.max_recv_sge 1; qp_attr.cap.max_inline_data 0; ​ g_ctx.qp ib_create_qp(g_ctx.pd, qp_attr); if (IS_ERR(g_ctx.qp)) { ret PTR_ERR(g_ctx.qp); g_ctx.qp NULL; pr_err(DRV_NAME : ib_create_qp failed, ret%d\n, ret); goto err; } ​ pr_info(DRV_NAME : ib_create_qp success, qpn%u\n, g_ctx.qp-qp_num); ​ pr_info(DRV_NAME : resource smoke success\n); return 0; ​ err: krdma_destroy_resources(); return ret; } ​ static int krdma_add_one(struct ib_device *dev) { const char *name; ​ if (!dev) return 0; ​ name dev_name(dev-dev); if (!name) return 0; ​ pr_info(DRV_NAME : found RDMA device %s\n, name); ​ if (g_created) return 0; ​ if (rdma_dev_name strcmp(rdma_dev_name, name) ! 0) return 0; ​ if (!krdma_create_resources(dev)) g_created true; ​ return 0; } ​ static void krdma_remove_one(struct ib_device *dev, void *client_data) { if (g_ctx.dev dev) krdma_destroy_resources(); } ​ static struct ib_client krdma_client { .name DRV_NAME, .add krdma_add_one, .remove krdma_remove_one, }; ​ static int __init krdma_init(void) { pr_info(DRV_NAME : init, target rdma_dev_name%s\n, rdma_dev_name); return ib_register_client(krdma_client); } ​ static void __exit krdma_exit(void) { pr_info(DRV_NAME : exit\n); ib_unregister_client(krdma_client); krdma_destroy_resources(); } ​ module_init(krdma_init); module_exit(krdma_exit); ​ MODULE_LICENSE(GPL); MODULE_AUTHOR(kernel rdma resource smoke demo); MODULE_DESCRIPTION(Minimal kernel verbs PD/CQ/QP resource smoke example);Makefileobj-m kernel_rdma_resource_smoke.o ​ KVER ? $(shell uname -r) KDIR ? /lib/modules/$(KVER)/build ​ OFED_DIR : /usr/src/ofa_kernel/x86_64/$(KVER) OFED_INC : $(OFED_DIR)/include OFED_SYMVERS : $(OFED_DIR)/Module.symvers ​ PWD : $(shell pwd) ​ ccflags-y -Wall ​ ifneq ($(wildcard $(OFED_INC)/rdma/ib_verbs.h),) ccflags-y -I$(OFED_INC) endif ​ ifneq ($(wildcard $(OFED_SYMVERS)),) KBUILD_EXTRA_SYMBOLS : $(OFED_SYMVERS) endif ​ all: echo Using KDIR$(KDIR) echo Using OFED_INC$(OFED_INC) echo Using OFED_SYMVERS$(OFED_SYMVERS) $(MAKE) -C $(KDIR) M$(PWD) KBUILD_EXTRA_SYMBOLS$(KBUILD_EXTRA_SYMBOLS) modules ​ clean: $(MAKE) -C $(KDIR) M$(PWD) clean编译运行make clean make V1加载sudo insmod kernel_rdma_resource_smoke.ko rdma_dev_namemlx5_0这时候这个程序实际上已经运行了,要看运行结果需要看dmesg日志dmesg -wT预期日志kernel_rdma_resource_smoke: ib_create_qp success, qpn2 kernel_rdma_resource_smoke: resource smoke success卸载sudo rmmod kernel_rdma_resource_smoke总结对比项Userspace RDMAKernel RDMA运行位置userspacekernel是否经过 uverbs是否是否经过 ioctl是否是否直接操作 driver否是APIibv_*ib_*内存来源malloc/mmapkmalloc/dma_allocMR 注册复杂度高较低

相关文章:

RDMA之从userspace verbs 到kernel verbs

用户态RDMA(userspace verbs)RDMA是一种高性能网络协议,一般用在GPU集群的高速通信库,如NCCL、NVSHMEM等,这些都是用户态通信库,我们熟知的RDMA大部分都是用户态RDMA。比如,如下一个简单的RDMA程序int main() { ​// 1…...

深耕区域数字生态,智森传媒赋能本地中小企业破局增长

在本地生活流量红利消退、行业内卷加剧的当下,中小企业数字化转型已不是选择题,而是生存题。十堰智森网络传媒立足本土市场,以技术研发为根基,以区域获客为核心,以数字人直播为抓手,为中小企业搭建全链路数…...

深入解析epoll ET模式与守护进程

引言在前面的文章中,我们学习了 epoll 的基础用法和 LT 模式。本文将深入讲解两个重要主题:epoll 的 ET 模式:边缘触发模式的编程要点与完整实现守护进程:Linux 后台服务进程的原理与编写规范ET 模式是 epoll 高性能的关键&#x…...

win10打印机不能共享报0x0000011b/0x00000709修复工具合集分享 ,亲测解决Windows打印机共享报错问题

先说说我的情况。公司大概十几个人,两台共享打印机,一台接在Win10的台式机上,一台接在Win11的笔记本上。本来用着一直正常,去年开始,陆陆续续有同事反映连不上打印机。 最常见的报错就是0x00000709,还有0x…...

拾亩绿光纯亚麻籽微粉效果怎么样

很多人想通过亚麻籽补充营养,却常遇到传统亚麻籽难吸收、营养易流失的问题:直接嚼咽口感粗糙,普通研磨粉冲调结块,榨油后Omega-3等核心营养大量损耗。拾亩绿光纯亚麻籽微粉依托南京国英健康科技有限公司的专利技术,可解…...

Windows 10 PL2303驱动修复终极指南:3种方案解决串口设备兼容性问题

Windows 10 PL2303驱动修复终极指南:3种方案解决串口设备兼容性问题 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 PL2303驱动修复方案是解决Windows 10系…...

爆单实操课:从3C到美妆,跨境商家如何用AI神器搞定TikTok本土化

每天都有无数跨境卖家在各大社群里发问:怎么用ai生成带货视频,有哪些工具比较好用? 在 TikTok 这个极度依赖内容爆发的平台上,不同类目的产品对视频素材的需求千差万别。靠人工剪辑不仅效率低,且极难跨越本土化语言的障…...

语音真实度突破98.7%的关键在哪?ElevenLabs最新v3.2引擎深度测评,附权威MOS评分对比表

更多请点击: https://intelliparadigm.com 第一章:语音真实度突破98.7%的关键在哪?ElevenLabs最新v3.2引擎深度测评,附权威MOS评分对比表 ElevenLabs v3.2 引擎在2024年Q2发布的音频合成基准测试中,首次在自然度&…...

Sora 2如何“唤醒”3D Gaussian Splatting?:从神经辐射场到毫秒级动态场景生成的4层技术跃迁解析

更多请点击: https://intelliparadigm.com 第一章:Sora 2与3D Gaussian Splatting融合的范式革命 传统视频生成模型受限于体素网格或NeRF隐式表示的计算开销与几何保真度瓶颈,而Sora 2通过引入时空一致性token压缩机制,与3D Gaus…...

基于LLM的多智能体协作框架:从原理到实践构建自主开发团队

1. 项目概述与核心价值最近在开源社区里,一个名为zxkane/autonomous-dev-team的项目引起了我的注意。乍一看这个标题,你可能会联想到科幻电影里的全自动机器人编程,或者是一些过于理想化的“AI接管开发”的噱头。但在我花时间深入研究和实践之…...

PCI总线‘对话’的艺术:主从设备如何通过FRAME#、STOP#信号优雅地‘开始’与‘结束’传输

PCI总线‘对话’的艺术:主从设备如何通过FRAME#、STOP#信号优雅地‘开始’与‘结束’传输 在计算机系统的内部世界里,总线的数据传输就像一场精心编排的舞会。PCI总线作为这场舞会的舞台,主从设备之间的每一次交互都遵循着严格的礼仪规则。这…...

别再乱加电阻了!手把手教你用SI9000搞定PCB阻抗匹配(附50欧姆计算实例)

高速PCB设计实战:用SI9000精准计算阻抗匹配的工程方法 当信号频率突破百兆赫兹时,PCB走线就不再是简单的电气连接——它们变成了需要精密控制的传输线。去年参与一个千兆以太网项目时,我曾目睹团队因阻抗失配导致信号完整性崩溃的惨痛案例&am…...

音频变压器关键参数深度解析:Z值与最大电流的工程实践

音频变压器关键参数深度解析:Z值与最大电流的工程实践引言在专业音频系统、高保真音响以及工业信号隔离场景中,音频变压器始终扮演着不可替代的角色。它的核心使命是在保持信号完整性的同时,完成阻抗匹配、地环路隔离和信号平衡转换三大任务。…...

为AI智能体构建可编程邮箱:mailbot实战指南

1. 项目概述:为AI智能体打造专属的“可编程邮箱”如果你正在开发一个AI智能体,无论是客服机器人、自动化工作流还是个人助理,让它具备收发邮件的能力往往是刚需。传统的做法是什么?要么去折腾Gmail的API,忍受OAuth授权…...

3分钟掌握Krita AI抠图:点一下就能完成的智能选区革命

3分钟掌握Krita AI抠图:点一下就能完成的智能选区革命 【免费下载链接】krita-vision-tools Krita plugin which adds selection tools to mask objects with a single click, or by drawing a bounding box. 项目地址: https://gitcode.com/gh_mirrors/kr/krita-…...

百度文库文档免费下载终极指南:3步快速获取纯净PDF

百度文库文档免费下载终极指南:3步快速获取纯净PDF 【免费下载链接】baidu-wenku fetch the document for free 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wenku 你是否曾在百度文库找到心仪的文档,却被烦人的广告、付费提示和杂乱页面…...

【DeepSeek开发者垂直搜索实战指南】:3大行业落地案例+5个避坑要点,限时公开内部调优参数

更多请点击: https://intelliparadigm.com 第一章:DeepSeek开发者垂直搜索应用案例全景概览 DeepSeek系列大模型凭借其开源、高性能与强推理能力,正被广泛集成至开发者垂直搜索场景中——从代码片段检索、API文档语义查找,到私有…...

【力扣100题】22. 矩阵置零

一、题目描述 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2: …...

日本电子产业转型启示:从技术过剩到商业模式创新

1. 日本电子产业的十字路口:一场箱根闭门会背后的行业剧痛2013年的春天,当全球电子产业的聚光灯都打在硅谷和深圳时,日本箱根的一家温泉旅馆里,正进行着一场鲜为人知却意义深远的对话。索尼、瑞萨、NEC、日立、松下、富士通、Mega…...

AXI协议深度解析:从握手到低功耗,一次搞懂芯片内部数据流的那些“潜规则”

AXI协议深度解析:从握手到低功耗,一次搞懂芯片内部数据流的那些“潜规则” 在当今高性能计算和复杂SoC设计中,AXI协议已成为连接处理器、存储器和外设的黄金标准。但真正理解AXI的精髓,远不止于掌握基础操作——那些隐藏在规范字里…...

Excel数据同步ERP/CRM太麻烦?一个Python脚本搞定多系统自动填充(基于GoBot)

Excel数据同步ERP/CRM太麻烦?一个Python脚本搞定多系统自动填充(基于GoBot) 每次月底看着财务同事在ERP系统里逐条录入Excel数据,市场部同事又在CRM里重复同样的操作,这种低效场景你一定不陌生。数据在不同系统间的孤岛…...

告别桌面混乱!Ubuntu 16.04 多桌面+Terminator分屏,打造程序员高效工作流

Ubuntu 16.04多桌面与Terminator分屏:构建程序员的高效工作流 作为一名长期在Ubuntu环境下工作的开发者,我深刻体会到工作环境配置对效率的影响。桌面混乱、窗口堆叠、频繁切换不仅浪费时间,还会打断编程的"心流"状态。经过多次迭代…...

告别龟速下载!实测对比Axel、Aria2、mwget三大神器,教你选对多线程工具

三大命令行下载神器深度横评:Axel、Aria2与mwget的性能对决 当你在终端里反复输入wget或curl命令,盯着缓慢增长的进度条时,是否想过还有更高效的解决方案?本文将带你深入探索Axel、Aria2和mwget这三款命令行下载加速工具&#xff…...

MGRE实验报告

一.实验概述实验名称:MGRE实验实验目的:掌握 PPP 协议的 PAP/CHAP 认证与 HDLC 封装配置,理解不同广域网链路协议的工作机制与认证流程。实现 MGRE 环境(R1 为 Hub)与 GRE 环境的部署,理解点到多点 VPN 与点…...

DDR3内存训练(Training)完全解析:从原理到代码,深入浅出

DDR3内存训练(Training)完全解析:从原理到代码,深入浅出 目录 一、为什么需要内存训练? 二、DDR3训练的核心原理 三、训练流程详解:一场精密的三步仪式 四、代码实战:从初始化到训练完成...

C语言-指针二

一. 指针的操作int main() {int a 10 , b 20, c 30;int *p NULL, *q NULL;p &a;//对指针变量p本身进行修改b *p;//*p为右值表示对变量a的读取*p 60;//*p为左值表示通过指向的内存空间对变量a的写入p &c;//p指向的内存空间发生变化b *p;//对c的读取操作*p 70…...

iOS越狱防火墙ijfw:从网络流量监控到精细化应用管控实战

1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫ijfw,全称是iOS Jailbreak Firewall。顾名思义,这是一个专门为越狱后的iOS设备设计的防火墙工具。如果你和我一样,是个喜欢在iPhone上“折腾”的玩家,或者对…...

数据中心机架内互连新范式:为何PCIe正取代以太网与InfiniBand?

1. 数据中心互连的十字路口:为什么是PCIe?在数据中心这个庞大而精密的数字世界里,服务器、存储和网络设备之间的“对话”效率,直接决定了整个系统的性能上限。过去十几年,我们习惯了用以太网(Ethernet&…...

Windows下Python包管理权限踩坑实录:从WinError 5到WinError 32的完整解决流程

Windows下Python包管理权限问题深度解析:从WinError 5到WinError 32的实战指南 作为一名长期在Windows平台进行Python开发的工程师,我深刻理解文件权限问题带来的困扰。特别是当你在紧急项目交付前夜,突然遭遇PermissionError: [WinError 5]或…...

从五管OTA到两级运放:在Cadence IC617中如何规划你的设计指标与晶体管尺寸(gm/id方法详解)

从五管OTA到两级运放:gm/id设计方法在Cadence IC617中的策略性应用 在模拟集成电路设计中,运算放大器的设计始终是工程师面临的核心挑战之一。特别是当设计需求从简单的五管OTA扩展到更复杂的两级运放时,设计者需要处理的不仅仅是晶体管尺寸的…...