您的位置:首页 > 运维架构 > Linux

Linux死锁调试之softlockup

2016-05-04 14:41 633 查看
Kernel branch: 3.0.35

概要:

softlockup 主要用于检测内核的进程调度是否正常,当发生softlockup时,内核不能被调度,

但是中断还是可以响应,而hrtimer属于中断的下半部,所以此情况下也可以响应。

原理:

系统在每个cpu上创建一个内核线程,当hrtimer定期执行的回调后会尝试唤醒此线程,如果线程有被正常调度而被唤醒,

它会更新时间变量watchdog_touch_ts,如果没有则不会更新。在hrtimer的回调函数中会判断watchdog_touch_ts和当前

时间差,如果超过给定值,那就证明内核调度失败,接着就打印异常log。

code流程大概:

lockup_detector_init ->

cpu_callback -> //action CPU_UP_PREPARE

watchdog_prepare_cpu -> //hrtimer对应function是watchdog_timer_fn

cpu_callback ->

watchdog_enable ->

kthread_create -> //为每个cpu创建名字叫watchdog/x的thread, x是cpu number,对应function为watchdog().

watchdog ->

sched_priority = MAX_RT_PRIO-1 //设置线程优先级成最高

__touch_watchdog //初始化watchdog_touch_ts为当前时间

hrtimer_start //启动timer,时间周期从get_sample_period(),由watchdog_thresh决定,

除5是在触发hardlockup之前给hrtimer5次机会触发,后面文章会提到hardlockup。

__touch_watchdog //重新更新时间戳。

schedule //睡眠等待设置时间后hrtimer触发

watchdog_timer_fn -> //hrtimer被触发

wake_up_process //唤醒前面休眠的进程

hrtimer_forward_now //重新设置hrtimer

is_softlockup //如果计算时间差超过了最大时间,证明没有进程调度了、

print_modules //打印信息。

dump_stack //打印堆栈信息。

另一方面,watchdog线程会被唤醒,然后执行__touch_watchdog 会重新更新watchdog_touch_ts。

测试例子:

在某个线程里添加如下语句:

preempt_disable();

while(1);

然后过会就会打印如下log:

[ 28.548865] BUG: soft lockup - CPU#1 stuck for 22s! [us kthread:1106]

[ 28.555378] Modules linked in:

[ 28.558566]

[ 28.560173] Pid: 1106, comm: us kthread

[ 28.564951] CPU: 1 Not tainted (3.0.35-00007-g60f7071-dirty #153)

[ 28.571528] PC is at ks103_ultrasonic_thread+0x18/0x1c

[ 28.576750] LR is at kthread+0x80/0x88

[ 28.580566] pc : [<c0357084>] lr : [<c00ab1c8>] psr: 60000013

[ 28.580571] sp : d441bfc8 ip : c08ba7d0 fp : 00000000

[ 28.592249] r10: 00000000 r9 : 00000000 r8 : 00000000

[ 28.597599] r7 : 00000013 r6 : c035706c r5 : 00000000 r4 : d402fe94

[ 28.604202] r3 : d441a000 r2 : 00000001 r1 : d4044560 r0 : 00000000

[ 28.610854] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel

[ 28.618287] Control: 10c53c7d Table: 1000404a DAC: 00000015

[ 28.624095]

[ 28.624098] PC: 0xc0357004:

[ 28.628502] 7004 ebffffaa e58d0004 eaffffd7 e59f1034 e59f0040 eb0c4e8a e3a00003 ebffffa3

[ 28.637449] 7024 e59f2034 e59f101c e1a03000 e59f002c e3530000 e58d3004 01a02000 e59f0020

[ 28.646433] 7044 eb0c4e7f eaffffc8 c06a73cc c07e9fdc c07e9ffc c07ea018 c07ea038 c07e9fc4

[ 28.655417] 7064 c07e9fd4 c07ea058 e1a0200d e3c23d7f e3c3303f e5932004 e2822001 e5832004

[ 28.664414] 7084 eafffffe e92d4008 e3a00000 e59f1008 ebfe1658 e3a00000 e8bd8008 c0972128

[ 28.673356] 70a4 e92d4008 e3a00000 e59f100c ebfe2136 e3500000 13e0000f e8bd8008 c0972128

[ 28.682303] 70c4 e3a03001 e3443004 e1510003 e92d4010 e1a04002 0a000007 e3a03002 e3443004

[ 28.691325] 70e4 e1510003 0a000012 e59f00b4 eb0c4e54 e3e00015 e8bd8010 e59f00a8 eb0c6694

参考:
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=14528823&id=4215888
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: