Linux内核中简单的AB-BA死锁案例

描述

简单的AB-BA死锁案例

下面举一个简单的AB-BA死锁的例子:

#include < linux/module.h >
#include < linux/init.h >
#include < linux/kernel.h >

static DEFINE_SPINLOCK(hack_spinA);
static DEFINE_SPINLOCK(hack_spinB);

void hack_spinAB(void)
{
    printk("hack_lockdep:A- >Bn");
    spin_lock(&hack_spinA);
    spin_lock(&hack_spinB);
}

void hack_spinBA(void)
{
    printk("hack_lockdep:B- >An");
    spin_lock(&hack_spinB);
}

static int __init lockdep_test_init(void)
{
    printk("figo:my lockdep module initn");
    
    hack_spinAB();
    hack_spinBA();
 
    return 0;
}

static void __exit lockdep_test_exit(void)
{
  printk("goodbyen");
}

module_init(lockdep_test_init);
module_exit(lockdep_test_exit);
MODULE_LICENSE("GPL");

上述代码初始化了两个自旋锁,其中hack_spinAB()函数分别申请了hack_spinA锁和hack_spinB锁,hack_spinBA()函数要申请hack_spinB锁。因为刚才锁hack_spinB已经被成功获取且还没有释放,所以它会一直等待,而且它也被锁在hack_spinA的临界区里。

现象:

[root@imx6ull:~]# insmod lockdep_test.ko 
[  437.981262] figo:my lockdep module init
[  437.985145] hack_lockdep:A- >B
[  437.989054] hack_lockdep:B- >A
[  437.992304] 
[  437.993819] =============================================
[  437.999229] [ INFO: possible recursive locking detected ]
[  438.004641] 4.9.88 #2 Tainted: G           O   
[  438.009180] ---------------------------------------------
[  438.014589] insmod/367 is trying to acquire lock:
[  438.019303]  (hack_spinB){+.+...}, at: [< 7f00a030 >] lockdep_test_init+0x30/0x3c [lockdep_test]

[  438.028006] but task is already holding lock:
[  438.032547]  (hack_spinB){+.+...}, at: [< 7f008038 >] hack_spinAB+0x38/0x3c [lockdep_test]

[  438.040715] other info that might help us debug this:
[  438.045950]  Possible unsafe locking scenario:
[  438.045950] 
[  438.051883]        CPU0
[  438.054337]        ----
[  438.056790]   lock(hack_spinB);
[  438.059975]   lock(hack_spinB);
[  438.063160] 
[  438.063160]  *** DEADLOCK ***
[  438.063160] 
[  438.069094]  May be due to missing lock nesting notation
[  438.069094] 
[  438.075896] 2 locks held by insmod/367:
[  438.079740]  #0:  (hack_spinA){+.+...}, at: [< 7f008030 >] hack_spinAB+0x30/0x3c [lockdep_test]
[  438.088358]  #1:  (hack_spinB){+.+...}, at: [< 7f008038 >] hack_spinAB+0x38/0x3c [lockdep_test]
[  438.096977] 
[  438.096977] stack backtrace:
[  438.101352] CPU: 0 PID: 367 Comm: insmod Tainted: G           O    4.9.88 #2
[  438.108410] Hardware name: Freescale i.MX6 UltraLite (Device Tree)
[  438.114628] [< 801136cc >] (unwind_backtrace) from [< 8010e78c >] (show_stack+0x20/0x24)
[  438.122396] [< 8010e78c >] (show_stack) from [< 804ccc34 >] (dump_stack+0xa0/0xcc)
[  438.129646] [< 804ccc34 >] (dump_stack) from [< 8018f020 >] (__lock_acquire+0x8bc/0x1d4c)
[  438.137502] [< 8018f020 >] (__lock_acquire) from [< 80190b78 >] (lock_acquire+0xf4/0x2f8)
[  438.145358] [< 80190b78 >] (lock_acquire) from [< 80c94a0c >] (_raw_spin_lock+0x4c/0x84)
[  438.153129] [< 80c94a0c >] (_raw_spin_lock) from [< 7f00a030 >] (lockdep_test_init+0x30/0x3c [lockdep_test])
[  438.162638] [< 7f00a030 >] (lockdep_test_init [lockdep_test]) from [< 80102004 >] (do_one_initcall+0x54/0x184)
[  438.172315] [< 80102004 >] (do_one_initcall) from [< 80229624 >] (do_init_module+0x74/0x1f8)
[  438.180431] [< 80229624 >] (do_init_module) from [< 801dac54 >] (load_module+0x201c/0x279c)
[  438.188461] [< 801dac54 >] (load_module) from [< 801db648 >] (SyS_finit_module+0xc4/0xfc)
[  438.196317] [< 801db648 >] (SyS_finit_module) from [< 80109680 >] (ret_fast_syscall+0x0/0x1c)

提示信息显示:尝试获取hack_spinB锁,但是该锁已经在函数hack_spinAB中被锁定

Linux

lockdep已经很清晰地显示了死锁发生的路径和发生时函数调用的栈信息,根据这些信息可以很快速地定位问题和解决问题。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分