昨天有同事问我:“linux hungtask导致卡死了,是什么原因?”

我想了想回答说:“可能你对hungtask有什么误解...,你这句话有问题。”

如果读者看到这里也不清楚哪里有问题,那么这篇文章就有必要继续看下去了。

Linux的几种异常和处理方式

对linux异常挂死打印call trace的行为,很多人都说,linux死了、挂了。但是对熟悉内核问题的人来说,死了,挂了此类描述并不是完全准确。所以我们更多遇到这种对话

“哎,帮我看个linux问题,跑着跑着挂了”

“...给我日志我自己看吧”

为什么呢,因为linux挂了,有很多原因,异常原因常见有hungtask、panic、oom、咬狗、softlockup,下面逐一介绍。

hungtask

现象:

内核打印“INFO: task xxx:xxx blocked for more than 120 seconds.”




centos kill父子进程_linux


触发原因:

内核某进程/线程长期处于D状态,无法唤醒

说明:

1,.必须是内核线程(用户态任务无法触发);但如果某用户态任务调度到内核态,内核态处理出现D,会触发。

2.默认hungtask是不会panic和挂掉,内核只是会打印hung住的堆栈,因为内核无法判断hung住是主观故意为之还是异常,所以内核认为此异常不必须挂掉。

接口:

hungtask默认开启,D时间超过120s会打印,修改时间和关闭开启的接口

hung_task_panic------------------------是否在检测到hung后panic,默认值0

hung_task_check_count---------------最大检查task数量,默认值32768

hung_task_timeout_secs--------------超时时间,默认值120

hung_task_warnings--------------------打印hung warning的次数,默认值10

panic

现象:


centos kill父子进程_默认值_02


panic,英文意思即崩溃,linux走到崩溃之际,将尽可能把它此时能获取的全部信息都打印出来。

触发原因:

内核崩溃,错误原因很多,比如页表异常、硬件不可恢复错误、空指针访问等等。

oom

现象:


centos kill父子进程_linux proc 堆栈_03


触发原因:

Linux内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽内核会把该进程杀掉,同时打印信息。

说明:

1.OOM默认不会挂掉,会尝试kill耗费资源的进程,如果kill后恢复,则系统正常。如果没恢复,会一直kill;

2.Kill顺序首先根据/proc/PID/oom_score_adj设置优先级去kill,同优先级基本先kill耗费内存最大的进程;

设置进程kill优先级接口

/proc/PID/oom_score_adj(注意 points越小越不容易被杀)

softlockup

现象:

打印“[ 56.032356] NMI watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [cat:153]“


centos kill父子进程_默认值_04


说明:

softlockup 死锁,主要用于检测内核的进程调度是否正常,当发生softlockup时,内核不能被调度,

系统在每个cpu上创建一个内核线程,当hrtimer定期执行的回调后会尝试唤醒此线程,如果线程有被正常调度而被唤醒,

它会更新时间变量watchdog_touch_ts,如果没有则不会更新。在hrtimer的回调函数中会判断watchdog_touch_ts和当前

时间差,如果超过给定值,那就证明内核调度失败,接着就打印异常log。

接口

/proc/sys/kernel/nmi_watchdog-------------------------hard lockup开关,
/proc/sys/kernel/soft_watchdog------------------------soft lockup开关,
/proc/sys/kernel/watchdog-----------------------------watchdog总开关,
/proc/sys/kernel/watchdog_cpumask---------------------watchdog cpumaks,
/proc/sys/kernel/watchdog_thresh----------------------watchdog超时阈值设置

总结

在linux异常问题定位时,首先判断异常类型,根据异常触发原理推断异常触发原因,可以极大缩短问题范围。

“linux hungtask导致卡死了,是什么原因?”

“hungtask不会导致卡死,后面应该有其他导致卡死的原因。”