中斷上下文主要是硬體中斷上下文 軟體中斷上下文 和 bh臨界區上下文
中斷上下文你主要分為以下兩種情況
(1)執行該中斷的處理函式(我們一般稱之interrupt handler或者叫做top half),也就是hard interrupt context
(2)執行軟中斷處理函式,執行tasklet函式,執行timer callback函式。(或者統稱bottom half),也就是software interrupt context。
top half當然是絕對的interrupt context,但對於上面的第二種情況,稍微有些複雜,其執行的現場包括:
(1)執行完top half,立刻啟動bottom half的執行ss
(2)當負荷比較重的時候(中斷產生的比較多),系統在一段時間內都在處理interrupt handler以及相關的softirq,從而導致無法排程到程序執行,這時候,linux kernel採用了將softirq推遲到softirqd這個核心執行緒中執行
(3)程序在核心態執行的時候,由於核心同步的需求,需要使用local_bh_disable/local_bh_enable來保護臨界區。在臨界區**執行的時候,有可能中斷觸發並raise softirq,但是由於softirq處於disable狀態從而在中斷返回的時候沒有辦法invoke softirq的執行,當呼叫local_bh_enable的時候,會呼叫已經觸發的那個softirq handler。
對於上面的情況1和情況3,毫無疑問,絕對的中斷上下文,執行現場的current task和softirq handler沒有任何的關係。對於情況2,雖然是在專屬的核心執行緒中執行,但是我也傾向將其歸入software interrupt context。
中斷是短暫的 linux核心的大部分時間都是各種程序切來切去 一會兒執行在程序的使用者空間,一會兒通過系統呼叫進入核心空間 當時系統不是封閉的 也要和外設等互動 這是就要通過中斷上下文 外省硬體的互動 最後把資料交付程序或者程序將資料傳遞給外設 程序上下文有豐富的、屬於自己的資源:例如有硬體上下文,有使用者棧、有核心棧,有使用者空間的正文段、資料段等等。而中斷上下文什麼也沒有,只有一段執行**及其附屬的資料 所以當中斷發生的時候,遇到哪乙個程序就借用哪乙個程序的資源 這也就導致了中斷上下文不能睡眠的原因
linux提供了幾個函式判斷是在哪個context
#define in_irq() (hardirq_count())
#define hardirq_count() (preempt_count() & hardirq_mask)
top half的處理是被irq_enter()和irq_exit()所包圍,在irq_enter函式中會呼叫preempt_count_add(hardirq_offset),為hardirq count的bit field增加1。在irq_exit函式中,會呼叫preempt_count_sub(hardirq_offset),為hardirq count的bit field減去1。因此,只要in_irq非零,則說明在中斷上下文並且處於top half部分。
解決了hard interrupt context,我們來看software interrupt context。
#define in_serving_softirq() (softirq_count() & softirq_offset)
這個函式是直接的判斷是否在software interrupt context
還有乙個類似的函式
#define in_softirq() (softirq_count())
#define softirq_count() (preempt_count() & softirq_mask)
這是判斷是否在software interrupt context 和程序上下文中disable bottom half的臨界區部分
#define in_interrupt() (irq_count())
#define irq_count() (preempt_count() & (hardirq_mask | softirq_mask \
| nmi_mask))
這是hard interrupt contxt software interrupt context 上禁止softirq情況下的程序上下文
中斷上下文不能sleep的原因
當然,linux的設計並非如此(其實在rt linux中已經有了這樣的苗頭,可以參考中斷執行緒化的文章),中斷handler以及bottom half(不包括workqueue)都是在interrupt context中執行。當然一提到context,各種資源還是要存在的,例如說核心棧、例如說memory space等,interrupt context雖然單薄,但是可以借屍還魂。當中斷產生的那乙個時刻,當前程序有幸成為interrupt context的殼,提供了核心棧,儲存了hardware context,此外各種資源(例如mm_struct)也是借用當前程序的。本來呢interrupt context身輕如燕,沒有依賴的task,排程器其實是不知道如何排程interrupt context的(它處理的都是task),在interrupt context借了乙個外殼後,從理論上將,排程器是完全可以block該interrupt context執行,並將其他的task調入進入running狀態。然而,block該interrupt context執行也就block其外殼task的執行,多麼的不公平,多麼的不確定,中斷命中你,你就活該被schedule out,擁有正常思維的linux應該不會這麼做的。
因此,在中斷上下文中(包括hard interrupt context和software interrupt context)不能睡眠。
中斷上下文 程序上下文
在學習與作業系統相關的知識時候,我們經常遇到程序上下文 中斷上下文,看似熟悉又感覺不是特別清晰。這裡我們從如下幾個方面進行描述。上下文是從英文中context翻譯過來的,指的是一種環境。上下文我們看起來不怎麼熟悉,但是我們可以看context的中文翻譯,或者我們能更加的情形些。context n 語...
中斷上下文
一 中斷下半部 工作佇列 1 中斷 先看一下宋寶華先生的 linux裝置驅動開發詳解 裡面對中斷的描述吧。這本書個人感覺 寫的比較好,從開始學驅動到現在,還能從中得到不少知識。裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望...
linux中斷 程序上下文和中斷上下文
中斷發生以後,cpu跳到核心設定好的中斷處理 中去,由這部分核心 來處理中斷。這個處理過程中的上下文就是中斷上下文。為什麼可能導致睡眠的函式都不能在中斷上下文中使用呢?首先睡眠的含義是將程序置於 睡眠 狀態,在這個狀態的程序不能被排程執行。然後,在一定的時機,這個程序可能會被重新置為 執行 狀態,從...