如何监视和记录哪些模块在 linux 内核中持有锁?

Posted

技术标签:

【中文标题】如何监视和记录哪些模块在 linux 内核中持有锁?【英文标题】:How to monitor and log what module holds locks in linux kernel? 【发布时间】:2013-01-02 23:20:43 【问题描述】:

是否可以监控Linux内核中哪个模块持有锁?

我的意思是我怎么知道谁锁定了spin_locksemaphoremutex 等。

对于用户空间:

Linux: How can I find the thread which holds a particular lock?

【问题讨论】:

【参考方案1】:

通常,当检测到软锁定时,内核将打印当前堆栈跟踪。例如:

INFO: task bdi-default:19 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
bdi-default   D 0000000000000001     0    19      2 0x00000000
ffff88013cd7fc60 0000000000000046 ffff88013cd7fc10 ffffffff810096f0
ffff88013806f4f8 0000000000000000 0000000000d7fc20 ffff880028313b40
ffff88013cd7b0b8 ffff88013cd7ffd8 000000000000f4e8 ffff88013cd7b0b8
Call Trace:
[<ffffffff810096f0>] ? __switch_to+0xd0/0x320
[<ffffffff814eca40>] ? thread_return+0x4e/0x77e
[<ffffffff814ed8c5>] schedule_timeout+0x215/0x2e0
[<ffffffff814ed543>] wait_for_common+0x123/0x180
[<ffffffff8105fa50>] ? default_wake_function+0x0/0x20
[<ffffffff814ed65d>] wait_for_completion+0x1d/0x20
[<ffffffff810909f9>] kthread_create+0x99/0x120
[<ffffffff81134d40>] ? bdi_start_fn+0x0/0x100
[<ffffffff8100bc0e>] ? apic_timer_interrupt+0xe/0x20
[<ffffffff81134bb7>] bdi_forker_task+0x187/0x310
[<ffffffff81134a30>] ? bdi_forker_task+0x0/0x310
[<ffffffff81090886>] kthread+0x96/0xa0
[<ffffffff8100c14a>] child_rip+0xa/0x20
[<ffffffff810907f0>] ? kthread+0x0/0xa0
[<ffffffff8100c140>] ? child_rip+0x0/0x20

如果调用跟踪没有提供足够的信息,请尝试在内核中启用锁定检测(需要重新编译内核)

 make menuconfig
         \--> Kernel Hacking
           \--> Detect Soft Lockups

然后调用跟踪将显示更多信息,以:

BUG: soft lockup detected on CPU#0!

要查看调用跟踪,检查 dmesg,或者您最好使用串行控制台来捕获所有内核日志(在某些情况下,由于软锁定,内核可能会挂起而不会将所有日志吐出到文件中,但是串行控制 - 或其他替代方案,如 netconsole 等 - 您可以捕获日志)。

【讨论】:

以上是关于如何监视和记录哪些模块在 linux 内核中持有锁?的主要内容,如果未能解决你的问题,请参考以下文章

在持有pthread锁时可以抢占一个线程吗?

透过 Linux 内核看无锁编程

linux互斥锁简介(内核态)

Linux 线程同步都有哪些方法?

内核模块编译过程摘要记录

Linux 同步方法剖析--内核原子,自旋锁和互斥锁