Deferred Procedure Calls (DPCs)

< BACK  NEXT >
[oR]

While a piece of kernel-mode code is running at an elevated IRQL, nothing executes (on the same CPU) at that or any lower IRQL. Of course, if too much code executes at too high an IRQL, overall system performance will degrade. Time-critical event handling could be deferred and cause more disastrous results.

To avoid these problems, kernel-mode code must be designed to execute as much code as possible at the lowest possible IRQL. One important part of this strategy is the Deferred Procedure Call (DPC).

Operation of a DPC

The DPC architecture allows a task to be triggered, but not executed, from a high-level IRQL. This deferral of execution is critical when servicing hardware interrupts in a driver because there is no reason to block lower-level IRQL code from executing if a given task can be deferred. Figure 3.1 illustrates the operation of a DPC. Subsequent chapters present more specific information about the use of a DPC in a driver, but an overview is presented below.

Figure 3.1. Deferred Procedure Call flow.
graphics/03fig01.gif
  1. When some piece of code running at a high (e.g., hardware) IRQL wants to schedule some of its work at a lower IRQL, it adds a DPC object to the end of the system's DPC dispatching queue and requests a DPC software interrupt. Since the current IRQL is above DISPATCH_ LEVEL, the interrupt won't be acknowledged immediately, but instead remains pending.

  2. Eventually, the processor's IRQL falls below DISPATCH_LEVEL and the previously pended interrupt is serviced by the DPC dispatcher.

  3. The DPC dispatcher dequeues each DPC object from the system queue and calls the function whose pointer is stored in the object. This function is called while the CPU is at DISPATCH_LEVEL.

  4. When the DPC queue is empty, the DPC dispatcher dismisses the DISPATCH_LEVEL software interrupt.

Device drivers typically schedule cleanup work with a DPC. This has the effect of reducing the amount of time the driver spends at its DIRQL and improves overall system throughput.

Behavior of DPCs

For the most part, working with DPCs is easy because Windows 2000 includes library routines that hide most details of the process. Nevertheless, there are two frustrating aspects of DPCs that should be highlighted.

First, Windows 2000 imposes a restriction that only one instance of a DPC object may be present on the system DPC queue at a time. Attempts to queue a DPC object that is already in the queue are rejected. Consequently, only one call to the DPC routine occurs, even though a driver expected two. This might happen if two back-to-back device interrupts occurred before the initial DPC could execute. The first DPC is still on the queue when the driver services the second interrupt.

The driver must handle this possibility with a clever design. Perhaps a count of DPC requests could be maintained or a driver might choose to implement a separate (on the side) queue of requests. When the real DPC executes, it could examine the count or private queue to determine exactly what work to perform.

Second, there is an issue of synchronization when working with multiprocessor machines. One processor could service the interrupt and schedule the DPC. However, before it dismisses the interrupt, another parallel processor could respond to the queued DPC. Thus, the interrupt service code would be executing simultaneously with the DPC code. For this reason, DPC routines must synchronize access to any resources shared with the driver's interrupt service routine.

The DPC architecture prevents any two DPCs from executing simultaneously, even on a multiprocessor machine. Thus, resources shared by different DPC routines do not need to worry about synchronization.

< BACK  NEXT >


The Windows 2000 Device Driver Book(c) A Guide for Programmers
The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)
ISBN: 0130204315
EAN: 2147483647
Year: 2000
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net