Bn" ); spin_lock ( spin_lock (} void hack_spinBA ( void ) { printk ( "hack_lockdep:B- >An" ); spin_lock (} 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 (lockd" />
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

麦辣鸡腿堡 来源:嵌入式Linux充电站 作者:Vincent 2023-09-27 15:19 次阅读

简单的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中被锁定

图片

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

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

    关注

    3

    文章

    1362

    浏览量

    40219
  • Linux
    +关注

    关注

    87

    文章

    11221

    浏览量

    208882
  • 死锁
    +关注

    关注

    0

    文章

    25

    浏览量

    8064
收藏 人收藏

    评论

    相关推荐

    Linux内核container_of原理详解

    Linux内核中经常可见container_of的身影,它在实际驱动的编写也是广泛应用。
    发表于 07-14 15:19 300次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b><b class='flag-5'>中</b>container_of原理详解

    Linux内核地址映射模型与Linux内核高端内存详解

    Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当
    发表于 05-08 10:33 3439次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>地址映射模型与<b class='flag-5'>Linux</b><b class='flag-5'>内核</b>高端内存详解

    简单分析linux内核的结构体使用方法

    所谓linux驱动编程可以理解为linux内核的编程。既然在内核编程那就必须要符合内核的逻辑和各种规定好的框架。
    发表于 01-19 08:26

    Linux内核教程

    本章学习目标掌握LINUX内核版本的含义理解并掌握进程的概念掌握管道的概念及实现了解内核的数据结构了解LINUX内核的算法掌握
    发表于 04-10 16:59 0次下载

    linux处理机调度与死锁

    linux处理机调度与死锁 掌握处理机的三级调度 掌握作业调度及进程调度的概念 理解调度算法的评价准则 掌握并灵活运用常用的几种作业调度、
    发表于 04-28 14:59 0次下载

    Linux内核解读入门

    Linux内核解读入门关键词:Linux, 内核,源代码一.核心源程序的文件组织: 1. Linux核心源程序通常都安装在/usr/src/
    发表于 01-16 14:40 103次下载

    DIN死锁避免和死锁恢复

    DIN死锁避免和死锁恢复 由于存在占用资源者申请另一个资源的情形,在DIN由于拓扑结构本身存在环状路径,所以
    发表于 02-23 14:47 899次阅读
    DIN<b class='flag-5'>中</b>的<b class='flag-5'>死锁</b>避免和<b class='flag-5'>死锁</b>恢复

    Linux内核配置系统详解

    随着 Linux 操作系统的广泛应用,特别是 Linux 在嵌入式领域的发展,越来越多的人开始投身到 Linux 内核级的开发。面对日益庞
    发表于 11-01 15:45 4次下载

    用crash工具分析Linux内核死锁的一次实战分享

    内核死锁问题一般是读写锁(rw_semaphore)和互斥锁(mutex)引起的,本文主要讲如何通过ramdump+crash工具来分析这类死锁问题。
    的头像 发表于 03-17 09:27 1.6w次阅读
    用crash工具分析<b class='flag-5'>Linux</b><b class='flag-5'>内核</b><b class='flag-5'>死锁</b>的一次实战分享

    linux内核是什么_linux内核学习路线

    Linux内核是一个操作系统(OS)内核,本质上定义为类Unix。它用于不同的操作系统,主要是以不同的Linux发行版的形式。Linux
    发表于 09-16 15:49 2613次阅读

    linux内核参数设置_linux内核的功能有哪些

    本文主要阐述了linux内核参数设置及linux内核的功能。
    发表于 09-17 14:40 1362次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>内核</b>参数设置_<b class='flag-5'>linux</b><b class='flag-5'>内核</b>的功能有哪些

    linux内核的driver_register介绍

    linux内核注册驱动由driver_register()完成。它将驱动程序的信息添加到内核的驱动程序列表,使得内核能够在需要时与该驱动
    的头像 发表于 07-14 09:17 2659次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>内核</b><b class='flag-5'>中</b>的driver_register介绍

    Linux内核死锁lockdep功能

    的编程思路,也不可能避免会发生死锁。在Linux内核,常见的死锁有如下两种: 递归死锁:如在中
    的头像 发表于 09-27 15:13 673次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b><b class='flag-5'>死锁</b>lockdep功能

    Linux内核实际项目中的死锁

    实际项目中的死锁 下面的例子要复杂一些,这是从实际项目中抽取出来的死锁,更具有代表性。 # include # include # include # include # include
    的头像 发表于 09-27 15:24 729次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>实际项目中的<b class='flag-5'>死锁</b>

    使用 PREEMPT_RT 在 Ubuntu 构建实时 Linux 内核

    的实时内核补丁来完成。简介我们曾介绍过在Ubuntu22.04启用实时Linux内核有多简单,因为Canonical已将该
    的头像 发表于 04-12 08:36 2195次阅读
    使用 PREEMPT_RT 在 Ubuntu <b class='flag-5'>中</b>构建实时 <b class='flag-5'>Linux</b> <b class='flag-5'>内核</b>