soft lockup 解决思路

soft lockup 解决思路,第1张

前几天,帮同事一起查一个机器老是挂死无法进入问题,说有一台虚拟机时不时登陆不上挂死,同时甲方竟然没有这些主机监控,判断不了当时的cpu,内存,网络等的基础数据信息,那就只能看看内核信息了。

通过dmesg命令显示如下图,可以看到有soft lockup- CPU..stuck for 24s!字样,soft lockup是一种内核死锁检查的方式,类似于程序的心跳,打印这句话表示发生了内核软锁死。linux中每个cpu都设置了一个看门狗

进程,来检测内存软锁的问题,如果进程进入死锁或者进入死循环,长时间看门狗进程得不到调度,系统检测到进程占用cpu的时间超出特定的时间值后,会打印soft lockup告警,告警包含占用时长和进程名以及pid。

它的原理查了下:

也可以直接修改启动参数:

如下参数也都可以在/etc/default/grub修改GRUB_CMDLINE_LINUX行添加

这样在重启的时候不需要重新设置。

为了打印内核的core信息,需要安装kdump且启动程序

这是正常的,因为softpoint的作者已经不打算更新了。

softpoint电脑版是一款非常强大的里番在线播放和下载工具,可以搜索到最新最全的真人cospiay视频和日本动漫系的资源,可以在电脑上进行资源播放、下载,应用集合了2000-2015年的所有精彩里番视频,并且每月会对新番进行更新让不错过任何一部精彩视频。

一、概述

    Softlockup主要用于检查cpu上的任务是否有无法被调度的情况发生。其原理就是在cpu上创建一个实时FIFO优先级为99的percpu内核线程(一般情况下可以认为是系统中优先级最高的任务),其名字为watchdog;此任务一般会由一个高精度定时器htimer定期唤醒,唤醒后watchdog线程会去执行“喂狗” *** 作(具体而言就是将当前的时间戳写到变量watchdog_touch_ts)。同时,c这个htimer定时器还会定期检查此cpu上“喂狗”是否有发生,即判断当前时间戳与watchdog_touch_ts的差值是否大于一个门限,内核用get_softlockup_thresh()函数来取得此门限值,默认为20秒。 如果htimer定时器检测到watchdog_touch_ts距离现在已经超过了门限值就判断为发生了softlockup。

    触发softlockup的场景有许多种可能,例如在某个cpu上有优先级99的死循环FIFO任务;或者系统中有不健康的软中断在长时间进行软中断处理;又或者内核中产生了死循环等等

二、检测原理

    在上面已经了解到softlockup的检测依赖于两个对象:watchdog线程和定时器htimer。

    定时器htimer。 这个定时器的周期由内核中的变量sample_period来表示,默认为4秒。这个变量又由内核中的另外一个变量watchdog_thresh计算而来,其具体计算方式为:sample_period=watchdog_thresh * 2*(NSEC_PER_SEC/5),单位纳秒。内核中watchdog_thresh默认为10,用户可以通过/proc/sys/kernel/watchdog_thresh来指定。例如执行

echo 15 >/proc/sys/kernelwatchdog_thresh

后,sample_period的值,即定时器的周期就设置为6秒。

    当定时器到期后会调用htimer的时钟处理函数watchdog_timer_fn()做如下事情:

    (1) 唤醒watchdog线程;

    (2) 检查是否有发生softlockup;

    (3) 如果有发生softlockup则进行处理。

    这里第(2)步是如何检查是否有发生softlockup呢?原理就是检查上一次watchdog线程“喂狗”时距离现在的时间间隔是否超过了门限值softlockup_thresh,默认为20秒。其计算方式为softlockup_thresh=watchdog_thresh * 2。  上面已经提过watchdog_thresh默认为10,可通过/proc接口修改。

watchdog内核线程。 看门狗线程watchdog是由内核创建的percpu线程,创建后一直睡眠,然后等待htimer周期性的唤醒自己。被唤醒后watchdog线程就会去“喂狗”,即将当前时间戳写入到percpu变量watchdog_touch_ts中;

    正常情况下每隔每隔sample_period秒的实际watchdog线程就会被唤醒一次,由于watchdog线程的优先级是实时FIFO调度策略99的优先级,因而它是系统中优先级最高的任务了。由于它首屈一指的高优先级,可以预测的是,唤醒后它会有机会立刻得到运行(除非系统中也有优先级为99的FIFO任务在运行状态),即去更新watchdog_touch_ts变量。因而,我们还可以预测,正常情况下watchdog_touch_ts每隔sample_period秒就会更新一次,或者说递增一次,递增的粒度也正好是htimer时钟的周期sample_period。

这种预测在何时可能不成立呢?

    (1) watchdog没有被及时唤醒。这种情况就是htimer没有及时触发;由于htimer唤醒是在高精度时钟中断中完成的,除非时钟中断出现问题,否则watchdog不会出现这种情况。而这种情况多半是长时间关闭本地中断造成的,这种情况一般需要通过hardlockup机制来检测;

    (2) 系统中有长时间处于软中断处理函数。虽然watchdog线程优先级很高,但是只是任务级别的执行流,对于软中断执行流程是优先级更低的。假如系统中的有一个软中断由于某种原因进入到了死锁或者死循环,那么watchdog线程是无法执行的,这样watchdog_touch_ts也无法及时得到更新。

    (3) cpu上有优先级为99的FIFO任务一直占有cpu。实时FIFO的调度策略是严格按优先级调度的,而同等优先级的任务遵守先来先运行、一直到无法再运行为止的原则。因而,如果cpu上原来已经有一个调度策略为FIFO且优先级为99的任务一直占有CPU时watchdog即使被唤醒后也是无法得到运行的。

    这里列举了典型的三种watchdog无法及时获得cpu运行的情况,也就是发生soft lockup的典型情况,也就是说明此cpu有比FIFO99优先级相等或更高优先级的任务/模块在一直占用cpu。

三、softlockup的处理

    一旦发生softlockup内核一般会有类似如下的打印:

# BUG: soft lockup - CPU#%d stuck for 22us! [loop:1023]

    即softlockup的处理主要是打印告警信息以通知相关人员有相关情况发生。整个处理流程有如下几个部分:

    (1) 通过soft_watchdog_warn判断是否已经发生过告警信息打印,则不再继续;

    (2) 打印告警信息和current现场等等告警信息;

    (3) 如果softlockup_all_cpu_backtrace变量使能,则打印其他各个cpu的堆栈回溯信息,这个变量可通过/proc/sys/kernel/softlockup_all_cpu_backtrace接口来enable/disable;

   (4) 如果使能softlockup_panic变量,则进入panic。变量softlockup_panic可通过/proc/sys/kernel/softlockup_panic来修改。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9583691.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存