3、操作系统准备:Linux内核版本要求、驱动安装(MLNX_OFED)、固件升级、NUMA绑定与CPU隔离
好,咱们进入实操环节。操作系统准备这块,说白了就是给RDMA搭个稳当的“地基”。我见过太多人,硬件买得挺贵,结果系统层面没弄好,性能直接腰斩。今天咱们就把这四步走扎实:内核、驱动、固件、还有NUMA和CPU的绑定。
3.1 Linux内核版本要求
先聊内核。RDMA对内核版本其实挺挑剔的。你想想看,内核里要是缺了某些关键模块,或者版本太老,那MLNX_OFED驱动装上去也跑不起来。
我个人习惯,生产环境首选RHEL 8.4以上,或者Ubuntu 20.04 LTS。内核版本建议在4.18以上,最好是5.x系列。为什么?因为从4.18开始,内核里对RoCEv2的支持才比较完整。我之前在CentOS 7.6(内核3.10)上折腾过,嗯,那叫一个痛苦——很多新特性不支持,还得自己打补丁。
内核版本速查表
| 操作系统 | 推荐内核版本 | 备注 |
|---|---|---|
| RHEL/CentOS 8.x | 4.18.0-305+ | 建议升级到最新小版本 |
| Ubuntu 20.04 LTS | 5.4.0-100+ | HWE内核更好 |
| Ubuntu 22.04 LTS | 5.15.0-50+ | 原生支持较好 |
怎么查内核版本?很简单:
uname -r
如果版本太低,我建议你直接升级。别想着凑合用,RDMA这玩意儿对内核依赖太深,省不了这一步。
3.2 驱动安装(MLNX_OFED)
驱动安装是重头戏。MLNX_OFED是Mellanox(现在叫NVIDIA)官方的驱动包,集成了网卡驱动、RDMA核心库、还有各种工具。
我建议,永远从官网下载最新LTS版本。别用系统自带的驱动,那个太老了。下载地址我就不贴了,你搜“MLNX_OFED download”就能找到。
安装步骤其实不复杂:
# 1. 下载对应系统的驱动包
wget http://www.mellanox.com/downloads/ofed/MLNX_OFED-5.8-1.0.1.1/MLNX_OFED_LINUX-5.8-1.0.1.1-rhel8.6-x86_64.tgz
# 2. 解压
tar xzf MLNX_OFED_LINUX-5.8-1.0.1.1-rhel8.6-x86_64.tgz
# 3. 进入目录
cd MLNX_OFED_LINUX-5.8-1.0.1.1-rhel8.6-x86_64
# 4. 安装(带参数)
./mlnxofedinstall --add-kernel-support --force
小技巧:加上--add-kernel-support参数,驱动会自动编译适配当前内核。不加的话,万一内核版本不匹配,驱动就装不上。
安装过程中可能会报依赖缺失。别慌,看提示装一下就行。RHEL系用yum install,Ubuntu用apt install。
装完之后,重启一下:
reboot
然后检查驱动状态:
ibstat
ibv_devinfo
能看到网卡信息,说明驱动装好了。我记得有一次,客户那边装完驱动后ibstat报错,查了半天发现是固件版本太老。嗯,这就引出了下一步。
3.3 固件升级
固件这事儿,很多人容易忽略。你想想看,驱动是软件,固件是网卡自己的“操作系统”。固件太老,很多新特性用不了,甚至可能出bug。
我曾经遇到过一个案例:某数据中心部署RoCEv2,性能死活上不去。排查了三天,最后发现是固件版本低了两个大版本。升级之后,延迟直接降了30%。
升级固件用mlxup工具:
# 下载mlxup
wget http://www.mellanox.com/downloads/firmware/mlxup
# 加执行权限
chmod +x mlxup
# 运行(会自动检测并升级)
./mlxup
注意:升级固件有风险!千万别在生产环境直接操作。我建议先在测试机上验证,确认没问题再批量升级。升级过程中绝对不能断电,否则网卡就变砖了。
升级完成后,重启网卡或者重启机器:
# 重启网卡
mlxfwreset -d /dev/mst/mt4123_pciconf0 reset
# 或者直接重启机器
reboot
升级后再次检查固件版本:
flint -d /dev/mst/mt4123_pciconf0 query
确保版本号跟官网最新一致。
3.4 NUMA绑定与CPU隔离
这部分是性能调优的关键。说白了,就是让网卡和CPU“就近”通信,别跨NUMA节点。
先查一下你的NUMA拓扑:
lscpu | grep -i numa
numactl --hardware
你会看到类似这样的输出:
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7
node 1 cpus: 8 9 10 11 12 13 14 15
node 0 size: 65536 MB
node 1 size: 65536 MB
然后查网卡在哪个NUMA节点上:
cat /sys/class/infiniband/mlx5_0/device/numa_node
假设网卡在NUMA 0上,那你的应用程序就应该绑定在NUMA 0的CPU上跑。怎么做?
# 绑定到NUMA 0的CPU核心
numactl --cpunodebind=0 --membind=0 ./your_rdma_app
我个人习惯,还会做CPU隔离。把一部分核心专门留给RDMA应用,不让其他进程干扰。
修改/etc/default/grub,在GRUB_CMDLINE_LINUX里加上:
isolcpus=0-3 nohz_full=0-3 rcu_nocbs=0-3
然后更新grub:
grub2-mkconfig -o /boot/grub2/grub.cfg
重启后,核心0-3就隔离出来了。只有你指定的进程才能用它们。
避坑指南:隔离CPU后,记得把系统中断也绑到其他核心上。否则中断来了,隔离核心还是会被打断。用irqbalance或者手动设置/proc/irq/下的smp_affinity。
最后,验证一下绑定效果:
# 查看进程运行在哪个核心
taskset -p <pid>
嗯,到这里,操作系统层面的准备工作就差不多了。内核对了,驱动装了,固件升了,NUMA和CPU也绑好了。接下来就可以放心地配置网络和RDMA参数了。