昨天有同事问我:“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.”
触发原因:
内核某进程/线程长期处于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
现象:
panic,英文意思即崩溃,linux走到崩溃之际,将尽可能把它此时能获取的全部信息都打印出来。
触发原因:
内核崩溃,错误原因很多,比如页表异常、硬件不可恢复错误、空指针访问等等。
oom
现象:
触发原因:
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]“
说明:
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不会导致卡死,后面应该有其他导致卡死的原因。”