嵌入式 Linux内核spin_lock与spin_lock_irq以及spin_lock_irqsave分析

原创 2013年12月03日 16:41:06

如果自旋锁在中断处理函数中被用到,那么在获取该锁之前需要关闭本地中断,spin_lock_irqsave 只是下列动作的一个便利接口:
1 保存本地中断状态
2 关闭本地中断
3 获取自旋锁

解锁时通过 spin_unlock_irqrestore完成释放锁、恢复本地中断到之前的状态等工作

还有一对 spin_lock_irq 和 spin_unlock_irq
如果你确定在获取锁之前本地中断是开启的,那么就不需要保存中断状态,解锁的时候直接将本地中断启用就可以啦

在Linux内核中何时使用spin_lock,何时使用spin_lock_irqsave很容易混淆。首先看一下代码是如何实现的。

spin_lock的调用关系

     spin_lock

            |

           + ----->  raw_spin_lock

|

+------>  _raw_spin_lock

                         |

                        +--------> __raw_spin_lock

[cpp] view plaincopyprint?
  1. staticinline void __raw_spin_lock(raw_spinlock_t *lock) 
  2.         preempt_disable(); 
  3.         spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); 
  4.         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); 

spin_lock_irq的调用关系

    spin_lock_irq

                |

               +-------> raw_spin_lock_irq

                                           |

                                          +---------> _raw_spin_lock_irq

                                                                      |

                                                                      +------------> __raw_spin_lock_irq

[cpp] view plaincopyprint?
  1. staticinline void __raw_spin_lock_irq(raw_spinlock_t *lock) 
  2.         local_irq_disable(); 
  3.         preempt_disable(); 
  4.         spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); 
  5.         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); 

可以看出来他们两者只有一个差别:是否调用local_irq_disable()函数, 即是否禁止本地中断。

在任何情况下使用spin_lock_irq都是安全的。因为它既禁止本地中断,又禁止内核抢占。

spin_lock比spin_lock_irq速度快,但是它并不是任何情况下都是安全的。

举个例子:进程A中调用了spin_lock(&lock)然后进入临界区,此时来了一个中断(interrupt),

该中断也运行在和进程A相同的CPU上,并且在该中断处理程序中恰巧也会spin_lock(&lock)

试图获取同一个锁。由于是在同一个CPU上被中断,进程A会被设置为TASK_INTERRUPT状态,

中断处理程序无法获得锁,会不停的忙等,由于进程A被设置为中断状态,schedule()进程调度就

无法再调度进程A运行,这样就导致了死锁!

但是如果该中断处理程序运行在不同的CPU上就不会触发死锁。 因为在不同的CPU上出现中断不会导致

进程A的状态被设为TASK_INTERRUPT,只是换出。当中断处理程序忙等被换出后,进程A还是有机会

获得CPU,执行并退出临界区。

所以在使用spin_lock时要明确知道该锁不会在中断处理程序中使用。

相关文章推荐

linux内核spin_lock分析

今天我们详细了解一下spin_lock在内核中代码实现,我们总共分析四个项目:   1.spinlock_t的定义分析: 首先来看一下spinlock_t的定义: typede...

Linux内核-spin_lock()

spin_lock()在Linux2.6中,spin_lock()宏有两种实现方式,一种是具有内核抢占的spin_lock(),一种是非抢占式内核中的spin_lock(),下面先看下自旋锁的数据结构...
  • Jay14
  • Jay14
  • 2017年02月15日 20:43
  • 147

Linux内核同步机制之(四):spin lock

copy from: http://www.wowotech.net/kernel_synchronization/spinlock.html/comment-page-2#comments作者:li...

Linux内核同步机制API函数:宏:spin_lock_init ( )

宏定义:       在内核源码中的位置:linux-2.6.30/include/linux/spinlock.h 宏定义格式:# define spin_lock_init(lock)    ...
  • dyzok88
  • dyzok88
  • 2014年12月22日 17:18
  • 2924

Linux内核同步机制API函数:宏:spin_lock_init ( )

宏定义:       在内核源码中的位置:linux-2.6.30/include/linux/spinlock.h 宏定义格式:# define spin_lock_init(lock)...

Linux内核spin_lock与spin_lock_irq分析

本文摘自:http://blog.csdn.net/zhanglei4214/article/details/6837697 感谢该朋友对内核锁的的深度分析  在Linux内核中何时使...

Linux内核spin_lock与spin_lock_irq分析

在Linux内核中何时使用spin_lock,何时使用spin_lock_irqsave很容易混淆。首先看一下代码是如何实现的。 spin_lock的调用关系      spin_lock...

spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗?

spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗? static inline unsigned long __raw_spin_lock_irqsave(raw_spin...

内核自旋锁spin_lock

自旋锁的初衷:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁不应该被持有时间过长。如果需要长时间锁定的话, 最好使用信号...

转帖--关于spin_lock-(居然首次关注内核执行路径,惭愧)

关于spin_lock需要澄清的是,互斥手段的选择,不是根据临界区的大小,而是根据临界区的性质,以及 有哪些部分的代码,即哪些内核执行路径来争夺。 从严格意义上说,semaphore和spinlock...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:嵌入式 Linux内核spin_lock与spin_lock_irq以及spin_lock_irqsave分析
举报原因:
原因补充:

(最多只允许输入30个字)