Chapter 5.Interrupt Request Levels(IRQL) and DPCs
Q1. what is the different between Scheduling and IRQL?
All user mode thread execution takes place at IRQL PASSIVE_LEVEL.Scheduling priorities are artifacts of Dispather(DISPATH_LEVEL) which used them to determine which thread to next make active.
IRQL are interrupt priorities. An interrupt at any IRQL above PASSIVE_LEVEL will interrupt the highest priority User mode thread in the system.
Q2. How IRQL are used?
Currrent IRQL deffer the same or lower IRQL activities.
Never lower your IRQL less than that at which it was entered.
0-31 levels IRQL,
0 PASSIVE_LEVEL Oridinary thread execution in both kernel and user modes.
1 APC_LEVEL Kernel Asynchronous Procedure Calls(APC) handling; Paging
I/O completion is used in APC_LEVEL for iostatus that will be returned to its calling context. The kernel mode APCs is serialized.
n Processing Deffered Procedure Calls(DPC)
n Running the Dispatcher.(thread scheduler)
l Thread in DISPATH_LEVEL will run regardless of quantum expires.
l Codes run at DISPATCH_LEVEL can not wait for event or mutex to be set. The wait operation directly returns.
l Must use nonpaged codes, as can not wait for dispatch objects to be signaled.
Q3. What are DPC and its characteristics?
DPC are typically requested from higher IRQLs to allow processing to take place.Eg: Timer.
DPC objects are allocated by nonpaged pool and inilizatied by KeinitializeDpc() with DefferRoutine. Then place the DPC objects insert into the DPC queue of issued processor. DPCs are invoked before dispatcher and run in arbitrary context.
A DPC object can be unique in DPC queue. If insert again, it will be ignored.
Q4. How does DPC use in multiprocessor enviroment?
Work in parallel status.
By default it is the issued processor. Functions KeSetTargetProcessor() can be used.
Q4. what is DpcForIsr and its usage?
Special DPC used for Interrupt Service Routines (ISR).
Chapter 15 Interrupt Service Routines and DPCs.
Q1 What is ISR? When to use ISR?
When a device interrupts, ISR is called. ISR gathering the information about the device and passed that information to DpcForIsr to process.
Preparation: In DriverEntry
1. Translating Interrupt levels and vectors. HalGetInterruptVector() gets the device interrupt level translated to IRQL parameters and return the translated interrupt vector.
2. Connect its ISR to the interrupt by IoConnectInterrupt()
3. using function to intialize DPC object for DpcForIsr.
IN PDEVICE_OBJECT DeviceObject, // initialized DPC object //embedded in device object
IN PIO_DPC_ROUTINE DpcRoutine) // Pointer to DpcForIsr
Q2 What should ISR do and what should DPCForISR do?
ISR Entry point: Before entered, spin locks are required.
//1 Determine whether is interrupting
//2 Storing interrupt information for the DPC in device object extension.
//3 requesting the Device DpcForIsr
VOID IoRequestDpc() to use DpcForIsr
KeInsertQueueDpc() to use CustomDpc.
//4 return true to indicate the interrupt has been recognized.
ISR runs in arbitrary thread context at DIRQL.
IoCompleteRequest() can not be used in ISR and must be used in DpcForIsr().
Q3 The usage of DPCForIsr and CustomDpc.
DPCForIsr is reference in driverEntry, CustomDpc use KeInsertQueueDpc().
Q4 ISR VS DPC, which should process more? Why？
ISR should process as short as possible. Coz ISR run in DIRQL.