linux内核中watchdoglockupstallhung等检测
Posted 为了维护世界和平_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核中watchdoglockupstallhung等检测相关的知识,希望对你有一定的参考价值。
目录
lockup
系统(在一个或多个CPU核上)保持在长时间无反应状态。可检测类型有watchdog、soft lockup、hard lockup、 hung task、workqueue stall 等。
一、watchdog看门狗
检测系统的健康状态,有能力重启系统。
CONFIG_SOFT_ WATCHDOG=m
查看内核中看门狗的运行
#ps -e | grep watch
103 ? 00:00:00 watchdogd
二、soft /hard lockup
Kernel hacking | Debug Oops, Lockups and Hangs
看门狗的配置
# sysctl -a | grep watchdog
//0:关闭NMI看门狗和硬件lockup检测
kernel.nmi_watchdog = 0
//开启软件lockup检测
kernel.soft_watchdog = 1
//1 开启两者(软/硬)
kernel.watchdog = 1
//
kernel.watchdog_cpumask = 0-127
//硬件lockup 超时,软件lockup 2*10
kernel.watchdog_thresh = 10
1、soft lockup
内核处于紧密的循环中,长时间不让其他任务得到调度
当检测到软锁定时
- panic (内核配置nmi_watchdog=1;kernel.hardlockup_panic sysctl=1;BOOTPARAM_ SOFTLOCKUP_PANIC=1)
- 发出大量的警告
测试程序 :自旋spin_(un)lock()
kernel_thread 线程中有如下循环,CPU密集型
spin_lock(&spinlock);
while (i < 10000000000)
i ++;
if (!(i%50000000))
PRINT_CTX();
spin_unlock(&spinlock);
检测输出
[ 312.261567] watchdog: BUG: soft lockup - CPU#1 stuck for 22s! [lkd/kt_stuck:589]
[ 354.256680] kthread_stuck:simple_kthread(): 001) [lkd/kt_stuck]:589 | .N.0 /* simple_kthread() */
[ 354.722453] kthread_stuck:simple_kthread(): 001) [lkd/kt_stuck]:589 | .N.0 /* simple_kthread() */
2、hard lockup
在内核模式下运行的CPU内核仍处于紧密循环状态,不允许其他硬件中断运行;
系统检测到硬锁时
- panic (内核配置nmi_watchdog=1;kernel.hardlockup_panic sysctl=1;BOOTPARAM_ SOFTLOCKUP_PANIC=1)
- 发出大量的警告
内核配置
1、硬锁定只能由NMI,在本机x86_64上检测到;
2、必须启用NMI和NMI看门狗 nmi_ watchdog=1
3、CONFIG_RCU_CPU_STALL_TIMEOUT 值的范围 (3~300)在此时间内一定能检测到
4、CONFIG_RCU_STALL_COMMON=y
测试程序 自旋转IRQs、禁止抢占 spin_(un)lock_irq()
kernel_thread 线程中有如下循环,CPU密集型
spin_lock_irq(&spinlock);
while (i < 10000000000)
i ++;
if (!(i%50000000))
PRINT_CTX();
spin_unlock_irq(&spinlock);
检测输出
[ 4557.452812] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[ 4557.454426] rcu: 1-...0: (1 ticks this GP) idle=43e/1/0x4000000000000000 softirq=6242/6242 fqs=2599
[ 4557.455684] rcu: (detected by 2, t=5252 jiffies, g=13033, q=119)
[ 4557.457412] Task dump for CPU 1:
[ 4557.458131] lkd/kt_stuck R running task 0 793 2 0x0000002a
[ 4557.459379] Call trace:
[ 4557.460526] __switch_to+0xd0c/0xd44
[ 4557.461157] logbuf_lock+0x0/0x4
[ 4557.464316] kthread_stuck:simple_kthread(): 001) [lkd/kt_stuck]:793 | dN.0 /* simple_kthread() */
三、kernel's hung task
内核设置
Kernel hacking | Debug Oops, Lockups and Hangs | Detect Hung Tasks
配置见图二
参数解析
# sudo sysctl -a|grep hung_task
//如果设置1 则内核给所有核发送NMI中断,触发堆栈追溯
kernel.hung_task_all_cpu_backtrace = 0
//检测任务数的上线
kernel.hung_task_check_count = 4194304
//0 意味着挂起任务的值是kernel.hung_task_timeout_secs
kernel.hung_task_check_interval_secs = 0
//1:kernel panix 0:任务维持挂起状态
kernel.hung_task_panic = 0
//设置0 则禁止检测
kernel.hung_task_timeout_secs = 120
//报告的最大经过数
kernel.hung_task_warnings = 10
四、workqueue stall
内核设置
Kernel hacking | Debug Oops, Lockups and Hangs | Detect Workqueue Stalls
配置见图二
参数解析
检测时间workqueue.watchdog_thresh 默认30秒,设置0 禁止检测
测试例子:在workqueue回调函数中,添加CPU密集型函数
static void work_func(struct work_struct *work)
struct st_ctx *priv = container_of(work, struct st_ctx, work);
u64 i = 0;
PRINT_CTX();
//CPU密集型执行
while (1)
i += 3;
static int __init workq_simple_init(void)
ctx.data = INITIAL_VALUE;
//初始化workqueue
INIT_WORK(&ctx.work, work_func);
return 0;
测试输出
[ 580.742603] BUG: workqueue lockup - pool cpus=1 node=0 flags=0x0 nice=0 stuck for 73s!
[ 529.474102] rcu: INFO: rcu_sched self-detected stall on CPU
[ 529.474499] rcu: 1-....: (20464 ticks this GP) idle=fc6/1/0x4000000000000002 softirq=4407/4408 fqs=9074
参考内核
https://course.0voice.com/v1/course/intro?courseId=2&agentId=0
以上是关于linux内核中watchdoglockupstallhung等检测的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核编译 Linux 内核 ⑤ ( 查看 .config 编译配置文件 | 正式编译内核 )
Linux 内核Linux 操作系统结构 ( Linux 内核在操作系统中的层级 | Linux 内核子系统及关系 | 进程调度 | 内存管理 | 虚拟文件系统 | 网络管理 | 进程间通信 )