Mellanox OFED编译实战:从源码到内核模块加载全流程

张开发
2026/4/11 16:18:16 15 分钟阅读

分享文章

Mellanox OFED编译实战:从源码到内核模块加载全流程
1. Mellanox OFED编译前的准备工作第一次接触Mellanox OFED驱动编译的朋友可能会觉得有点懵这玩意儿到底是干啥的简单来说它就是Mellanox网卡的灵魂伴侣。就像给新买的手机装系统一样没有合适的驱动再好的网卡也发挥不出性能。我当年第一次编译时踩了不少坑今天就把这些经验都分享给大家。首先得确认你的硬件环境。Mellanox网卡主要有ConnectX和BlueField两大系列不同型号对OFED版本要求可能不同。建议先用lspci | grep Mellanox查看网卡型号再去官网确认兼容的OFED版本。我遇到过最坑的情况是用了不匹配的版本编译过程一切顺利结果网卡死活不认。软件环境准备也很关键。建议使用CentOS或RHEL系统Ubuntu虽然也能用但会遇到更多依赖问题。内核开发包必须安装用yum install kernel-devel kernel-headers搞定。有次我偷懒没装configure阶段直接报错排查了半天才发现是这个原因。另外gcc、make这些基础工具链就不用说了版本不要太老就行。下载源码包时要注意区分OFED和MLNX_OFED。前者是开源版本后者是Mellanox的商业发行版。我们这里主要讨论开源版本的编译。官网下载页面有时候会让人眼花缭乱建议直接搜索MLNX_OFED_LINUX开头的tar包。我习惯把源码放在/usr/src目录下这样符合Linux惯例也方便后续管理。2. 源码获取与解压的正确姿势很多人觉得下载解压源码是最简单的部分其实这里面的门道也不少。Mellanox官网的源码包有两种格式rpm和tar.gz。我强烈建议选择tar.gz格式因为rpm包还需要额外解压步骤容易出问题。下载命令推荐用wgetwget https://linux.mellanox.com/public/repo/mlnx_ofed/5.5-1.0.3.2/MLNX_OFED_SRC-5.5-1.0.3.2.tgz注意替换成你需要的版本号。下载完成后别急着解压先用md5sum校验下完整性。我就遇到过下载中途断线导致文件损坏的情况结果编译到一半各种诡异错误。解压命令很简单tar -xzvf MLNX_OFED_SRC-5.5-1.0.3.2.tgz但有个细节要注意解压后的目录名可能很长建议重命名为简单形式比如ofed_src。这样后续操作方便很多不用每次都输入一长串路径。进入源码目录后你会看到一堆子目录。核心代码主要在ofed_scripts和ofed_kernel这两个目录里。前者包含配置脚本后者是内核模块源码。第一次看可能会觉得结构复杂其实只要关注几个关键文件就行。3. 配置阶段的那些坑配置阶段是整个编译过程最容易出错的地方。Mellanox的configure脚本参数多得吓人但实际常用的就那么几个。最基本的配置命令是这样的./configure --kernel-version$(uname -r) --with-core-mod --with-mlx5-mod -j$(nproc)这个命令做了三件事指定当前内核版本、启用核心模块、启用mlx5模块。-j参数表示并行编译nproc会自动获取CPU核心数。但实际项目中往往需要更多功能。比如要支持RDMA和IPoIB的话就得加上这些参数./configure --kernel-version$(uname -r) \ --with-core-mod \ --with-user_mad-mod \ --with-user_access-mod \ --with-mlx5-mod \ --with-ipoib-mod \ --with-isert-mod \ --with-iser-mod \ --with-srp-mod \ --with-scsi_transport_srp-mod \ -j$(nproc)配置过程中最常见的错误是依赖缺失。如果看到Could not find XXX之类的错误基本就是缺开发包了。比如报错缺少libssl就需要安装openssl-devel。我建议提前安装这些常见依赖yum install -y openssl-devel libnl3-devel python-devel rpm-build另一个坑是内核版本匹配问题。如果你的内核是自己编译的或者用了非标准内核可能会遇到版本不匹配。这时可以尝试--kernel-sources参数手动指定内核源码路径。有次我遇到个奇葩情况系统报告的内核版本和实际不符最后发现是uname和实际运行的内核不一致折腾了好久。4. 编译与安装的实战技巧配置成功后编译阶段相对简单。直接运行make -j$(nproc)这个-j参数和configure时一样表示并行编译。建议根据CPU核心数设置能显著加快编译速度。不过要注意并行编译虽然快但出错时的日志会比较乱。如果遇到编译错误可以先不加-j参数单线程编译这样更容易定位问题。编译过程中可能会遇到警告只要不是错误就不用管。但有种情况要特别注意如果看到incompatible pointer type这类内核模块特有的警告最好重视起来。我有次忽略了这类警告结果加载模块时直接kernel panic了。编译完成后安装命令很简单make install但建议先不急着安装而是手动加载测试。这是因为安装会覆盖系统原有驱动万一新驱动有问题系统可能就无法正常联网了。内核模块的编译结果一般在./ofed_kernel/build目录下。可以用find命令快速查找所有生成的.ko文件find . -name *.ko -type f把这些文件复制到一个临时目录方便后续测试mkdir -p /tmp/ofed_modules find . -name *.ko -exec cp {} /tmp/ofed_modules \;5. 内核模块加载的注意事项模块加载是最关键的环节也是问题最多的阶段。首先必须卸载旧版驱动顺序很重要。错误的卸载顺序会导致模块还在使用中无法卸载。标准的卸载顺序应该是rmmod mlx_compat rmmod mlx5_ib rmmod mlx5_core rmmod ib_iser rmmod rdma_ucm rmmod ib_umad rmmod ib_uverbs rmmod ib_ipoib rmmod rdma_cm rmmod ib_cm rmmod iw_cm rmmod ib_core如果提示模块正在使用中可以尝试先停止相关服务systemctl stop opensm systemctl stop rdma有时候需要多执行几次rmmod或者加上-f强制卸载。但强制卸载有风险可能导致系统不稳定。加载新模块的顺序也很讲究基本是卸载的逆序insmod /tmp/ofed_modules/ib_core.ko insmod /tmp/ofed_modules/ib_cm.ko insmod /tmp/ofed_modules/iw_cm.ko insmod /tmp/ofed_modules/rdma_cm.ko insmod /tmp/ofed_modules/ib_umad.ko insmod /tmp/ofed_modules/ib_uverbs.ko insmod /tmp/ofed_modules/mlx5_core.ko insmod /tmp/ofed_modules/mlx5_ib.ko加载后可以用这些命令检查状态dmesg | tail -20 # 查看内核日志 ibstat # 查看IB设备状态 ibv_devinfo # 查看详细设备信息6. 常见问题排查指南遇到模块加载失败时首先查看dmesg输出。最常见的错误是Unknown symbol这通常是因为模块依赖关系没处理好。比如加载mlx5_ib时提示缺少mlx5_core的符号说明加载顺序错了。版本不匹配也是个常见问题。症状包括模块能加载但设备不识别或者性能异常。可以用modinfo检查模块版本modinfo mlx5_core | grep version确保所有相关模块版本一致。如果遇到网卡不识别先检查物理连接和PCI设备状态lspci -d 15b3: # 15b3是Mellanox的厂商ID如果设备没显示可能是硬件问题或者PCI枚举有问题。性能调优方面建议关注这些参数cat /sys/class/infiniband/mlx5_0/ports/1/hw_counters/*这些计数器能帮助诊断性能瓶颈。我遇到过因为MTU设置不当导致RDMA性能下降50%的情况。7. 进阶技巧与优化建议对于生产环境建议使用DKMS自动重建内核模块。这样升级内核后就不用手动编译了。具体做法是编译时加上--with-dkms参数然后安装DKMS包yum install dkms ./configure --with-dkms ... make make install性能调优方面可以调整这些内核参数echo 65535 /sys/class/infiniband/mlx5_0/ports/1/smi/port_pkey_tbl_len echo 2048 /sys/module/mlx5_core/parameters/log_num_mgm_entry_size对于NVMe over Fabrics场景需要额外启用这些模块--with-nvmf-mod --with-nvme-mod最后提醒下编译环境最好保持干净。我习惯用Docker容器来编译避免污染主机环境。这样也能方便地测试不同版本的兼容性。

更多文章