Linux死锁调试之softlockup

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 : []    lr : []    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

你可能感兴趣的:(IMX6_Android4.4)