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
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核中簡單的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()函數(shù)分別申請了hack_spinA鎖和hack_spinB鎖,hack_spinBA()函數(shù)要申請hack_spinB鎖。因為剛才鎖hack_spinB已經(jīng)被成功獲取且還沒有釋放,所以它會一直等待,而且它也被鎖在hack_spinA的臨界區(qū)里。

現(xiàn)象:

[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鎖,但是該鎖已經(jīng)在函數(shù)hack_spinAB中被鎖定

圖片

lockdep已經(jīng)很清晰地顯示了死鎖發(fā)生的路徑和發(fā)生時函數(shù)調(diào)用的棧信息,根據(jù)這些信息可以很快速地定位問題和解決問題。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1360

    瀏覽量

    40185
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11210

    瀏覽量

    208721
  • 死鎖
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    8059
收藏 人收藏

    評論

    相關(guān)推薦

    Linux內(nèi)核container_of原理詳解

    Linux內(nèi)核中經(jīng)??梢奵ontainer_of的身影,它在實際驅(qū)動的編寫也是廣泛應(yīng)用。
    發(fā)表于 07-14 15:19 ?295次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>中</b>container_of原理詳解

    Linux內(nèi)核地址映射模型與Linux內(nèi)核高端內(nèi)存詳解

    Linux 操作系統(tǒng)和驅(qū)動程序運行在內(nèi)核空間,應(yīng)用程序運行在用戶空間,兩者不能簡單地使用指針傳遞數(shù)據(jù),因為Linux使用的虛擬內(nèi)存機(jī)制,用戶空間的數(shù)據(jù)可能被換出,當(dāng)
    發(fā)表于 05-08 10:33 ?3436次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>地址映射模型與<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>高端內(nèi)存詳解

    簡單分析linux內(nèi)核的結(jié)構(gòu)體使用方法

    所謂linux驅(qū)動編程可以理解為linux內(nèi)核的編程。既然在內(nèi)核編程那就必須要符合內(nèi)核的邏輯和各種規(guī)定好的框架。
    發(fā)表于 01-19 08:26

    Linux內(nèi)核教程

    本章學(xué)習(xí)目標(biāo)掌握LINUX內(nèi)核版本的含義理解并掌握進(jìn)程的概念掌握管道的概念及實現(xiàn)了解內(nèi)核的數(shù)據(jù)結(jié)構(gòu)了解LINUX內(nèi)核的算法掌握
    發(fā)表于 04-10 16:59 ?0次下載

    linux處理機(jī)調(diào)度與死鎖

    linux處理機(jī)調(diào)度與死鎖 掌握處理機(jī)的三級調(diào)度 掌握作業(yè)調(diào)度及進(jìn)程調(diào)度的概念 理解調(diào)度算法的評價準(zhǔn)則 掌握并靈活運用常用的幾種作業(yè)調(diào)度、
    發(fā)表于 04-28 14:59 ?0次下載

    Linux內(nèi)核解讀入門

    Linux內(nèi)核解讀入門關(guān)鍵詞:Linux, 內(nèi)核,源代碼一.核心源程序的文件組織: 1. Linux核心源程序通常都安裝在/usr/src/
    發(fā)表于 01-16 14:40 ?103次下載

    DIN死鎖避免和死鎖恢復(fù)

    DIN死鎖避免和死鎖恢復(fù) 由于存在占用資源者申請另一個資源的情形,在DIN由于拓?fù)浣Y(jié)構(gòu)本身存在環(huán)狀路徑,所以
    發(fā)表于 02-23 14:47 ?896次閱讀
    DIN<b class='flag-5'>中</b>的<b class='flag-5'>死鎖</b>避免和<b class='flag-5'>死鎖</b>恢復(fù)

    Linux內(nèi)核配置系統(tǒng)詳解

    隨著 Linux 操作系統(tǒng)的廣泛應(yīng)用,特別是 Linux 在嵌入式領(lǐng)域的發(fā)展,越來越多的人開始投身到 Linux 內(nèi)核級的開發(fā)。面對日益龐
    發(fā)表于 11-01 15:45 ?4次下載

    用crash工具分析Linux內(nèi)核死鎖的一次實戰(zhàn)分享

    內(nèi)核死鎖問題一般是讀寫鎖(rw_semaphore)和互斥鎖(mutex)引起的,本文主要講如何通過ramdump+crash工具來分析這類死鎖問題。
    的頭像 發(fā)表于 03-17 09:27 ?1.5w次閱讀
    用crash工具分析<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>死鎖</b>的一次實戰(zhàn)分享

    linux內(nèi)核是什么_linux內(nèi)核學(xué)習(xí)路線

    Linux內(nèi)核是一個操作系統(tǒng)(OS)內(nèi)核,本質(zhì)上定義為類Unix。它用于不同的操作系統(tǒng),主要是以不同的Linux發(fā)行版的形式。Linux
    發(fā)表于 09-16 15:49 ?2604次閱讀

    linux內(nèi)核參數(shù)設(shè)置_linux內(nèi)核的功能有哪些

    本文主要闡述了linux內(nèi)核參數(shù)設(shè)置及linux內(nèi)核的功能。
    發(fā)表于 09-17 14:40 ?1355次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>參數(shù)設(shè)置_<b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>的功能有哪些

    linux內(nèi)核的driver_register介紹

    linux內(nèi)核注冊驅(qū)動由driver_register()完成。它將驅(qū)動程序的信息添加到內(nèi)核的驅(qū)動程序列表,使得內(nèi)核能夠在需要時與該驅(qū)動
    的頭像 發(fā)表于 07-14 09:17 ?2603次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>中</b>的driver_register介紹

    Linux內(nèi)核死鎖lockdep功能

    的編程思路,也不可能避免會發(fā)生死鎖。在Linux內(nèi)核,常見的死鎖有如下兩種: 遞歸死鎖:如在中
    的頭像 發(fā)表于 09-27 15:13 ?663次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>死鎖</b>lockdep功能

    Linux內(nèi)核實際項目中的死鎖

    實際項目中的死鎖 下面的例子要復(fù)雜一些,這是從實際項目中抽取出來的死鎖,更具有代表性。 # include # include # include # include # include
    的頭像 發(fā)表于 09-27 15:24 ?717次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>實際項目中的<b class='flag-5'>死鎖</b>

    使用 PREEMPT_RT 在 Ubuntu 構(gòu)建實時 Linux 內(nèi)核

    的實時內(nèi)核補(bǔ)丁來完成。簡介我們曾介紹過在Ubuntu22.04啟用實時Linux內(nèi)核有多簡單,因為Canonical已將該
    的頭像 發(fā)表于 04-12 08:36 ?2093次閱讀
    使用 PREEMPT_RT 在 Ubuntu <b class='flag-5'>中</b>構(gòu)建實時 <b class='flag-5'>Linux</b> <b class='flag-5'>內(nèi)核</b>