中斷的概念
中斷是系統用來響應硬件設備請求的一種機制,它會打斷進程的正常調度和執行,然後調用內核中的中斷處理程序來響應設備的請求。
中斷其實是一種異步的事件處理機制,可以提高系統的併發處理能力。由於中斷處理程序會打斷其他進程的運行,所以,爲了減少對正常進程運行調度的影響,中斷處理程序就需要儘可能快地運行。如果中斷本身要做的事情不多,那麼處理起來也不會有太大問題;但如果中斷要處理的事情很多,中斷服務程序就有可能要運行很長時間。
中斷處理程序在響應中斷時,還會臨時關閉中斷。這就會導致上一次中斷處理完成之前,其他中斷都不能響應,也就是說中斷有可能會丟失。
軟中斷
爲了解決中斷處理程序執行過長和中斷丟失的問題,Linux 將中斷處理過程分成了兩個階段,也就是上半部和下半部:
- 上半部用來快速處理中斷,它在中斷禁止模式下運行,主要處理跟硬件緊密相關的或時間敏感的工作。
- 下半部用來延遲處理上半部未完成的工作,通常以內核線程的方式運行。
這裏以網卡接收數據包的過程爲例來說明:
網卡接收到數據包後,會通過硬件中斷的方式,通知內核有新的數據到了。這時,內核就應該調用中斷處理程序來響應它。
對於中斷上半部來說,既然是快速處理,其實就是要把網卡的數據讀到內存中,然後更新一下硬件寄存器的狀態(表示數據已經讀好了),最後再發送一個軟中斷信號,通知下半部做進一步的處理。
而下半部被軟中斷信號喚醒後,需要從內存中找到網絡數據,再按照網絡協議棧,對數據進行逐層解析和處理,直到把它送給應用程序。 - 上半部直接處理硬件請求,也就是我們常說的硬中斷,特點是快速執行;
- 而下半部則是由內核觸發,也就是我們常說的軟中斷,特點是延遲執行。
軟中斷不只包括了剛剛所講的硬件設備中斷處理程序的下半部,一些內核自定義的事件也屬於軟中斷,比如內核調度和 RCU 鎖(Read-Copy Update 的縮寫,RCU 是 Linux 內核中最常用的鎖之一)等。
如何查看軟中斷和內核線程
Linux內核的proc 文件系統,它是一種內核空間和用戶空間進行通信的機制,可以用來查看內核的數據結構,或者用來動態修改內核的配置。
- /proc/softirqs 提供了軟中斷的運行情況;
- /proc/interrupts 提供了硬中斷的運行情況
下面是我的系統上中斷運行情況:
下面是我的系統上軟中斷運行情況:
$ cat /proc/softirqs
CPU0 CPU1
HI: 0 0
TIMER: 811613 1972736
NET_TX: 49 7
NET_RX: 1136736 1506885
BLOCK: 0 0
IRQ_POLL: 0 0
TASKLET: 304787 3691
SCHED: 689718 1897539
HRTIMER: 0 0
RCU: 1330771 1354737
查看 /proc/softirqs 文件內容時,需要注意以下這兩點:
- 軟中斷的類型。從第一列可以看到,軟中斷包括了 10 個類別,分別對應不同的工作類型。
- 同一種軟中斷在不同 CPU 上的分佈情況,也就是同一行的內容。正常情況下,同一種中斷在不同 CPU 上的累積次數應該差不多。
軟中斷實際上是以內核線程的方式運行的,每個 CPU 都對應一個軟中斷內核線程,這個軟中斷內核線程就叫做 ksoftirqd/CPU 編號。可以通過下面的命令來查詢:
$ ps aux | grep softirq
root 7 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/0]
root 16 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/1]
小結
Linux中的中斷處理程序分爲上半部和下半部:
-
上半部對應硬件中斷,用來快速處理中斷
-
下半部對應軟中斷,用來異步處理上半部未完成的工作。
Linux中的軟中斷包括網絡收發、定時、調度、RCU鎖等各種類型,可以通過查看/proc/softirqs來觀察軟中斷的運行情況。