linux-kernelspinlock

spin_lock_irqsave vs spin_lock_irq


On an SMP machine we must use spin_lock_irqsave and not spin_lock_irq from interrupt context.

Why would we want to save the flags (which contain the IF)?

Is there another interrupt routine that could interrupt us?


Solution

  • If interrupts are already disabled before your code starts locking, when you call spin_unlock_irq you will forcibly re-enable interrupts in a potentially unwanted manner. If instead you also save the current interrupt enable state in flags through spin_lock_irqsave, attempting to re-enable interrupts with the same flags after releasing the lock, the function will just restore the previous state (thus not necessarily enabling interrupts).

    Example with spin_lock_irqsave:

    spinlock_t mLock = SPIN_LOCK_UNLOCK;
    unsigned long flags;
    
    spin_lock_irqsave(&mLock, flags); // Save the state of interrupt enable in flags and then disable interrupts
    // Critical section
    spin_unlock_irqrestore(&mLock, flags); // Return to the previous state saved in flags
    

    Example with spin_lock_irq( without irqsave ):

    spinlock_t mLock = SPIN_LOCK_UNLOCK;
    unsigned long flags;
    
    spin_lock_irq(&mLock); // Does not know if interrupts are already disabled
    // Critical section
    spin_unlock_irq(&mLock); // Could result in an unwanted interrupt re-enable...