如何解释这个警告?信息:检测到可能的循环锁定依赖性

时间:2014-05-22 00:05:14

标签: linux-kernel linux-device-driver

我从暂停状态恢复后发现此信息/警告信息 INFO:检测到可能的循环锁定依赖性

有人可以告诉我如何阅读和解释信息消息吗?并且,任何建议如何感谢任何帮助。这里的初学者...... :)

[  131.399069] Restarting tasks ... done.
[  131.409640] PM: suspend exit 1970-01-13 21:48:39.838845730 UTC
[  131.449011] ------------[ cut here ]------------
[  131.449759] 
[  131.449768] ======================================================
[  131.449777] [ INFO: possible circular locking dependency detected ]
[  131.449789] 3.10.37+ #1 Not tainted
[  131.449797] -------------------------------------------------------
[  131.449807] swapper/2/0 is trying to acquire lock:
[  131.449859]  (&port_lock_key){-.-...}, at: [<c036a6dc>]     serial8250_console_write+0x108/0x134
[  131.449866] 
[  131.449866] but task is already holding lock:
[  131.449905]  (&(&pool->lock)->rlock){-.-...}, at: [<c004b1bc>] __queue_work+0x16c/0x500
[  131.449913] 
[  131.449913] which lock already depends on the new lock.
[  131.449920] the existing dependency chain (in reverse order) is:
[  131.449951] 
[  131.449951] -> #2 (&(&pool->lock)->rlock){-.-...}:
[  131.449975]        [<c0099c08>] validate_chain.isra.33+0xe60/0x12b4
[  131.449993]        [<c009c944>] __lock_acquire+0x3f4/0xc28
[  131.450012]        [<c009d8a0>] lock_acquire+0xbc/0x254
[  131.450031]        [<c08973d4>] _raw_spin_lock+0x4c/0x5c
[  131.450049]        [<c004b1bc>] __queue_work+0x16c/0x500
[  131.450067]        [<c004b5d0>] queue_work_on+0x80/0x84
[  131.450087]        [<c03c062c>] rpm_idle+0xe4/0x41c
[  131.450105]        [<c03c09e4>] __pm_runtime_idle+0x80/0xb4
[  131.450124]        [<c03b49f4>] driver_probe_device+0x114/0x388
[  131.450142]        [<c03b4d60>] __driver_attach+0xa4/0xa8
[  131.450160]        [<c03b28e4>] bus_for_each_dev+0x70/0xa4
[  131.450177]        [<c03b43a4>] driver_attach+0x2c/0x30
[  131.450194]        [<c03b3f38>] bus_add_driver+0x1f0/0x294
[  131.450212]        [<c03b5440>] driver_register+0x88/0x150
[  131.450230]        [<c03b68d8>] platform_driver_register+0x60/0x68
[  131.450252]        [<c0c5ce3c>] b_phy_init+0x24/0x28
[  131.450271]        [<c00087d4>] do_one_initcall+0xe8/0x19c
[  131.450291]        [<c0c2ac84>] kernel_init_freeable+0x148/0x1e8
[  131.450312]        [<c08812b8>] kernel_init+0x20/0x170
[  131.450331]        [<c000eda8>] ret_from_fork+0x14/0x20
[  131.450362] 
[  131.450362] -> #1 (&(&dev->power.lock)->rlock){-.-...}:
[  131.450382]        [<c0099c08>] validate_chain.isra.33+0xe60/0x12b4
[  131.450400]        [<c009c944>] __lock_acquire+0x3f4/0xc28
[  131.450418]        [<c009d8a0>] lock_acquire+0xbc/0x254
[  131.450436]        [<c0897558>] _raw_spin_lock_irqsave+0x58/0x6c
[  131.450454]        [<c03c128c>] __pm_runtime_resume+0x60/0x9c
[  131.450474]        [<c036d060>] b16550_serial_out+0x30/0x6c
[  131.450492]        [<c0369b50>] serial8250_set_mctrl+0x6c/0x70
[  131.450510]        [<c0367400>] uart_add_one_port+0x300/0x418
[  131.450528]        [<c036af38>] serial8250_register_8250_port+0x244/0x300
[  131.450546]        [<c036d538>] dw8250_probe+0x240/0x5ac
[  131.450565]        [<c03b61ac>] platform_drv_probe+0x24/0x28
[  131.450582]        [<c03b4a28>] driver_probe_device+0x148/0x388
[  131.450600]        [<c03b4d60>] __driver_attach+0xa4/0xa8
[  131.450617]        [<c03b28e4>] bus_for_each_dev+0x70/0xa4
[  131.450635]        [<c03b43a4>] driver_attach+0x2c/0x30
[  131.450652]        [<c03b3f38>] bus_add_driver+0x1f0/0x294 
[  131.450669]        [<c03b5440>] driver_register+0x88/0x150
[  131.450688]        [<c03b68d8>] platform_driver_register+0x60/0x68
[  131.450708]        [<c0c57f98>] dw8250_platform_driver_init+0x18/0x1c
[  131.450726]        [<c00087d4>] do_one_initcall+0xe8/0x19c
[  131.450744]        [<c0c2ac84>] kernel_init_freeable+0x148/0x1e8
[  131.450763]        [<c08812b8>] kernel_init+0x20/0x170
[  131.450781]        [<c000eda8>] ret_from_fork+0x14/0x20
[  131.450812] 
[  131.450812] -> #0 (&port_lock_key){-.-...}:
[  131.450831]        [<c0887d90>] print_circular_bug+0x7c/0x310
[  131.450850]        [<c0099eb0>] validate_chain.isra.33+0x1108/0x12b4
[  131.450869]        [<c009c944>] __lock_acquire+0x3f4/0xc28
[  131.450887]        [<c009d8a0>] lock_acquire+0xbc/0x254
[  131.450904]        [<c08973d4>] _raw_spin_lock+0x4c/0x5c
[  131.450923]        [<c036a6dc>] serial8250_console_write+0x108/0x134
[  131.450943]        [<c002a0c8>] call_console_drivers.constprop.16+0x100/0x23c
[  131.450960]        [<c002a8e8>] console_unlock+0x41c/0x490
[  131.450977]        [<c002ab70>] vprintk_emit+0x214/0x604
[  131.450995]        [<c0886fc0>] printk+0x44/0x4c
[  131.451016]        [<c002845c>] warn_slowpath_common+0x34/0x7c
[  131.451034]        [<c0028560>] warn_slowpath_null+0x2c/0x34
[  131.451052]        [<c004b03c>] insert_work+0xa8/0xbc
[  131.451070]        [<c004b1a4>] __queue_work+0x154/0x500
[  131.451089]        [<c004b5fc>] delayed_work_timer_fn+0x28/0x2c
[  131.451107]        [<c003a414>] call_timer_fn+0x90/0x3a0
[  131.451124]        [<c003abf4>] run_timer_softirq+0x154/0x380
[  131.451144]        [<c0031fa4>] __do_softirq+0x170/0x4ec
[  131.451161]        [<c0032410>] do_softirq+0x7c/0x80
[  131.451178]        [<c0032774>] irq_exit+0xbc/0xf0
[  131.451196]        [<c00152e4>] handle_IPI+0xb4/0x488
[  131.451213]        [<c0008670>] gic_handle_irq+0x68/0x6c
[  131.451231]        [<c0898304>] __irq_svc+0x44/0x78
[  131.451253]        [<c05961b0>] bl_enter_powerdown+0x90/0xf0
[  131.451271]        [<c05941ec>] cpuidle_enter_state+0x4c/0x104
[  131.451289]        [<c0594394>] cpuidle_idle_call+0xf0/0x478
[  131.451307]        [<c000fc6c>] arch_cpu_idle+0x18/0x4c
[  131.451327]        [<c008a38c>] cpu_startup_entry+0x158/0x454
[  131.451348]        [<c0882e08>] secondary_start_kernel+0x13c/0x148
[  131.451366]        [<500081ec>] 0x500081ec
 [  131.451374] 
[  131.451374] other info that might help us debug this:
[  131.451374] 
[  131.451419] Chain exists of:
[  131.451419]   &port_lock_key --> &(&dev->power.lock)->rlock --> &(&pool->lock)->rlock
[  131.451419] 
[  131.451426]  Possible unsafe locking scenario:
[  131.451426] 
[  131.451433]        CPU0                    CPU1
[  131.451440]        ----                    ----
[  131.451458]   lock(&(&pool->lock)->rlock);
[  131.451478]                                lock(&(&dev->power.lock)->rlock);
[  131.451497]                                lock(&(&pool->lock)->rlock);
[  131.451515]   lock(&port_lock_key);
[  131.451522] 
[  131.451522]  *** DEADLOCK ***
[  131.451522] 
[  131.451532] 3 locks held by swapper/2/0:
[  131.451575]  #0:  ((&(work)->timer)){..-...}, at: [<c003a384>] call_timer_fn+0x0/0x3a0
[  131.451618]  #1:  (&(&pool->lock)->rlock){-.-...}, at: [<c004b1bc>] __queue_work+0x16c/0x500
[  131.451660]  #2:  (console_lock){+.+.+.}, at: [<c002ab34>] vprintk_emit+0x1d8/0x604

[131.451667]

1 个答案:

答案 0 :(得分:1)

每当您获得新锁时,Lockdep会检查当前进程先前持有的锁列表,以警告任何死锁情况。

我怀疑这是在A-> B和B-> A订单中​​获取锁定导致死锁的情况。

在这种情况下,锁A是(&amp; pool-&gt; lock) - &gt; rlock, 和B锁定(&amp; dev-&gt; power.lock) - &gt; rlock。

您可以通过在lockdep_set_class()中设置相同的类来告诉Lockdep将两个不同的锁视为相同。在&amp;(&amp; dev-&gt; power.lock) - &gt; rlock)的调用跟踪中,在函数uart_add_one_port中,

lockdep_set_class(&uport->lock, &port_lock_key);

我们还可以看到在serial8250_console_write中获取的port-&gt; rlock也设置为同一个类。

 lockdep_set_class(&port->lock, &port_lock_key);

因此,Lockdep将port-&gt; lock和uport-&gt;锁定为同一个锁(B),并抱怨锁A和B的顺序相反。

解决方案是修改你的代码,以便始终以相同的顺序获取这两个锁。