赞
踩
更多内核安全、eBPF分析和实践文章,请关注博客和公众号:
CSDN博客:内核功守道
公众号: 内核功守道
接上篇文章:请记住内核中这个勤劳的监测卫士—Watchdog(Soft lockup篇),本篇详细分析Hard lockup流程和原理,并给出此类问题分析经验,供大家参考。
我们知道,hardware watchdog是Soc内的一个内部外设,是一个硬件模块,常说的watchdog driver指的就是该硬件。Hard lockup比soft lockup更加严重,CPU不仅无法调度其它进程,而且不能响应中断。在开启soft lockup时,已经给每个CPU启动了一个hrtimer定时器,在定时器中断处理函数watchdog_timer_fn中更新hrtimer_interrupts变量。
检测hard lockup的原理是:
static spinlock_t spinlock;
unsigned long flags;
spin_lock_init(&spinlock);
spin_lock_irqsave(&spinlock, flags);
while (1);
1、hrtimer中断处理函数
watchdog_timer_fn()
{
/* hrtimer_interrupts++ */
watchdog_interrupt_count();
/* test for hardlockups on the next cpu */
watchdog_check_hardlockup_other_cpu();
}
2、Hard lockup检测函数
void watchdog_check_hardlockup_other_cpu(void)
{
unsigned int next_cpu;
/* hrtimer的中断4s触发一次,“%3”表示经过3个周期*,即每隔12s检测一下是否 */
/* hard lockup*/
if (__this_cpu_read(hrtimer_interrupts) % 3 != 0)
return;
/* 得到下一颗CPU */
next_cpu = watchdog_next_cpu(smp_processor_id());
if (is_hardlockup_other_cpu(next_cpu)) {
if (hardlockup_panic)//是否panic
panic("Watchdog detected hard LOCKUP on cpu %u", next_cpu);
else
WARN(1, "Watchdog detected hard LOCKUP on cpu %u", next_cpu);
per_cpu(hard_watchdog_warn, next_cpu) = true;
} else {
per_cpu(hard_watchdog_warn, next_cpu) = false;
}
}
3、Hard lockup判断函数
static int is_hardlockup_other_cpu(unsigned int cpu)
{
unsigned long hrint = per_cpu(hrtimer_interrupts, cpu);
/* 如果相等,说明hrtimer中断函数没有执行,出现hard lockup */
if (per_cpu(hrtimer_interrupts_saved, cpu) == hrint)
return 1;
/* 保存最新的hrtimer_interrupts变量值 */
per_cpu(hrtimer_interrupts_saved, cpu) = hrint;
return 0;
}
HARDLOCKUP_DETECTOR_OTHER_CPU
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC
echo 1 > /proc/sys/kernel/hardlockup_panic
Soft lockup用于检测CPU调度是否正常,而Hard lockup主要用于检测CPU中断响应是否正常。内核调度以及中断响应的正常与否,和死锁有很深入的关系,也可以是说是检测系统死锁的一种机制。
遇到此类问题,最有效的方法就是使用Trace32或者ARM DS5这类的在线调试器,查看出现异常卡死的位置或者哪个模块最近一次关了中断没有释放,进一步分析可疑点。
以上两篇详细分析了Soft lockup和Hard lockup流程,并介绍了问题解决思路。可以看到不管是Soft lockup还是Hard lockup,都是从内核态的角度来分析死锁的情况,这也是很多内核工程师经常会遇到的问题。
尽管内核watchdog能检测softlockup 和 hardlockup 并采取相应的措施,但并非所有的系统宕机都是因为内核线程lockup引起的。用户线程/进程一样有可能引发系统宕机的情况。比如,用户程序有可能占着临界资源无法释放或系统太忙(疲于响应各种中断),导致无法调度其他用户进程(此时watchdog内核线程不受影响),这也可能导致系统无法正常使用。
后续会详细分析Android场景下的用户态Watchdog以及具体案例,敬请期待。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。