void Spin_lock (spinlock_t *lock);
void Spin_lock_irq (spinlock_t *lock);
void Spin_lock_irqsave (spinlock_t *lock, unsigned long flags);
1. Difference between Spin_lock and SPIN_LOCK_IRQ
When using Spin_lock in the Linux kernel, when to use Spin_lock_irqsave is easy to confuse. First look at how the code is implemented.
Spin_lock of the call relationship
Spin_lock
|
+-----> Raw_spin_lock
|
+------> _raw_spin_lock
|
+--------> __raw_spin_lock
Static void __raw_spin_lock (raw_spinlock_t *lock) { preempt_disable (); Spin_acquire (&lock00, _ret_ip_); lock_contended (lock, Do_raw_spin_trylock, Do_raw_spin_lock); }
View Code
Spin_lock_irq of the call relationship
Spin_lock_irq
|
+-------> Raw_spin_lock_irq
|
+---------> _raw_spin_lock_irq
|
+------------> __raw_spin_lock_irq
Static void __RAW_SPIN_LOCK_IRQ (raw_spinlock_t *lock) { local_irq_disable (); Preempt_disable (); Spin_acquire (&lock00, _ret_ip_); lock_contended (lock, Do_raw_spin_trylock, do_raw_spin_lock);
View Code
It can be seen that there is only one difference between them: whether to call the Local_irq_disable () function, or whether to prohibit local interrupts.
It is safe to use SPIN_LOCK_IRQ under any circumstances. Because it prohibits both local interrupts and kernel preemption.
Spin_lock is faster than SPIN_LOCK_IRQ, but it is not always safe under any circumstances.
For example: Process A calls Spin_lock (&lock) and then enters the critical section, where an interrupt (interrupt) occurs,
The interrupt also runs on the same CPU as process A and happens to be spin_lock in the interrupt handler (&lock)
An attempt was made to obtain the same lock. Because it is interrupted on the same CPU, process A is set to the Task_interrupt State,
The interrupt handler fails to get the lock, keeps busy, and so on, because process A is set to the interrupt state, the schedule () process schedule
No more scheduling of process a runs, which results in a deadlock!
However, if the interrupt handler is running on a different CPU, it will not trigger a deadlock. Because an interrupt on a different CPU does not cause
Process A's state is set to Task_interrupt, just swap out. When the interrupt handler is busy waiting to be swapped out, process a still has a chance
Get the CPU, execute and exit the critical section.
So when using Spin_lock, it is clear that the lock will not be used in the interrupt handler.
2. Difference between SPIN_LOCK_IRQ and Spin_lock_irqsave
Spin_lock_irqsave before entering the critical section, save the current interrupt register flag State, off interrupt, enter the critical section, when exiting the critical section, write the saved interrupt state back to the interrupt register.
The SPIN_LOCK_IRQ does not save the interrupt state before entering the critical zone, closes the interrupt, enters the critical section, and interrupts when exiting the critical section.
When the Spin_lock_irqsave lock returns, the interrupt state is not changed and the interrupt is opened before the call Spin_lock_irqsave.
SPIN_LOCK_IRQ lock return, always open interrupt, even if SPIN_LOCK_IRQ before is off interrupt
Transferred from: http://blog.csdn.net/zhanglei4214/article/details/6837697
http://blog.csdn.net/lbo4031/article/details/8894830
Spin_lock, SPIN_LOCK_IRQ, Spin_lock_irqsave difference