linux驅動 自旋鎖

最近在內核頻繁使用了自旋鎖,自旋鎖如果使用不當,極易引起死鎖,在此總結一下。

自旋鎖是一個互斥設備,它只有兩個值:“鎖定”和“解鎖”。它通常實現為某個整數值中的某個位。希望獲得某個特定鎖得代碼測試相關的位。如果鎖可用,則“鎖定”被設置,而代碼繼續進入臨界區;相反,如果鎖被其他人獲得,則代碼進入忙循環(而不是休眠,這也是自旋鎖和一般鎖的區別)并重復檢查這個鎖,直到該鎖可用為止,這就是自旋的過程。“測試并設置位”的操作必須是原子的,這樣,即使多個線程在給定時間自旋,也只有一個線程可獲得該鎖。

自旋鎖最初是為了在多處理器系統(SMP)使用而設計的,但是只要考慮到并發問題,單處理器在運行可搶占內核時其行為就類似于SMP。因此,自旋鎖對于SMP和單處理器可搶占內核都適用。可以想象,當一個處理器處于自旋狀態時,它做不了任何有用的工作,因此自旋鎖對于單處理器不可搶占內核沒有意義,實際上,非搶占式的單處理器系統上自旋鎖被實現為空操作,不做任何事情。

自旋鎖有幾個重要的特性:1、被自旋鎖保護的臨界區代碼執行時不能進入休眠。2、被自旋鎖保護的臨界區代碼執行時是不能被被其他中斷中斷。3、被自旋鎖保護的臨界區代碼執行時,內核不能被搶占。從這幾個特性可以歸納出一個共性:被自旋鎖保護的臨界區代碼執行時,它不能因為任何原因放棄處理器

考慮上面第一種情況,想象你的內核代碼請求到一個自旋鎖并且在它的臨界區里做它的事情,在中間某處,你的代碼失去了處理器。或許它已調用了一個函數(copy_from_user,假設)使進程進入睡眠。也或許,內核搶占發威,一個更高優先級的進程將你的代碼推到了一邊。此時,正好某個別的線程想獲取同一個鎖,如果這個線程運行在和你的內核代碼不同的處理器上(幸運的情況),那么它可能要自旋等待一段時間(可能很長),當你的代碼從休眠中喚醒或者重新得到處理器并釋放鎖,它就能得到鎖。而最壞的情況是,那個想獲取鎖得線程剛好和你的代碼運行在同一個處理器上,這時它將一直持有CPU進行自旋操作,而你的代碼是永遠不可能有任何機會來獲得CPU釋放這個鎖了,這就是悲催的死鎖

考慮上面第二種情況,和上面第一種情況類似。假設我們的驅動程序正在運行,并且已經獲取了一個自旋鎖,這個鎖控制著對設備的訪問。在擁有這個鎖得時候,設備產生了一個中斷,它導致中斷處理例程被調用,而中斷處理例程在訪問設備之前,也要獲得這個鎖。當中斷處理例程和我們的驅動程序代碼在同一個處理器上運行時,由于中斷處理例程持有CPU不斷自旋,我們的代碼將得不到機會釋放鎖,這也將導致死鎖。

因此,如果我們有一個自旋鎖,它可以被運行在(硬件或軟件)中斷上下文中的代碼獲得,則必須使用某個禁用中斷的spin_lock形式的鎖來禁用本地中斷(注意,只是禁用本地CPU的中斷,不能禁用別的處理器的中斷),使用其他的鎖定函數遲早會導致系統死鎖(導致死鎖的時間可能不定,但是發生上述死鎖情況的概率肯定是有的,看處理器怎么調度了)。如果我們不會在硬中斷處理例程中訪問自旋鎖,但可能在軟中斷(例如,以tasklet的形式運行的代碼)中訪問,則應該使用spin_lock_bh,以便在安全避免死鎖的同時還能服務硬件中斷。

補充:

鎖定一個自旋鎖的函數有四個:

void spin_lock(spinlock_t *lock); ? ? ?

最基本得自旋鎖函數,它不失效本地中斷。

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

在獲得自旋鎖之前禁用硬中斷(只在本地處理器上),而先前的中斷狀態保存在flags中

void spin_lockirq(spinlock_t *lock);

在獲得自旋鎖之前禁用硬中斷(只在本地處理器上),不保存中斷狀態

void spin_lock_bh(spinlock_t *lock);

在獲得鎖前禁用軟中斷,保持硬中斷打開狀態


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457893.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457893.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457893.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

百度輸入法

[用戶界面]:界面美觀,有不同畫風的ui界面,適合不同消費群體的需求。 [記住用戶選擇]:會默認記住用戶以往的輸入習慣,只需輸入首拼音字母就會出現過去使用的高頻詞。 [短期刺激]:美化的用戶界面讓人眼前一新…

rs232讀取智能電表_三相電表怎么看度數 怎么計算總電量

現在的三相電表一般都是在屏幕上面直接看,屏幕上面是有文字提示顯示的,三相電表的總度數,上面的文字提醒一般是“正向有功總電量”,三相電表一般屏幕旁邊都會上翻鍵和下翻鍵,可以上下翻開電表里面的數據。如下圖所示&a…

android 學習隨筆十六(廣播 )

1、廣播接收者 BroadcastReceiver接收系統發出的廣播現實中的廣播:電臺為了傳達一些消息,而發送的廣播,通過廣播攜帶要傳達的消息,群眾只要買一個收音機,就可以收到廣播了 Android中的廣播:系統在運行過程中…

驅動面試題總結

1、字符型驅動設備你是怎么創建設備文件的,就是/dev/下面的設備文件,供上層應用程序打開使用的文件? 答:mknod命令結合設備的主設備號和次設備號,可創建一個設備文件。 評:這只是其中一種方式&#xff0…

python程序寫詩_將Python詩歌與D結合起來

在與docker一起使用poetry時,需要記住以下幾點。 安裝 安裝poetry的正式方法是通過:curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python 這種方式允許poetry及其依賴項與依賴項分離。但是,在我看來…

Azure運維系列 4:安裝和使用Azure PowerShell管理云

前面講到了很多的管理方式,包括Azure中國最近更新的預覽版管理門戶和Azure云助理,都是非常不錯的管理Azure的方式,今天我們再來介紹一種更加高效的管理方式Azure PowerShell。熟悉命令行的朋友都知道,Linux之所以那么好用是因為其…

[轉]char * 和字符數組

[轉]char * 和字符數組 原文地址:http://www.cnblogs.com/jeakon/archive/2012/05/27/2816809.html 代碼中的int * i就是我們關注的焦點。它是一個指向int指針。也就是說:i指向一個內存地址,從這個地址開始存儲了一個數據。int * i中的int標明…

設備模型1

作為開頭篇,我不想寫HELLLOWORLD驅動,甚至字符設備驅動的開發,這樣文章充斥在各大網站上的博客上,隨便搜搜,就可以找到幾百篇。這是最基本的東西,通過這些內容的學習,我們要掌握LINUX驅動的基本…

如何使用Android Studio把自己的Android library分享到jCenter和Maven Central

第一部分:在bintray上創建package首先,你需要在bintray上創建一個package。為此,你需要一個bintray賬號,并在網站上創建一個package。第一步:在bintray.com上注冊一個賬號。(注冊過程很簡單,自己…

python2編碼_Python2字符編碼

我們通常見到的字符串編碼主要是三種GB2312/GBK、Unicode、UTF-8。GB2312/GBK是多字節(multibytes)編碼的一種,屬于“ASCII的加強版”,與之平行的由Big5、ShiftJIS之類的編碼各自為政,所有這些用兩個字節表示漢字的多字節編碼標準統稱為ANSI編…

angularJs關于指令的一些冷門屬性

我們使用ng的時候,經常會使用到指令,大家所熟知的屬性我在這里就不介紹了,講講大家沒怎么留意的屬性 1.multiElement 這是指定指令作用區間的功能,最常用的就是ng-repeat-start和ng-repeat-end了。 2.priority 指令優先級&#xf…

設備模型2

前言 在上一篇中,我們大致描述了LINUX設備模型,我們先來總結一下三要素的關系。 從圖中可以看出,Linux設備模型就是"總線、設備、驅動、類"這四個概念之前的相互關系;這也是Linux2.6內核抽象出來的用于管理系統中所有設備的模型圖; 簡單地描述…

angular自定義指令詳解

指令(directive)是angular里面最核心也是最難懂的東西,在慕課網看了下大漠窮秋老濕的視頻,自己百度半天做了一些小test,總算把一切都搞明白了。 先列出學習來源: 指令中controller和link的區別:…

delphi7aes加密解密與java互轉_跨語言(java vs python vs nodejs)的RSA加解密問題探討

多次被問到這樣的問題:java服務端的rsa加密操作已經完成,返回一個16進制的字符串給python平臺,但是在python進行私鑰解密的時候發現行不通。。。。前端python加密,后端用java解密,解不出來還有諸如nodejs從理論上來說&…

類的定義、成員定義修飾符

類的定義 修飾符含義1無或internal 只能在當前項目中訪問類,其它項目引用后也無法訪問2public 可以任何地方訪問類3abstract 不能實例化,只能供繼承之用4sealed 不能供派生之用,只能實例化5internal abstract136public abstract237intern…

設備模型3

在上一篇分析中,多次提到了SYSFS,這是個什么東西?這可是個很大的TOPIC,關于它的講述可以寫本書,但是我們暫時的目標不是要完全啃投它所有的東西,沒時間,沒精力,我們只要掌握我們需要…

浪潮之巔讀后感

這幾天看到一本非常好的書《浪潮之巔》。浪潮,指的是時代的大潮。而浪潮之巔,顧名思義就是指站在時代潮流的巔峰,引領時代潮流,扛起發展大旗。而本書就是在介紹各大處在浪潮之巔的IT公司的歷史及發展。 書中有句話說得好&#xff…

利用dft的定義計算dft的matlab程序_CP2K教程系列之靜態計算(Pymatflow篇)

本系列CP2K教程是《CP2K菜根譚》的升級版,在舊版基礎上添加了如何結合Pymatflow工具簡化計算流程的內容。話不多說,本文將為您帶來CP2K系列教程中的靜態計算部分。靜態計算設置靜態計算是大多數人接觸第一性原理計算后第一次運行的計算類型。很多其它類型…

機器學習:最大似然估計與最大后驗概率估計

在機器學習領域,概率估計是經常用到的一種模型,而概率估計中,我們經常會看到兩種估計模型,一種是最大似然估計,即 Maximum likelihood, 另外一種就是最大后驗概率估計,即 Maximum posterior &am…

ubuntu14.04安裝git

參考教程:git介紹:安裝,使用,創建分支 安裝的方法有兩種,一種直接是通過ubuntu的APT安裝,這種方法最簡便,缺點是版本可能不是最新的。所有還有另一種方法是下載源碼進行安裝,這種能…