16.2.5 Preventing Errors or Deadlocks While Using Spin Locks

When an NT driver routine holds a spin lock, it cannot cause a hardware exception or raise a software exception without bringing down the system. In other words, an NT driver’s ISR and any SynchCritSection routine that the driver supplies in a call to KeSynchronizeExecution must not cause a fault or trap, such as a page fault or an arithmetic exception, and cannot raise a software exception. A routine that calls KeAcquireSpinLock also cannot cause a hardware exception or raise a software exception until it has released its executive spin lock and is no longer running at IRQL DISPATCH_LEVEL.

Pageable Data and Support Routines

NT drivers must not call routines that access pageable data while holding a spin lock. Drivers can call certain support routines that access pageable data if and only if their calls occur while executing at an IRQL strictly less than DISPATCH_LEVEL. Note that this IRQL restriction precludes calling such a support routine while holding a spin lock.

Recursion

Attempting to acquire a spin lock recursively is guaranteed to cause a deadlock: the holding instantiation of a recursive routine cannot release the spin lock while a second instantiation spins, trying to acquire the same spin lock.

    NT driver writers who implement a recursive routine should follow these guidelines concerning spin lock usage:

For more information about recursive driver routines, see also Section 16.4.2.

Nested Spin Lock Acquisitions

Attempting to acquire a second spin lock while holding another spin lock also can cause deadlocks or poor driver performance.

    NT driver writers should follow these implementation guidelines in drivers holding a spin lock:

In general, NT driver writers should avoid using nested spin locks to protect overlapping subsets or discrete sets of shared data and resources. Consider what can happen if a driver uses two executive spin locks to protect discrete resources, such as a pair of timer objects that might be set individually and collectively by various driver routines. Such a driver would deadlock intermittently in an SMP machine, whenever either of two routines, each holding one spin lock, tried to acquire the other spin lock.

Even if a deadlock-proof driver can be designed to use nested spin locks, it could be difficult to implement successfully. Nested spin locks are very difficult to debug and to test adequately in a Windows NT SMP machine. Moreover, using nested spin locks can degrade both driver and system performance severely.