“kernel:NMI watchdog: BUG: soft lockup”内核软死锁BUG分析和解决

发布时间 2023-08-04 00:13:55作者: mini小新

内核软死锁(softlock)bug分析

1、bug现象

shell面板出现以下提示:

kernel:NMI watchdog: BUG: soft lockup - CPU#6 stuck for 28s! CentOS7linux

看门狗监控CPU资源调度捕获的异常进程。

2、bug影响

Soft lockup名称解释:指bug没有让系统彻底死机,但存在若干个进程(或者kernel thread)被锁死在了某个状态(一般在内核区域)。多数情况下是由内核锁的使用问题导致。

内核被锁死(软锁),无法进一步执行任务调度。

软死锁会挂起cpu使你的系统不可用。

3、解决办法

修改watchdog_thresh配置文件,增大看门狗的触发阈值,扩大之后就不容易使系统进入软死锁。

追加到配置文件中:

echo 30 > /proc/sys/kernel/watchdog_thresh 

查看修改结果:

tailf /proc/sys/kernel/watchdog_thresh
>>>30

临时生效:

sysctl -w kernel.watchdog_thresh=30
kernel.watchdog_thresh=30

4、bug原因分析

出现软死锁的原因,大致有以下的可能原因:

1、CPU高负载时间过长
2、服务器电源供电不足,导致CPU电压不稳定
3、vcpus超过物理cpu cores
4、虚机所在的宿主机的CPU太忙或磁盘IO太高
5、虚机机的CPU太忙或磁盘IO太高
6、VM网卡驱动存在bug,处理高水位流量时存在bug导致CPU死锁
7、BIOS开启了超频,导致超频时电压不稳,容易出现CPU死锁
8、Linux kernel或KVM存在bug
9、BIOS Intel C-State开启导致,关闭可解决
10、BIOS spread spectrum开启导致

5、原理分析

Linux内核死锁检测机制

死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务,而且还会占用系统资源,影响其他进程。所以内核中设计了内核死锁检测机制,一旦发现死锁进程,就重启OS,快刀斩乱麻解决问题。之所以使用重启招数,还是在于分布式系统中可以容忍单点崩溃,不能容忍单点进程计算异常,否则进行死锁检测重启OS就得不偿失了。

Linux内核对于每一个cpu都有一个监控进程,在技术界这个叫做watchdog(看门狗)。

通过ps –ef | grep watchdog能够看见,进程名称大概是watchdog/X(数字:cpu逻辑编号1/2/3/4之类的)。

这个进程或者线程每一秒钟运行一次,否则会睡眠和待机。

这个进程运行会收集每一个cpu运行时使用数据的时间并且存放到属于每个cpu自己的内核数据结构。

在内核中有很多特定的中断函数。

这些中断函数会调用soft lockup计数,他会使用当前的时间戳与特定(对应的)cpu的内核数据结构中保存的时间对比,如果发现当前的时间戳比对应cpu保存的时间大于设定的阀值,他就假设监测进程或看门狗线程在一个相当可观的时间还没有执。

Cpu软锁为什么会产生,是怎么产生的?如果linux内核是经过精心设计安排的CPU调度访问,那么怎么会产生cpu软死锁?

那么只能说由于用户开发的或者第三方软件引入,看我们服务器内核panic的原因就是qmgr进程引起。

因为每一个无限的循环都会一直有一个cpu的执行流程(qmgr进程示一个后台邮件的消息队列服务进程),并且拥有一定的优先级。

Cpu调度器调度一个驱动程序来运行,如果这个驱动程序有问题并且没有被检测到,那么这个驱动程序将会暂用cpu的很长时间。

根据前面的描述,看门狗进程会抓住(catch)这一点并且抛出一个软死锁(soft lockup)错误。