首頁 > php教程 > PHP开发 > 深入淺出分析Linux裝置驅動程式中斷 (1)(3)

深入淺出分析Linux裝置驅動程式中斷 (1)(3)

黄舟
發布: 2016-12-23 14:32:31
原創
1499 人瀏覽過

六、中斷處理程序的不可重入性

上一節我們提到有時候需要屏蔽中斷,可是為什麼要將這個中斷屏蔽掉呢?這並不是因為技術上實作不了同一中斷例程的並行,而是出於管理上的考量。之所以在中斷處理的過程中要屏蔽同一IRQ來的新中斷,是因為中斷處理程序是不可重入的,所以不能並行執行同一個中斷處理程序。這裡我們舉一個例子,從這裡子例可以看出如果一個中斷處理程序是可以並行的話,那麼很有可能會發生驅動程式鎖死的情況。當驅動程式鎖死的時候,你的作業系統不一定會崩潰,但是鎖死的驅動程式所支援的那個裝置是不能再使用了--裝置驅動程式死了,裝置也就死了。

其中激發PS1的事件會使A1產生一個中斷,然後B1去讀R1中已有的數據,然後代碼C1向R2中寫數據。而激發PS2的事件會使A2產生一個中斷,然後B2刪除R1中的數據,然後C2讀去R2中的數據。

如果PS1先產生,且當他執行到A1和B1之間的時候,如果PS2產生了,這是A2會產生一個中斷,將PS2中斷掉(掛到任務隊列的尾部),然後刪除了R1的內容。當PS2運行到C2時,由於C1還沒有向R2中寫數據,所以C2將會在這裡被掛起,PS2就睡眠在代碼C2上,直到有數據可讀的時候被信號喚醒。這是由於PS1中的B2原先要讀的R1中的資料被PS2中的B2刪除了,所以PS1頁會睡在B1上,直到有資料可讀的時候被訊號喚醒。這樣一來,喚醒PS1和PS2的事件就永遠不會發生了,因此PS1和PS2之間就鎖死了。

由於裝置驅動程式要和裝置的暫存器打交道,所以很難寫出可以重入的程式碼來,因為裝置暫存器就是全域變數。因此,最簡潔的辦法就是禁止相同裝置的中斷處理程序並行,也就是裝置的中斷處理程序是不可重入的。

有一點一定要清楚:在2.0版本以後的Linux kernel中,所有的上半部都是不可中斷的(上半部的操作是原子性的);不同設備的下半部可以互相中斷,但一個特定的下半部不能被它自己所中斷(即同一個下半部不能並行)。

由於中斷處理程序要求不可重入,所以程式設計師也不必為編寫可重入的程式碼而頭痛了。以我的經驗,編寫可重入的裝置驅動程式是可以的,編寫可重入的中斷處理程序是非常難得,幾乎不可能。

七、避免競爭條件的出現

我們都知道,一旦競爭條件出現了,就有可能會發生死鎖的情況,嚴重時可能會將整個系統鎖死。所以一定要避免競爭條件的出現。這裡我不多說,大家只要注意一點:絕大多數因為中斷產生的競爭條件,都是在有中斷的核心行程被睡眠造成的。所以在實作中斷的時候,一定要相信謹慎的讓行程睡眠,必要的時候可以使用cli、sti或save_flag、restore_flag。具體細節請參考本文指定參考書。

八、實作

如何實現驅動程式的中斷例程,是各位讀者的事情了。只要你們仔細的閱讀short例程的源代碼,搞清楚編寫驅動程式中斷例程的規則,就可以編寫自己的中斷例程了。只要概念正確,在正確的規則下寫你的程式碼,那就是符合道理的東西。我始終強調,概念是第一位的,能編多少程式碼是很其次的,我們一定要概念正確,才能進行正確的思考。

(T114)

 以上就是深入淺出分析Linux裝置驅動程式中斷 (1)(3)的內容,更多相關內容請關注PHP中文網(www.php.cn)!


來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板