撰寫 DPC 常式的指導方針

撰寫 DpcForIsrCustomDpc 常式時,請記住下列幾點:

  • DpcForIsrCustomDpc常式必須同步處理其實體裝置的存取權,以及驅動程式維護的任何共用狀態資訊或資源,以及驅動程式存取相同裝置或記憶體位置的其他常式。

    如果 DpcForIsrCustomDpc 常式與 ISR 共用裝置或狀態,則必須呼叫 KeSynchronizeExecution,並提供驅動程式提供的 SynchCritSection 常式位址,以程式設計裝置或存取共用狀態。 如需詳細資訊,請參閱 使用重要區段

    如果 DpcForIsrCustomDpc 常式共用狀態或資源,例如連結佇列或計時器物件,且具有 ISR 以外的常式,則必須使用驅動程式初始化的執行微調鎖定來保護共用狀態或資源。 如需詳細資訊,請參閱 微調鎖定

  • DpcForIsrCustomDpc 常式會在 IRQL = DISPATCH_LEVEL執行,這會限制他們可以呼叫的支援常式集。

    例如, DpcForIsrCustomDpc 常式無法存取或配置可分頁記憶體,而且無法等候 核心發送器物件 設定為已發出訊號的狀態。 另一方面,他們可以使用 KeAcquireSpinLockAtDpcLevelKeReleaseSpinLockFromDpcLevel取得並釋放驅動程式的執行微調鎖定,其執行速度比 KeAcquireSpinLockKeReleaseSpinLock快。

    雖然 DPC 常式無法進行封鎖呼叫,但它可以將工作專案排入佇列,以在 IRQL 上執行的 系統背景工作執行緒 中執行,其等於PASSIVE_LEVEL。 工作專案可以進行封鎖呼叫,以等候發送器物件。 若要將工作專案排入佇列, DpcForIsr 常式通常會呼叫 IoQueueWorkItem之類的常式,而 CustomDpc 常式通常會呼叫 ExQueueWorkItem 常式。

  • DpcForIsrCustomDpc 常式通常負責啟動裝置上的下一個 I/O 作業。

    對於使用直接 I/O 的最低層級實體設備磁碟機,此責任可能包括使用 SynchCritSection 常式 來程式設計裝置以傳輸更多資料,以便在驅動程式呼叫 IoStartNextPacket之前滿足目前的 IRP。

  • DpcForIsrCustomDpc 常式應該只在短時間內執行,而且應該盡可能將處理委派給背景工作執行緒。

    當 DPC 常式在處理器上執行時,所有線程都無法在同一個處理器上執行。 已排入佇列並準備好執行的其他 DPC 常式可以封鎖執行,直到目前的 DPC 常式完成為止。 為了避免系統回應性降低,每次呼叫 DPC 常式時,一般 DPC 常式應該執行不超過 100 毫秒。 如果工作需要超過 100 毫秒,而且必須在 IRQL 執行等於 DISPATCH_LEVEL,DPC 常式應該會在 100 微秒之後結束,並排程一或多個 CustomTimerDpc 常式,稍後完成工作。 如需 CustomTimerDpc 常式的詳細資訊,請參閱 計時器物件和 DPC

    DPC 常式應該只執行必須在DISPATCH_LEVEL執行的工作,然後將任何剩餘中斷相關工作委派給在 IRQL = PASSIVE_LEVEL執行的執行緒。 例如,DPC 常式可以將工作專案排入佇列,以在 系統背景工作執行緒中執行。

    呼叫 KeStallExecutionProcessor 常式以順延強制的 DPC 常式不得指定超過 100 毫秒的延遲。

    使用 WDK 中的效能分析工具來評估 DPC 常式的執行時間。 如需使用 Tracelog 工具來監視 DPC 執行時間的範例,請參閱 範例 15:測量 DPC/ISR 時間

  • 如果驅動程式使用 DMA 及其 AdapterControl 常式傳回 KeepObjectDeallocateObjectKeepRegisters (藉此保留系統 DMA 控制器通道或匯流排主機介面卡以進行其他傳輸作業) , DpcForIsrCustomDpc 常式負責在完成目前的 IRP 並傳回控制項之前,先釋放配接器物件或地圖暫存器與 FreeAdapterChannelFreeMapRegisters

  • 如果最低層級的實體設備磁碟機設定 控制器物件 ,以透過控制器同步處理 I/O 作業至連接的裝置,其 DpcForIsrCustomDpc 常式會負責使用 IoFreeController 釋放控制器物件,再完成目前的 IRP 並傳回控制項。

  • DpcForIsrCustomDpc 常式通常負責記錄在處理指定要求期間發生的任何裝置錯誤、視需要和可能重試目前的要求,以及設定 I/O 狀態欄塊,並呼叫目前 IRP 的 IoCompleteRequest

  • 如果驅動程式和裝置支援重迭的 I/O 作業,驅動程式必須遵循 處理重迭 I/O 作業的規則。

  • 任何驅動程式的 DpcForIsrCustomDpc 常式通常只會針對驅動程式必須支援的公用 I/O 控制項代碼子集完成 I/O 處理。 特別是,DPC 常式會針對具有下列特性的裝置控制要求完成作業:

    • 變更實體裝置狀態的要求

    • 要求需要傳回實體裝置的固有變動性資訊