Linux spin_lock vs NT KeAcquireSpinLock

From what I can assemble:

  • NT KeAcquireSpinLock equivalent to spin_lock_bh : one raises IRQL to DISPATCH_LEVEL, the other masks the bottom half interrupts - functionally the same. Although the NT variant preserves OldIrql, the Linux variant does not seem to store "areInterruptsAlreadyMasked" anywhere. Does this mean that spin_unlock_bh always disguises them?
  • NT KeAcquireInterruptSpinLock is similar to spin_lock_irqsave .

What is the NT equivalent of spin_lock ?

If spin_unlock_bh always spin_unlock_bh interrupts (in NT-talk, IRQL always falls to <DISPATCH_LEVEL), does this mean that spin_lock akin to KeAcquireSpinLockAtDpcLevel ?

+6
source share
1 answer

A raw spin_lock can be used when you don't know that interrupts or lower halves will never fight for a lock. By avoiding masking interrupts, you retain the interrupt delay, but still avoid the overhead of the mutex for critical sections short enough to turn on.

In practice, they are apparently mostly used by things like file system drivers to lock internal cache structures and other things where you never need to block IO when locking. Since the back halves and driver interrupts never touch the FS driver directly, there is no need to mask interrupts.

I suspect that the Windows equivalent will be CRITICAL_SECTION , or whatever the equivalent of the NT kernel API; however, unlike the critical NT partition, Linux Linux locks do not return to the mutex when it is approved; they just keep spinning.

And, yes, spin_unlock_bh unconditionally restores the lower halves. You can either keep track of when to enable / disable manually (since you should generally issue locks in the opposite order of acquisition, this is usually not a problem) or simply resort to spin_lock_irqsave .

+2
source

Source: https://habr.com/ru/post/899345/


All Articles