Interrupt Synchronization

< BACK  NEXT >
[oR]

Writing reentrant code that executes at multiple IRQL levels requires attention to proper synchronization. This section examines the issues that arise in this kind of environment.

The Problem

If code executing at two different IRQLs attempts to access the same data structure simultaneously, the structure can become corrupted. Figure 5.1 illustrates the details of this synchronization problem.

Figure 5.1. Synchronization problem with interrupting code.
graphics/05fig01.gif

To understand the exact problem, consider this sequence of events.

  1. Suppose code executing at a low IRQL decides to modify several fields in the foo data structure. For this example, the code executes to the point where the field foo.x is set to 1.

  2. An interrupt occurs and a higher-IRQL piece of code gets control of the processor. This code also modifies foo, setting foo.x to 10 and foo.y to 20.

  3. When the higher-IRQL code dismisses its interrupt and control returns to the lower-IRQL routine, the original modification of foo completes by setting foo.y to 2. The lower-IRQL code is completely unaware that it was interrupted.

  4. The foo structure is now inconsistent, with 10 in the x field and 2 in the y field. Neither section of code obtains the desired result.

Of course, similar results occur even when only a single shared value is used with different code threads. When one code path attempts to increment the variable, there may be a brief moment in time when the modified value is held in a CPU register. If this thread is interrupted prior to storing the register back into the variable, the same contention problem arises.

In the following sections, techniques that a driver can use to synchronize the work of multiple code paths is described.

Interrupt Blocking

In the previous example, the lower-IRQL routine could have avoided synchronization problems by preventing itself from being interrupted. To do this, it can temporarily raise the IRQL of the CPU and then lower it back to its original level after completing the modification. This technique is called interrupt blocking. Table 5.4 lists the kernel functions that a driver can use to manipulate the IRQL value.

Rules for Blocking Interrupts

When using interrupt blocking, there are certain rules that must be followed.

Table 5.4. Functions that control the CPU's IRQL level.
Interrupt Blocking Function
Function Description
KeRaiseIrql Changes the CPU IRQL to a specified value, blocking interrupts at or below that IRQL level
KeLowerIrql Lowers the CPU IRQL value
KeGetCurrentIrql Returns the IRQL value of the CPU on which this call is made

  • Every piece of code touching a protected (shared) data structure must agree on the IRQL level to use for synchronization. The agreement requires that no code path touch the structure (read or write) unless the IRQL has been raised to the chosen level.

  • If lower-IRQL level code elevates to the agreed upon IRQL level, it should remain there as briefly as possible. Depending on the blocking level, other hardware interrupts could remain blocked for too long unless this rule is followed.

  • While a driver can elevate a code's IRQL level, it should never drop the IRQL level below its original value. Disobeying this rule compromises the entire system interrupt priority mechanism.

Synchronization Using Deferred Procedure Calls

DPCs provide another way to avoid data structure collisions. If all the kernel-mode components using a particular data structure access it only from within a DPC routine, there will be no corruption since DPC routines are always executed serially. The main advantage of using DPCs for synchronization is that they run at a relatively low IRQL.

Another key advantage of DPC routines is that the kernel's DPC Dispatcher automatically handles synchronization in a multi processor (MP) environment. The next section describes what is required to perform manual synchronization among multiple processors.

< 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