【开发工具】【lockdep】Linux内核死锁检测工具(lockdep)的使用【转】
转自:https://blog.csdn.net/Ivan804638781/article/details/100740857
相关链接:
【开发日常】【死锁】写一个简单的死锁demo
【同步与并发】【死锁】什么是死锁?产生死锁的原因及必要条件?如何避免死锁?
【调试工具】【lockdep】Linux内核死锁检测工具(lockdep)的使用
问题描述
实际产品运行过程中,Linux系统僵死,屏幕无任何有效串口打印信息,网络中断、键盘鼠标没有任何响应。
这种故障现象,可能是因为Linux内核死锁导致。由于无任何有效打印信息,内核日志中也没有记录,就无法定位故障根因。
如何让Linux内核在僵死前打印相关信息,对问题定位尤为关键。其中一个有效手段是打开“Kernel Hacking”选项,然后重新编译内核。对于Linux(3.14.28)内核死锁有帮助的几个配置选项有:
Kernel hacking --->Debug Lockups and Hangs --->
[*] Detect Hard and Soft Lockups
[*] Panic (Reboot) On Soft Lockups
[*] Detect Hung Tasks
(120) Default timeout for hung task detection (in seconds)
[*] Panic (Reboot) On Hung Tasks
soft lockup 和 hard lockup?
soft lockup:抢占被长时间关闭而导致进程无法调度.
hard lockup : 中断被长时间关闭而导致更严重的问题.
后面会分析这种lockup的内核检测原理.
lockdep 死锁检测模块
介绍了最简单的 ABBA 死锁的形成,回到正题,回到 kernel, 里面有千千万万锁,错综复杂,也不可能要求所有开发人员熟悉 spin_lock, spin_lock_irq, spin_lock_irqsave, spin_lock_nested 的区别。所以,在锁死发生前,还是要做好预防胜于治疗,防患于未然的工作,尽量提前发现并且提前在开发阶段发现和解决这其中潜在的死锁风险,而不是等到最后真正出现死锁时给用户带来糟糕的体验。应运而生的就是 lockdep 死锁检测模块,在 2006 年已经引入内核(https://lwn.net/Articles/185666/)。
相关内核配置选项
CONFIG_DEBUG_RT_MUTEXES=y
检测rt mutex的死锁,并自动报告死锁现场信息。
CONFIG_DEBUG_SPINLOCK=y
检测spinlock的未初始化使用等问题。配合NMI watchdog使用,能发现spinlock死锁。
CONFIG_DEBUG_MUTEXES=y
检测并报告mutex错误
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
检测wait/wound类型mutex的slowpath测试。
CONFIG_DEBUG_LOCK_ALLOC=y
检测使用中的锁(spinlock/rwlock/mutex/rwsem)被释放,或者使用中的锁被重新初始化,或者在进程退出时持有锁。
CONFIG_PROVE_LOCKING=y
使内核能在死锁发生前报告死锁详细信息。参见/proc/lockdep_chains。
CONFIG_LOCKDEP=y
整个Lockdep的总开关。参见/proc/lockdep、/proc/lockdep_stats。
CONFIG_LOCK_STAT=y
记锁持有竞争区域的信息,包括等待时间、持有时间等等信息。参见/proc/lock_stat。
CONFIG_DEBUG_LOCKDEP=y
会对Lockdep的使用过程中进行更多的自我检测,会增加很多额外开销。
CONFIG_DEBUG_ATOMIC_SLEEP=y
在atomic section中睡眠可能造成很多不可预测的问题,这些atomic section包括spinlock持锁、rcu读操作、禁止内核抢占部分、中断处理中等等。
一、D状态死锁检测
所谓D状态死锁:进程长时间(系统默认配置120秒)处于TASK_UNINTERRUPTIBLE 睡眠状态,这种状态下进程不响应异步信号。如:进程与外设硬件的交互(如read),通常使用这种状态来保证进程与设备的交互过程不被打断,否则设备可能处于不可控的状态。
内核D状态死锁检测就是hung_task机制,主要代码就在kernel/hung_task.c文件。
具体实现原理:
1.创建Normal级别的khungtaskd内核线程,在死循环中每隔sysctl_hung_task_timeout_secs时间后check一下,用schedule_timeout定时(节约定时器浪费的CPU)。
2.调用do_each_thread,while_each_thread宏遍历所有的进程信息,如果有D状态进程,则检查最近切换次数和task计算是否一致,即最近是否有调度切换,如果一致,则没有切换,打印相关信息,并根据sysctl_hung_task_panic开关决定是否重启。
对应用户态控制的proc接口有:
/proc/sys/kernel/hung_task_timeout_secs,hung_task_panic等。
二、R状态死锁检测
所谓R状态死锁:进程长时间(系统默认配置60秒)处于TASK_RUNNING 状态垄断cpu而不发生切换,一般情况下是进程关抢占后长时候干活,有时候可能进程关抢占后处于死循环或者睡眠后,这样就造成系统异常。
补充:lockdep不是所谓的死锁。
内核R状态死锁检测机制就是lockdep机制,入口即是lockup_detector_init函数。
1.通过cpu_callback函数调用watchdog_enable,在每个CPU core上创建SCHED_FIFO级别的实时线程watchdog,其中使用了hrtimer定时器,控制检查周期。
2.hrtimer定时器调用watchdog_timer_fn进行清狗的时间检查,而线程则每次重置清狗时间,如果watchdog_timer_fn发现狗的重置时间已经和当前时间差出危险值,则根据开关进行panic处理。
对应用户态控制的proc接口有:
/proc/sys/kernel/watchdog_thresh,softlockup_panic等。
查看锁的相关信息
/proc/sys/kernel/lock_stat /* 置位则可以查看/proc/lock_stat统计信息,清除则关闭lockdep统计信息。 */
/proc/lock_stat /* 关于锁的使用统计信息 */
/proc/lockdep /* 存在依赖关系的锁 */
/proc/lockdep_stats /* 存在依赖关系锁的统计信息 */
/proc/lockdep_chains /* 依赖关系锁链表 */
/proc/locks /* */
/proc/sys/kernel/prove_locking
/proc/sys/kernel/max_lock_depth
/sys/kernel/debug/tracing/events/lock /* 内核提供了Tracepoint协助发现锁的使用问题 */
参考文章
https://blog.csdn.net/ccwzhu/article/details/81171092
死锁的形成
Linux 死锁检测模块 Lockdep 简介
————————————————
版权声明:本文为CSDN博主「Evan_ZGYF丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ivan804638781/article/details/100740857
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
2016-01-07 linux键盘input_event浅析【转】
2016-01-07 多点触摸与单点触摸接口主要区别【转】
2016-01-07 Linux 内核驱动--多点触摸接口【转】
2016-01-07 Linux触摸屏驱动测试程序范例【转】
2016-01-07 Linux内核触摸屏驱动--多点触摸 【转】
2016-01-07 Linux内核抢占实现机制分析【转】