In any Windows multiprocessor platform, the following conditions hold:
The NT-based operating system is designed to run uniformly on uniprocessor and symmetric multiprocessor platforms, and kernel-mode drivers should be designed to do likewise.
To run safely on a symmetric multiprocessor (SMP) platform, any operating system must solve this problem: how to guarantee that code executing on one processor does not simultaneously access and modify data that is being accessed and modified from another processor. For example, a lowest-level driver's ISR that is handling a device interrupt on one processor must have exclusive access to critical, driver-defined data (or the device registers) in case its device interrupts simultaneously on another processor.
Furthermore, drivers' I/O operations that are serialized in a uniprocessor machine can be overlapped in an SMP machine. That is, a driver's routine that processes incoming I/O requests can be executing on one processor while another routine that communicates with the device executes concurrently on another processor. Whether they are running on a uniprocessor or symmetric multiprocessor machine, this situation requires all kernel-mode drivers, including WDM drivers, to synchronize access to any driver-defined data or system-provided resources that are shared among driver routines and to synchronize access to the physical device, if any.
The NT Kernel component exports a mechanism, called a spin lock, that is used to protect shared data (or device registers) from simultaneous access by one or more routines running concurrently on a symmetric multiprocessor platform. The Kernel enforces two policies regarding the use of spin locks:
These policies prevent a driver routine that usually runs at a lower IRQL but is currently holding a spin lock from being preempted by a higher priority driver routine that is trying to acquire the same spin lock, thereby causing a deadlock.
The IRQL assigned to a spin lock is generally that of the highest-IRQL routine that can acquire the spin lock. For example, a lowest-level driver's ISR frequently shares a state area with the driver's DPC routine, which calls a driver-supplied critical-section routine to access the shared area. In this case, the spin lock protecting the shared area has an IRQL equal to the DIRQL at which the device interrupts. While the critical-section routine holds the spin lock and accesses the shared area at DIRQL, the ISR cannot be run in a uniprocessor machine because the device interrupt is masked off, as mentioned in Always Preemptible and Always Interruptible. And in a symmetric multiprocessor machine, the ISR still cannot acquire the spin lock protecting the shared data while the critical-section routine holds the spin lock and accesses the shared data at DIRQL.
A set of kernel-mode threads can synchronize access to shared data or resources by waiting on one of the Kernel's dispatcher objects: an event, mutex, semaphore, timer, or another thread. However, most drivers do not set up their own threads because they have better performance when they avoid thread-context switches. Time-critical kernel-mode support routines and drivers must use the Kernel's spin locks to synchronize access to shared data or resources whenever they run at IRQL = DISPATCH_LEVEL or at DIRQL.
For more information, see Spin Locks, Managing Hardware Priorities, and Kernel Dispatcher Objects.