0%

watchdog分析


作者: 耗子007


softlockup和hardlockup含义

softlockup

内核在内核模式loop超过get_softlockup_thresh()获取的阈值时间,导致其他任务没有机会运行的bug,称为”softlockup”。
简单来说,就是抢占被关闭时间超过阈值,导致其他进程无法调度。

hardlockup

CPU在内核模式loop时间超过hw_nmi_get_sample_period函数获取的阈值时间,导致其他中断不能运行的bug,称为”hardlockup”。
简单来说,就是中断被关闭时间超过阈值,导致其他中断无法运行。

softlockup注册和触发流程

基于proc文件系统的watchdog流程

1
2
3
4
5
6
7
proc_watchdog_update 更新watchdog状态,如果开启了watchdog,触发开狗流程
--> watchdog_enable_all_cpus 打开所有cpu的狗
--> smpboot_register_percpu_thread(&watchdog_threads) 创建启动所有CPU上面的hotplug相关线程
--> __smpboot_create_thread 创建线程,线程执行的函数是smpboot_thread_fn
--> smpboot_thread_fn 开始会注册调用watchdog_threads的setup(就是watchdog_enable),正常流程会不断的执行watchdog_threads的thread_fn
--> watchdog_enabled 会启动一个hrtimer的定时器,触发的回调函数是watchdog_timer_fn
--> watchdog_timer_fn 根据is_softlockup判断是否发生softlockup

watchdog函数就是喂狗,保证不出现softlockup,这里不需要关注太详细。

1
2
3
4
5
6
7
8
9
static void watchdog(unsigned int cpu)
{
__this_cpu_write(soft_lockup_hrtimer_cnt,
__this_cpu_read(hrtimer_interrupts));
__touch_watchdog();

if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
watchdog_nmi_disable(cpu);
}

内核初始化时的流程

tick的方式,注册watchdog。

1
2
3
4
5
6
7
8
kernel_init 内核初始化
--> kernel_init_freeable
--> lockup_detector_init 如果开狗了会执行watchdog_enable_all_cpus;如果开启了CONFIG_TICKLESS,会注册tick_notify。
--> watchdog_enable_all_cpus 后续流程和proc的一致,参考上面的分析
--> register_tick_notifier 注册回调函数softlockup_tickonoff_callback
--> softlockup_tickonoff_callback 注册回调函数softlockup_tick_onoff
--> softlockup_tick_onoff 如果tick是打开的,会启动一个hrtimer,定期执行watchdog_timer_fn函数
--> watchdog_timer_fn 和上面的流程一致了