首页 > 技术知识 > 正文

1. 前言

这里总结几种内核异常时,常用的几种调试方法

2. Watchdog softlockup

linux-3.4\Documentationlockup-watchdogs.txt

(1) Linux3.4 Watchdog softlockup配置

Munuconfig配置 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 检测到softlockup后不触发内核panic;配置1会触发内核panic

Cmdline传参 softlockup_panic=1 : 检测到后系统触发panic softlockup_panic=0 : 检测到softllockup后系统不触发panic nosoftlockup : 关闭watchdog检测 nowatchdog : 关闭watchdog检测

(2)内核调试节点

/proc/sys/kernel/watchdog echo “0” :关闭watchdog检测功能;echo “1”:使能watchdog检测功能

/proc/sys/kernel/nmi_watchdog echo “0” :关闭hardlockup检测功能;echo “1”:使能hardlockup检测功能

/proc/sys/kernel/watchdog_thresh echo “N” :更改watchdog

/proc/sys/kernel/softlockup_panic echo “0” : 检测到softllockup后系统不触发panic

(3)原理

每个cpu 的per_cpu独立内存区都创建了以下变量: watchdog_touch_ts : 看门狗定时器触发后当前的时间戳 softlockup_watchdog :softlockup检测线程task_struct结构体指针 watchdog_hrtimer :watchdog 定时器 softlockup_touch_sync :softlock线程更新标志 soft_watchdog_warn: softlockup检测警告标志

如果系统运行的平台支持cpu hotplug功能,那么当cpu从off状态唤被调度到online状态的过程中,watchdog模块会响应cpu_chain发送的不同notifier消息,为cpu创建watchdog_hrtimer定时器和softlockup_watchdog 内核线程,该线程的调度器为SCHED_FIFO,线程名为watchdog/%d,%d与当前的cpuid一致,因此通过ps命令可以看到当前系统每一个cpu都会对应一个watchdog/0、watchdog/1、watchdog/2不等的内核线程绑定在对应的cpu上。

softlockup_watchdog 线程初始化过程: 1).将当前cpu的时间戳保存在per_cpu内存区的watchdog_touch_ts变量中; 2).启动watchdog_hrtimer定时器,间隔20s;

softlockup_watchdog 线程运行过程: 1).将当前cpu的时间戳保存在per_cpu内存区的watchdog_touch_ts变量中; 2).释放cpu调度执行权

watchdog_hrtimer定时器工作机制 1).定时器触发后,从per_cpu内存区读取watchdog_touch_ts变量值; 2).当前cpu的per_cpu内存区hrtimer_interrupts变量计数加1; 3).每隔hrtimer_interrupts计数增加3次时,检查一次其他cpu的 watchdog_nmi_touch变量是否为true; 如果为false,检查该cpu的hrtimer_interrupts变量和hrtimer_interrupts_saved变量是否相等,如果相等则认为该cpu有可能发生了hardlockup,定时器计数长时间没有更新; 如果不相等,则说明该cpu没有异常,将该cpu的hrtimer_interrupts变量和hrtimer_interrupts_saved

(4)问题场景分析 [ 322.239524] BUG: soft lockup – CPU#0 stuck for 22s! [swapper/0:0] [ 322.246258] Modules linked in: uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core sunxi_ir_rx algif_skcipher algif_rng algif_hash af_alg ss snd_usb_audio snd_usbmidi_lib snd_hwdep mali(O) fivm nand(O) [ 322.266994] [ 322.268645] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 3.10.65 #7 [ 322.276326] task: ffffffc000b60850 ti: ffffffc000b50000 task.ti: ffffffc000b50000 [ 322.284592] PC is at __do_softirq+0xbc/0x29c [ 322.289305] LR is at __do_softirq+0xa8/0x29c [ 322.294014] pc : [<ffffffc0000a0adc>] lr : [<ffffffc0000a0ac8>] pstate: 80000145 [ 322.302168] sp : ffffffc000b57c30

BUG: soft lockup 出现问题,一般有两种可能性:

1). CPU#X上出现大量的中断,不断的抢占内核进程调度导致。 例如某问题场景下内核驱动模块打印大量的出错日志,比如display 或mali fence timeout大量出错日志; 例如某问题场景下平台某硬件模块出现异常,不断触发中断,卡死Cpu;比如dvb测试ts读写时,tsc模块出现异常,中断20000次/S;

2).CPU#X上R状态进程长时间处于TASK_RUNNING状态抢占CPU而不发生调度切换。 例如某问题场景下内核态进程在关闭内核抢占后,陷入死循环;

3). CPU#X上S状态/D状态进程关闭内核抢占后发生睡眠 例如某问题场景下mutext锁等待睡眠; 例如某问题场景下等待pagecache write-back阻塞太久; 例如某问题场景下平台emmc存储出现IO异常,内核态进程在关闭内核抢占后,等待write-back阻塞超时; preempt_disable(); …睡眠/condition等待超时; preempt_enable();

分析方法:

1). 锁定所有的Cpu online 如果系统只有一个Cpu online并且发生了soft lockup,此时无法进行debug调试,锁定所有的Cpu online后,可以通过其他在线Cpu进行分析调试;例如sunxi平台锁定Cpu方法: echo N > /sys/kernel/autohotplug/lock { N:max cpus }

2). 动态修改watchdog soft lockup时间或者关闭watchdog检测 echo 50 > /proc/sys/kernel/watchdog_thresh { 调大soft lockup检测周期 } echo 0 > /proc/sys/kernel/watchdog { 关闭watchdog }

3). 周期性检查系统中断是否发生异常 检查系统中断是否存在异常 while true;do cat /proc/interrupts; sleep 1; done”

或者通过trace跟踪irq时间 echo 1 > /sys/kernel/debug/tracing/tracing_enabled echo 1 > /sys/kernel/debug/tracing/tracing_on echo > /sys/kernel/debug/tracing/trace echo 1 >/sys/kernel/debug/tracing/events/irq/enable cat /sys/kernel/debug/tracing/trace_pipe或cat /sys/kernel/debug/tracing/trace_pipe > /mnt/trace.log

4). 检查进程关闭抢占事件 内核menuconfig确认打开内核preempt trace跟踪功能 CONFIG_PREEMPT_TRACER=y 通过trace跟踪preemptoff事件,找到关闭抢占的代码点 echo 0 > /sys/kernel/debug/tracing/options/function-trace echo preemptoff > /sys/kernel/debug/tracing/current_tracer echo 1 > /sys/kernel/debug/tracing/tracing_on echo 0 > /sys/kernel/debug/tracing/tracing_max_latency cat /sys/kernel/debug/tracing/trace_pipe或cat /sys/kernel/debug/tracing/trace_pipe > /mnt/trace.log

3.Watchdog hardlockup

Watchdog hardlockup配置 Munuconfig配置 CONFIG_HARDLOCKUP_DETECTOR=y

使能hardlockup检测功能 CONFIG_HARDLOCKUP_DETECTOR_NMI=n

需要平台IC硬件PMU模块支持,如果硬件不支持,关闭该项配置 CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y

使能多Cpu hardlockup检测功能 CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 检测到 hardlockup后不触发内核panic;配置1会触发内核panic

Cmdline传参 nmi_watchdog=panic : hardlockup后触发内核panic nmi_watchdog=nopanic : hardlockup后不触发内核panic nmi_watchdog=0 : 关闭watchdog检测

4. Hung task detected

Linux3.4 Hung task配置 Munuconfig配置 CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120

Cmdline传参 hung_task_panic=1 : 检测进程出现长时间block状态后触发panic hung_task_panic=0 : 检测进程出现长时间block状态后不处罚panic

内核调试节点 /proc/sys/kernel/hung_task_check_count /proc/sys/kernel/hung_task_panic /proc/sys/kernel/hung_task_timeout_secs /proc/sys/kernel/ hung_task_warnings

猜你喜欢