前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux内核中softlockup,hardlockup代码实现

linux内核中softlockup,hardlockup代码实现

原创
作者头像
cdh
发布2020-06-02 19:25:03
7K1
发布2020-06-02 19:25:03
举报
文章被收录于专栏:笔记+笔记+

代码基于SLES11SP3:

一,softlockup: watchdog软狗/软锁----用于检测系统调度是否正常。 能响应中断,但调度异常。

软件死锁:内核在内核模式下循环超过20s (watchdog_thresh*2),没有给其它进程机会去运行。

默认系统保持死锁显示当前堆栈信息。可以通过softlockup_panic=1来配置主动panic系统。

运行时参数sysctl:

1, /proc/sys/kernel/watchdog -->watchdog_enable //默认为1,使能,开启watchdog

2, /proc/sys/kernel/watchdog_thresh -->watchdog_thresh //默认为10s,但watchdog的定时器检查时间是: watchdog_thresh*2/5

3, /proc/sys/kernel/softlockup_panic -->softlockup_panic //默认为0, 即默认只是显示告警堆栈, 为1表示会panic系统。

4, /proc/sys/kernel/nmi_watchdog -->watchdog_enabled // 0(关闭hardlockup,softlockup); panic,nopanic

:~ # sysctl -a | grep watchdog

kernel.watchdog = 1

kernel.watchdog_thresh = 10

kernel.nmi_watchdog = 1

:~ # sysctl -a | grep softlockup

kernel.softlockup_panic = 0

softlockup与hardlockup的启动参数:

1>,softlockup_panic=1 在检测到softlockup时panic系统, 如果为0,watchdog也会检测softlockup但不会panic.

2>,nosoftlockup/nowatchdog : watchdog_enable=0,即关闭softlockup也会关闭hardlockup,即关闭软狗与硬狗.

启动参数:

3>,nmi_watchdog=[panic,] [nopanic,] [num] ----> hardlockup_panic_setup( )

设置非屏蔽中断(NMI)watchdog的特性。"0"表示禁用NMI watchdog(也会关闭softlockup);

panic: 表示在hardlockup发生时,主动panic系统。nopanic:只打印告警信息。

运行时关闭与开启:

echo 0 >/proc/sys/kernel/nmi_watchdog 运行时关闭硬锁检测。

echo 1> /proc/sys/kernel/nmi_watchdog 运行时重新使能硬锁检测。

4>,nowatchdog: watchdog_enable=0,关闭softlockup 和hardlockup,即关闭软狗与硬狗.

softlockup原理图:

初始化流程:

init/main.c

start_kernel()

rest_init()

-->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); //创建1号进程,它最后会执行用户态的init进程

kernel_init()--> //1号进程

lockup_detector_init(); //watchdog初始化,开启第一个watchdog/%d

cpu_callback(&cpu_nfb,CPU_UP_PREPARE,cpu)

register_cpu_notifier(&cpu_nfb); //把通知块cpu_nfb(回调函数为cpu_callback)加入到通知链cpu_chain

smp_init(); //唤起其它CPU,开启其它watchdog/%d

cpu_up(cpu)

->_cpu_up(cpu, 0);

->__cpu_notify

->notifier_call_chain() //遍历cpu_chain,并执行cpu_nfb通知块对应的函数cpu_callback

kernel/watchdog.c

static int __cpuinit cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)

{

int hotcpu = (unsigned long)hcpu;

switch (action) {

case CPU_UP_PREPARE:

case CPU_UP_PREPARE_FROZEN:

watchdog_prepare_cpu(hotcpu); //初始化定时器watchdog_hrtimer

break;

case CPU_ONLINE:

case CPU_ONLINE_FROZEN:

if (watchdog_enabled)

watchdog_enable(hotcpu); //创建"watchdog/%d"内核线程,也会调用watchdog_nmi_enable(cpu)使能hardlockup

break;

...

}

二,hardlockup: nmi_watchdog硬狗/硬锁----用于检测中断系统是否正常。

硬件死锁:CPU在内核模式下循环超过10s(watchdog_thresh)没有给其它中断机会运行则默认系统保持死锁。可以通过nmi_watchdog=panic配置当检查到hardlockup时主动panic系统.

在当前X86/X86_64的通用平台上,有一个硬件特性:能产生 watchdog NMI interrupts. 即产生:不可屏蔽中断。

通过周期性的执行NMI中断,可以监视每个CPU是否被锁死。

hardlockup: 硬锁实现原理 (当前用PMU实现, Performance monitor units性能管理监视单元)

为了使能NMI watchdog, 内核需要支持APIC。

X86 SMP系统内核:APIC已自动编译进内核。

X86 UP系统内核:需启用CONFIG_X86_UP_APIC(Processor type and features -> Local APIC support on uniprocessors)

或CONFIG_X86_UP_IOAPIC(Processor type and features -> IO-APIC support on uniprocessors)。

注:CONFIG_X86_UP_APIC用于没有IO-APIC的单处理器机器。

CONFIG_X86_UP_IOAPIC用于具有IO-APIC的单处理器。

对于X86_64, APIC也已自动编译进内核。

NMI watchdog中断:

当使用 Local-APIC时,NMI interrupts 频率取决于系统load负载。

因为Local-APIC NMI watchdog没有更好的"中断源". 使用的是"cycles unhalted"事件。当系统idle,CPU在halted状态时不会产生tick事件.

如果系统硬死锁在除了"hlt"指令的任何地方,硬狗watchdog会在每个时钟周期clock tick中因"cycles unhalted"事件很快触发。

但是如果系统硬死锁在了"hlt"指令内, 则"cycles unhalted"事情就不会被触发,即不会触发watchdog.

--这就是Local-APIC watchdog的缺点。不幸的是:没有"clock ticks"事性可以始终工作。

使用 IO-APIC NMI watchdog 没有这个缺点。但是因为它是由外部设备驱动的, 由于它的中断频率比较高,对整个系统的性能有比较大的影响。

硬锁死锁的判断:

如果系统中的任何一个CPU没有执行"周期性的时钟中断"超过10s, 那么NMI处理程序就会产生一个oops并杀死进程.

初始化流程:

kernel/watchdog.c

watchdog_enable(cpu)

-->watchdog_nmi_enable(cpu);

wd_attr = &wd_hw_attr;

wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); // cpu_khz*1000*watchdog_thresh

perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);

PMU说明:翻译 tools/perf/design.txt

linux性能计数器:Performance Counters for Linux

------------------------------

性能计数器(Performance counters)是一类多数现代CPU中都有的特殊硬件寄存器。

这些寄存器计录了一些特定的硬件事件hw events: (不会减慢内核或应用程序)

如:

执行的指令数,instructions executed.

缓存未命中的损失,cachemisses suffered.

分支预测错误,branches mis-predicted.

这些寄存器也可以用来触发中断:比如设置一个事情的阈值,当此事性的阈值到时,就可以产生中断。

因此可以用(寄存器产生的中断)来分析在该CPU上运行的代码。

性能监视:可以参考使用命令perf

源码注释:kernel/watchdog.c

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档