Watchdog,是内核用于检测系统CPU是否锁死的机制。一旦检测到系统CPU出现锁死的情况,watchdog会主动触发系统复位。常见的CPU锁死的情况分为soft-lockup与hard-lockup,分别对应的是线程在CPU上一直得不到调度与中断在系统中得不到响应。
硬件watchdog与软件watchdog
watchdog分为两种实现方式,一种是硬件实现,一种是软件实现。不论是硬件实现还是软件实现,最终都可以在/dev/watchdog生成watchdog的设备文件。
硬件watchdog,需要有真实的硬件设备的支撑。在一定时间内如果检测到/dev/watchdog文件没有被写入,那么驱动会通知硬件设备触发系统复位。
软件watchdog,基于内核的高精度定时器实现,触发后通过软件控制系统复位。
一个/dev/watchdog设备同一时间内只支持软件watchdog与硬件watchdog中的一个。
Soft-lockup
Soft-lockup的检测原理,是内核会在每个CPU上注册一个watchdog线程,这个线程会由内核的高精度定时器hrtimer产生时钟中断定时去唤醒处理,一旦在规定的时间阈值就内这个线程没有得到处理,会认为这个CPU被占住了得不到调度(如发生了死锁、未让出的死循环等),即发生了sof-lockup。
内核注册soft watchdog线程的方式如下。先定义soft watchdog的处理线程和线程名等信息,其中的watchdog是线程定期调用的喂沟函数,负责更新时间戳。
static struct smp_hotplug_thread watchdog_threads = {
.store = &softlockup_watchdog,
.thread_should_run = watchdog_should_run,
.thread_fn = watchdog,
.thread_comm = "watchdog/%u",
.setup = watchdog_enable,
.cleanup = watchdog_cleanup,
.park = watchdog_disable,
.unpark = watchdog_enable,
};
然后通过smpboot_register_percpu_thread接口在每个CPU上均注册一个watchdog对象。 注册后,会在CPU上创建一个watchdog线程,并调用watchdog处理。
if (!watchdog_running) {
err = smpboot_register_percpu_thread(&watchdog_threads);
if (err)
pr_err("Failed to create watchdog threads, disabled\n");
else {
if (smpboot_update_cpumask_percpu_