2011年7月16日 星期六

IRQL and Page Fault

寫 Windows driver 常會看到 IRQL(IRQ Level), 它其實是對應於 CPU 提供的硬體中斷, 不同架構的 CPU 提供不等的硬體中斷數目, IRQL 愈高, 優先權就愈高, 可插斷正在低優先權中執行的工作.

我們常看到的 IRQL 有 PASSIVE_LEVEL 及 DISPATCH_LEVEL, 它們的 IRQL 如下:

    最低優先權    PASSIVE_LEVEL    0
                APC_LEVEL        1
                DISPATCH_LEVEL   2
                ...
    最高優先權    HIGH_LEVEL       15/31

一般 kernel thread 或是 user thread 會執行在 PASSIVE_LEVEL, 而負責 context switch 的 scheduler(Windows 稱 dispatcher) 及 DPC 等會執行在 DISPATCH_LEVEL. 在兩個優先權中間還有一個 APC_LEVEL, 處理非同步程序, 例如 page fault 發生後的處理等等.

在 MSDN 上查詢 kernel API 或是 callback 時, 都會看到 IRQL 的需求, 如果某 API 的 IRQL 需求是 PASSIVE_LEVEL, 那麼它的程式碼可能會在分頁區段, 或是它可能需要存取分頁區段的程式碼或資料, 因此最好不要在 DISPATCH_LEVEL 時叫用它, 否則可能會發生 page fault 而無法跳至 APC_LEVEL 中處理. 一樣地, 如果某 callback 的 IRQL 需求是 DISPATCH_LEVEL, 那麼你在實作這個 callback 時, 最好都只叫用 IRQL 需求是 DISPATCH_LEVEL 的 API 及非分頁區段中的程式碼.


更多資訊:

3 則留言: