Linux 驅動程式的中斷處理, #2: 深入淺出中斷模式

jollen 發表於 March 2, 2008 10:09 PM

Interrupt handler 的工作是負責處理裝置的中斷請求,並將結果回報(feedback)給裝置。一般而言,裝置產生中斷時,都是與資料讀寫有關的請求。Interrupt handler 便要根據中斷的特性,來判斷此中斷是要請求驅動程式將資料寫入至裝置,或是由裝置讀取資料。

Linux 驅動程式的 interrupt handler 實作原則如下:

1. 在 interrupt handler 裡,叫醒真正負責此中斷的 task 後立即結束執行。
2. Interrupt handler 應儘量執行最少的程式碼。
3. Interrupt handler 若執行過久,會造成中斷的關閉時間過長,因此可能會遺失緊接著產生的中斷請求。
4. 若 interrupt handler 裡有過長的計算動作或執行過久的程式碼,則應使用 tasklet 或 task queue 將該段程式碼做排程,留待其它時間再執行。如此便可避免interrupt handler執行時間過久。

此外,在中斷模式下做同步控制時,還要考慮是否會佔用過久 CPU 時間的問題。為什麼中斷模式下寫 code 需要注意這個議題呢?請看以下的說明。

Counting Semaphore

在作業系統教科書中,提及二種 semaphore 的做法:

1. blocking counting semaphore,即 Linux 的 down/up 版本。
2. spinlock counting semaphore,即 Linux 的 spinlock。

Spinlock counting semaphore 屬於傳統作法,spinlock 讓 waiting 的動作(P operation)以 busy-loop 方式實作,因此會佔用 CPU 資源;blocking counting semaphore 則是將 waiting 的動作以 blocking(sleeping) 的方式來進行。

在Linux kernel 裡,blocking counting semaphore 採用 wait queue 來實作,即以 sleep 方式做P operation。Wait queue 機制對驅動程式來說,原始用意為實作 process(user-space)的 blocking read 與 blocking write,這樣的 behavior 機制經常出現在實作 process 讀取裝置資料的場合;當 process 進行 blocking I/O 讀寫(synchronous I/O)時,由於 kernel-space 是以 sleeping 方式進行等待,因此能把 CPU 交給其它人使用,並將 process 排程到 I/O queue(waiting queue),因此不獨佔或浪費 CPU 時間。

在中斷模式下,因為不能使用 sleeping 版本的 semaphore,所以必須使用 spinlock,在此情況下,便會遭遇到 interrupt handler 佔用 CPU 時間太久的問題。

讀者留言 (0)

留言功能維護中。將於近日重新開放。

連絡作者

Jollen Chen,Moko365(仕橙3G教室)講師,熱愛研究 Linux 與 Android 技術。曾為 Motorola、HTC、Foxconn、LG、OPPO、騰迅、廣達電腦、緯創、仁寶等超過 50 家企業講授課程。目前在 MokoVersity 擔任軟體工程師,撰寫 Node.js 程式,也在幾家科技廠兼任 Android Framework 研發顧問。您可透過電子郵件 <jollen (at) jollen (dot) org> 或這裡與我連絡。