从内核恐慌到系统恢复:一次NMI watchdog触发的soft lockup深度诊断
1. 当服务器突然卡死从NMI watchdog错误说起那天下午3点机房警报突然响起。我冲到服务器前屏幕上赫然显示着刺眼的红色错误NMI watchdog: BUG: soft lockup - CPU#2 stuck for 23s!。这台承载着核心业务的服务器就像被冻住一样所有SSH连接全部断开监控图表上的CPU使用率曲线变成了一条直线。这种场景对运维人员来说就像噩梦——系统没有完全死机但核心功能已经瘫痪。soft lockup的本质是CPU被内核代码绑架了就像交通要道被一辆抛锚的卡车完全堵死。与完全死机的hard lockup不同soft lockup时系统还能勉强响应部分中断但这种半死不活的状态往往更让人抓狂。我立即连接了服务器的IPMI控制台发现除了这个错误外系统还在不断吐出网络丢包的警告。这给了我第一个线索网络中断可能是触发条件。通过IPMI导出完整的内核日志后我注意到错误发生前有大量virtio_net驱动的异常记录这提示我需要重点检查虚拟化网络驱动。2. 解剖soft lockup内核的心脏监护仪2.1 NMI watchdog的工作原理Linux内核的NMI watchdog机制就像给CPU安装的心脏监护仪。它由两个关键部分组成hrtimer高精度定时器每4秒默认值触发一次中断唤醒watchdog线程NMI不可屏蔽中断当常规中断无法响应时NMI是最后的救命稻草用医院来类比的话hrtimer就像是定期体检而NMI则是当病人昏迷时使用的电击除颤。当watchdog线程超过20秒2×watchdog_thresh得不到执行就会触发soft lockup报警。# 查看当前watchdog配置 cat /proc/sys/kernel/watchdog_thresh2.2 从dmesg日志中找线索关键的错误日志是这样的[Mon Dec 30 18:39:04 2019] NMI watchdog: BUG: soft lockup - CPU#1 stuck for 31s! [sshd:5071] [Mon Dec 30 18:39:04 2019] RIP: 0010:[ffffffff91f904dc] iowrite160x1c/0x40 [Mon Dec 30 18:39:04 2019] Call Trace: [Mon Dec 30 18:39:04 2019] [ffffffffc03f1584] start_xmit0x264/0x500 [virtio_net]这里有几个关键信息卡死的CPU是1号核心最后执行的函数是iowrite16调用栈显示问题出在virtio_net驱动的数据发送流程3. 深度诊断像侦探一样分析锁死现场3.1 绘制问题时间线通过梳理日志我重建了故障时间线时间事件18:38:33交换机端口开始出现CRC错误18:38:47虚拟机网络吞吐量突然下降90%18:39:04首次出现soft lockup警告18:39:41RCU调度器检测到CPU stall这个时间线清楚地显示网络中断先于CPU锁死说明可能是网络问题触发了内核bug。3.2 复现与压力测试为了验证猜想我搭建了测试环境# 模拟网络丢包 tc qdisc add dev eth0 root netem loss 30% # 启动网络压力测试 iperf -c 192.168.1.100 -t 600 -P 8经过3小时测试成功复现了soft lockup。有趣的是问题只在使用virtio_net驱动时出现切换到vmxnet3驱动后一切正常。4. 解决方案从临时缓解到彻底修复4.1 紧急处置方案当生产环境出现锁死时可以临时调整这些参数# 延长watchdog检测窗口 echo 30 /proc/sys/kernel/watchdog_thresh # 允许自动panic重启 echo 1 /proc/sys/kernel/softlockup_panic但要注意这只是止痛药不是根治方案。我曾见过一个案例调整阈值后系统虽然不报错了但性能下降了40%。4.2 根本解决之道根据我们的分析最终采取了以下措施升级virtio-net驱动从内核4.9升级到4.19调整网络队列减少virtio-net的发送队列长度ethtool -G eth0 tx 256 rx 256优化交换机配置调整端口流控阈值实施后连续监控两周再未出现锁死情况。这个案例让我深刻体会到soft lockup从来不是根本问题而是更深层次bug的症状。5. 经验总结预防优于抢救经过这次事件我们建立了新的监控策略提前预警机制# 监控watchdog事件 grep -c soft lockup /var/log/kern.log压力测试规范所有新服务器上线前必须通过72小时混合负载测试内核参数调优清单针对不同工作负载预设优化配置最让我意外的是事后查阅内核邮件列表发现我们遇到的居然是已知bug——virtio-net驱动在特定网络拥塞场景下会出现自旋锁问题。这提醒我们定期更新内核不仅能获得新特性更是稳定性保障。在技术这条路上每个故障都是最好的老师。那次深夜抢修后我养成了每周浏览内核更新日志的习惯。毕竟预防故障远比解决故障更有价值——对系统如此对人生亦是如此。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2605936.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!