1*b0cbba2eSHailong Liu.. include:: ../disclaimer-zh_CN.rst
2*b0cbba2eSHailong Liu
3*b0cbba2eSHailong Liu:Original: Documentation/admin-guide/lockup-watchdogs.rst
4*b0cbba2eSHailong Liu:Translator: Hailong Liu <liu.hailong6@zte.com.cn>
5*b0cbba2eSHailong Liu
6*b0cbba2eSHailong Liu.. _cn_lockup-watchdogs:
7*b0cbba2eSHailong Liu
8*b0cbba2eSHailong Liu
9*b0cbba2eSHailong Liu=================================================
10*b0cbba2eSHailong LiuSoftlockup与hardlockup检测机制(又名:nmi_watchdog)
11*b0cbba2eSHailong Liu=================================================
12*b0cbba2eSHailong Liu
13*b0cbba2eSHailong LiuLinux中内核实现了一种用以检测系统发生softlockup和hardlockup的看门狗机制。
14*b0cbba2eSHailong Liu
15*b0cbba2eSHailong LiuSoftlockup是一种会引发系统在内核态中一直循环超过20秒(详见下面“实现”小节)导致
16*b0cbba2eSHailong Liu其他任务没有机会得到运行的BUG。一旦检测到'softlockup'发生,默认情况下系统会打
17*b0cbba2eSHailong Liu印当前堆栈跟踪信息并进入锁定状态。也可配置使其在检测到'softlockup'后进入panic
18*b0cbba2eSHailong Liu状态;通过sysctl命令设置“kernel.softlockup_panic”、使用内核启动参数
19*b0cbba2eSHailong Liu“softlockup_panic”(详见Documentation/admin-guide/kernel-parameters.rst)以及使
20*b0cbba2eSHailong Liu能内核编译选项“BOOTPARAM_SOFTLOCKUP_PANIC”都可实现这种配置。
21*b0cbba2eSHailong Liu
22*b0cbba2eSHailong Liu而'hardlockup'是一种会引发系统在内核态一直循环超过10秒钟(详见"实现"小节)导致其
23*b0cbba2eSHailong Liu他中断没有机会运行的缺陷。与'softlockup'情况类似,除了使用sysctl命令设置
24*b0cbba2eSHailong Liu'hardlockup_panic'、使能内核选项“BOOTPARAM_HARDLOCKUP_PANIC”以及使用内核参数
25*b0cbba2eSHailong Liu"nmi_watchdog"(详见:”Documentation/admin-guide/kernel-parameters.rst“)外,一旦检
26*b0cbba2eSHailong Liu测到'hardlockup'默认情况下系统打印当前堆栈跟踪信息,然后进入锁定状态。
27*b0cbba2eSHailong Liu
28*b0cbba2eSHailong Liu这个panic选项也可以与panic_timeout结合使用(这个panic_timeout是通过稍具迷惑性的
29*b0cbba2eSHailong Liusysctl命令"kernel.panic"来设置),使系统在panic指定时间后自动重启。
30*b0cbba2eSHailong Liu
31*b0cbba2eSHailong Liu实现
32*b0cbba2eSHailong Liu====
33*b0cbba2eSHailong Liu
34*b0cbba2eSHailong LiuSoftlockup和hardlockup分别建立在hrtimer(高精度定时器)和perf两个子系统上而实现。
35*b0cbba2eSHailong Liu这也就意味着理论上任何架构只要实现了这两个子系统就支持这两种检测机制。
36*b0cbba2eSHailong Liu
37*b0cbba2eSHailong LiuHrtimer用于周期性产生中断并唤醒watchdog线程;NMI perf事件则以”watchdog_thresh“
38*b0cbba2eSHailong Liu(编译时默认初始化为10秒,也可通过”watchdog_thresh“这个sysctl接口来进行配置修改)
39*b0cbba2eSHailong Liu为间隔周期产生以检测 hardlockups。如果一个CPU在这个时间段内没有检测到hrtimer中
40*b0cbba2eSHailong Liu断发生,'hardlockup 检测器'(即NMI perf事件处理函数)将会视系统配置而选择产生内核
41*b0cbba2eSHailong Liu警告或者直接panic。
42*b0cbba2eSHailong Liu
43*b0cbba2eSHailong Liu而watchdog线程本质上是一个高优先级内核线程,每调度一次就对时间戳进行一次更新。
44*b0cbba2eSHailong Liu如果时间戳在2*watchdog_thresh(这个是softlockup的触发门限)这段时间都未更新,那么
45*b0cbba2eSHailong Liu"softlocup 检测器"(内部hrtimer定时器回调函数)会将相关的调试信息打印到系统日志中,
46*b0cbba2eSHailong Liu然后如果系统配置了进入panic流程则进入panic,否则内核继续执行。
47*b0cbba2eSHailong Liu
48*b0cbba2eSHailong LiuHrtimer定时器的周期是2*watchdog_thresh/5,也就是说在hardlockup被触发前hrtimer有
49*b0cbba2eSHailong Liu2~3次机会产生时钟中断。
50*b0cbba2eSHailong Liu
51*b0cbba2eSHailong Liu如上所述,内核相当于为系统管理员提供了一个可调节hrtimer定时器和perf事件周期长度
52*b0cbba2eSHailong Liu的调节旋钮。如何通过这个旋钮为特定使用场景配置一个合理的周期值要对lockups检测的
53*b0cbba2eSHailong Liu响应速度和lockups检测开销这二者之间进行权衡。
54*b0cbba2eSHailong Liu
55*b0cbba2eSHailong Liu默认情况下所有在线cpu上都会运行一个watchdog线程。不过在内核配置了”NO_HZ_FULL“的
56*b0cbba2eSHailong Liu情况下watchdog线程默认只会运行在管家(housekeeping)cpu上,而”nohz_full“启动参数指
57*b0cbba2eSHailong Liu定的cpu上则不会有watchdog线程运行。试想,如果我们允许watchdog线程在”nohz_full“指
58*b0cbba2eSHailong Liu定的cpu上运行,这些cpu上必须得运行时钟定时器来激发watchdog线程调度;这样一来就会
59*b0cbba2eSHailong Liu使”nohz_full“保护用户程序免受内核干扰的功能失效。当然,副作用就是”nohz_full“指定
60*b0cbba2eSHailong Liu的cpu即使在内核产生了lockup问题我们也无法检测到。不过,至少我们可以允许watchdog
61*b0cbba2eSHailong Liu线程在管家(non-tickless)核上继续运行以便我们能继续正常的监测这些cpus上的lockups
62*b0cbba2eSHailong Liu事件。
63*b0cbba2eSHailong Liu
64*b0cbba2eSHailong Liu不论哪种情况都可以通过sysctl命令kernel.watchdog_cpumask来对没有运行watchdog线程
65*b0cbba2eSHailong Liu的cpu集合进行调节。对于nohz_full而言,如果nohz_full cpu上有异常挂住的情况,通过
66*b0cbba2eSHailong Liu这种方式打开这些cpu上的watchdog进行调试可能会有所作用。
67