Synchronizing Multiple CPUs

< BACK  NEXT >
[oR]

Modifying the IRQL of one CPU has no effect on other CPUs and multiprocessor systems. Consequently, IRQLs provide only local CPU protection to share data. To prevent corruption of data structures in a multiprocessor environment, Windows 2000 uses synchronization objects called spin locks.

How Spin Locks Work

A spin lock is simply a mutual-exclusion object that is associated with a specific group of data structures. When a piece of kernel-mode code wants to touch any of the guarded data structures, it must first request ownership of the associated spin lock. Since only one CPU at a time can own the spin lock, the data structure is safe from contamination. Any CPU requesting an already-owned spin lock will busy-wait until the spin lock becomes available. Figure 5. 2 illustrates the process.

Figure 5.2. Spin locks.
graphics/05fig02.gif

A given spin lock is always acquired and released at a specific IRQL level. This has the effect of blocking dangerous interrupts on the local CPU and preventing the synchronization problems described earlier. While a CPU is waiting for a spin lock, all activity at or below the IRQL of the spin lock is blocked on that CPU. Both steps are essential elevate the IRQL level and acquire the spin lock.

Using Spin Locks

There are two major kinds of spin locks provided by the kernel. They are distinguished by the IRQL level at which they are used.

  • Interrupt spin locks.

    These synchronize and provide access to driver data structures shared by multiple-driver routines. Interrupt spin locks are acquired at the DIRQL associated with the device.

  • Executive spin locks.

    These guard various operating system data structures, and their associated IRQL is DISPATCH_LEVEL.

When a driver uses Interrupt spin locks, operation is straightforward. The function KeSynchronizeExecution is described in chapter 8.

Executive spin locks are more complicated to work with. The following steps must be followed when using Executive spin locks:

  1. Decide what data items must be guarded and how many spin locks should be used. Additional spin locks allow finer granularity of access to the data. However, the possibility of deadlock is present whenever acquisition of more than one spin lock at a time is required.

  2. Reserve space for a data structure of type KSPIN_LOCK for each lock. Storage for the spin lock must be in nonpaged pool. Usually, the spin lock is declared in the device or controller extension.

  3. Initialize the spin lock once by calling KeInitializeSpinLock. This function can be called from any IRQL level, though it is most commonly used from the DriverEntry routine.

  4. Call KeAcquireSpinLock before touching any resource guarded by a spin lock. This function raises IRQL to DISPATCH_LEVEL, acquires the spin lock, and returns the previous IRQL value. This function must be called at or below DISPATCH_LEVEL IRQL. If the code is already at DISPATCH_LEVEL, a more efficient call is KeAcquireSpinLockFromDpcLevel.

  5. When access to the resource is complete, use the KeReleaseSpinLock function to free the lock. This function is called from DISPATCH_LEVEL IRQL and it restores IRQL to its original value. If the original level was known to be DISPATCH_LEVEL, a more efficient call would be KeReleaseSpinLockFromDpcLevel, which releases the lock without changing IRQL.

Some driver support routines (like the interlock lists and queues described in the next section) use Executive spin locks for protection. In these cases, the only requirement is that the spin lock object be initialized. The driver support routines that manage the interlocked object will acquire and release the spin lock on the driver's behalf.

Rules for Using Spin Locks

Spin locks aren't terribly difficult to use, but there are a few rules that should be followed.

  • Be sure to release a spin lock as soon as possible because while holding it, other CPU activity may be blocked. The official DDK recommendation is not to hold a spin lock for more than about 25 microseconds.

  • Don't cause any hardware or software exceptions while holding the spin lock. This is a guaranteed system crash.

  • Don't access any page code or data while holding the spin lock. This may result in a page fault exception.

  • Don't try to acquire a spin lock the CPU already owns. This leads to a deadlock situation since the CPU freezes up, waiting for itself to release the spin lock.

  • Avoid driver designs that depend on holding multiple spin locks simultaneously. Without careful design, this can lead to a deadly embrace condition. If multiple spin locks must be used, ensure that all code paths agree to acquire them in a fixed order and release them in the exact reverse order.

< 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