美團面試的時候,突然面試官有問到我為什麼中斷上下文不能睡眠,當時不了解,後來上網搜搜,發現各種說法:
程序上下文:
通過系統呼叫,使用者空間的應用程式就會進入核心空間,由核心代表該程序執行於核心空間,這就涉及到上下文的切換,使用者空間和核心空間具有不同的位址對映,通用或專用的暫存器組,而使用者空間的程序要傳遞很多變數、引數給核心,核心也要儲存使用者程序的一些暫存器、變數等,以便系統呼叫結束後回到使用者空間繼續執行,所謂的程序上下文,就是乙個程序在執行的時候,cpu的所有暫存器中的值、程序的狀態以及堆疊中的內容,當核心需要切換到另乙個程序時,它需要儲存當前程序的所有狀態,即儲存當前程序的程序上下文,以便再次執行該程序時,能夠恢復切換時的狀態,繼續執行。
中斷上下文:
硬體通過觸發訊號,導致核心呼叫中斷處理程式,進入核心空間。這個過程中,硬體的一些變數和引數也要傳遞給核心,核心通過這些引數進行中斷處理,中斷上下文就可以理解為硬體傳遞過來的這些引數和核心需要儲存的一些環境,主要是被中斷的程序的環境。
linux核心工作在程序上下文或者中斷上下文。提供系統呼叫服務的核心**代表發起系統呼叫的應用程式執行在程序上下文;另一方面,中斷處理程式,非同步執行在中斷上下文。中斷上下文和特定程序無關。
執行在程序上下文的核心**是可以被搶占的(linux2.6支援搶占)。但是乙個中斷上下文,通常都會始終占有cpu(當然中斷可以巢狀,但我們一般不這樣做),不可以被打斷。正因為如此,執行在中斷上下文的**就要受一些限制,不能做下面的事情:
1、睡眠或者放棄cpu。
這樣做的後果是災難性的,因為核心在進入中斷之前會關閉程序排程,一旦睡眠或者放棄cpu,這時核心無法排程別的程序來執行,系統就會死掉
2、嘗試獲得訊號量
如果獲得不到訊號量,**就會睡眠,會產生和上面相同的情況
3、執行耗時的任務
中斷處理應該盡可能快,因為核心要響應大量服務和請求,中斷上下文占用cpu時間太長會嚴重影響系統功能。
4、訪問使用者空間的虛擬位址
因為中斷上下文是和特定程序無關的,它是核心代表硬體執行在核心空間,所以在終端上下文無法訪問使用者空間的虛擬位址
訊號量/互斥量/互斥鎖允許資源申請者進入睡眠,自旋鎖不允許呼叫者睡眠,而是讓其迴圈等待;所以訊號量/互斥量/互斥鎖不允許使用在中斷上下文中,由於在睡眠或者放棄cpu後,核心無法進行程序排程,所以不能排程其他的程序來執行,系統會死掉。
1、 中斷處理的時候,不應該發生程序切換,因為在中斷context中,唯一能打斷當前中斷handler的只有更高優先順序的中斷,它不會被程序打斷,如果在 中斷context中休眠,則沒有辦法喚醒它,因為所有的wake_up_***都是針對某個程序而言的,而在中斷context中,沒有程序的概念,沒 有乙個task_struct(這點對於softirq和tasklet一樣),因此真的休眠了,比如呼叫了會導致block的例程,核心幾乎肯定會死。
2、schedule()在切換程序時,儲存當前的程序上下文(cpu暫存器的值、程序的狀態以及堆疊中的內容),以便以後恢復此程序執行。中斷發生後,核心會先儲存當前被中斷的程序上下文(在呼叫中斷處理程式後恢復);
但在中斷處理程式裡,cpu暫存器的值肯定已經變化了吧(最重要的程式計數器pc、堆疊sp等),如果此時因為睡眠或阻塞操作呼叫了schedule(),則儲存的程序上下文就不是當前的程序context了.所以不可以在中斷處理程式中呼叫schedule()。
3、2.4核心中schedule()函式本身在進來的時候判斷是否處於中斷上下文:
if(unlikely(in_interrupt()))
bug();
因此,強行呼叫schedule()的結果就是核心bug,但我看2.6.18的核心schedule()的實現卻沒有這句,改掉了。
4、中斷handler會使用被中斷的程序核心堆疊,但不會對它有任何影響,因為handler使用完後會完全清除它使用的那部分堆疊,恢復被中斷前的原貌。
5、處於中斷context時候,核心是不可搶占的。因此,如果休眠,則核心一定掛起
中斷上下文 程序上下文
在學習與作業系統相關的知識時候,我們經常遇到程序上下文 中斷上下文,看似熟悉又感覺不是特別清晰。這裡我們從如下幾個方面進行描述。上下文是從英文中context翻譯過來的,指的是一種環境。上下文我們看起來不怎麼熟悉,但是我們可以看context的中文翻譯,或者我們能更加的情形些。context n 語...
中斷上下文
一 中斷下半部 工作佇列 1 中斷 先看一下宋寶華先生的 linux裝置驅動開發詳解 裡面對中斷的描述吧。這本書個人感覺 寫的比較好,從開始學驅動到現在,還能從中得到不少知識。裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望...
linux中斷 程序上下文和中斷上下文
中斷發生以後,cpu跳到核心設定好的中斷處理 中去,由這部分核心 來處理中斷。這個處理過程中的上下文就是中斷上下文。為什麼可能導致睡眠的函式都不能在中斷上下文中使用呢?首先睡眠的含義是將程序置於 睡眠 狀態,在這個狀態的程序不能被排程執行。然後,在一定的時機,這個程序可能會被重新置為 執行 狀態,從...