spin_lock_bh()与spin_unlock_bh()

spin_lock_bh通常用在进程中,用来禁止抢断和禁止软中断。

 

spin_lock_bh()中首先会调用local_bh_disable()禁止当前CPU的软件中断。而函数spin_unlock_bh()则调用local_bh_enable()来势能本地CPU的软件中断。在软件中断被禁止的时候,本地CPU的所有软中断都不会被执行。

 

如果一个softirq 与 用户上下文共享数据,就有两个问题:首先,当前的用户上下文可能被softirq中断;其次,临界区可能会在别的CPU进入。这时spin_lock_bh()(include/linux/spinlock.h)就有了用武之地。它会在那个CPU上禁止softirqs,然后获
取锁。spin_unlock_bh()做相反的工作。(由于历史原因,后缀‘bh’成为对各种下半部的通称,后者是software interrupts的旧称。其实spin_lock_bh本应叫作spin_lock_softirq才贴切),注意这里你也可以用spin_lock_irq()或者spin_lock_irqsave(),这样不单会禁止softirqs,还会禁止硬件中断。

tasklets 和timer其实是一种softirq,从加锁观点来看,tasklets和timers的地位是等同的。

 

硬中断通常与一个tasklet或softirq通信。这通常涉及到把一个任务放到某个队列中,再由softirq取出来。如果一个硬件中断服务例程与一个softirq共享数据,就有两点需要考虑。第一,softirq的执行过程可能会被硬件中断打断;第二,临界区可能会被另一个CPU上的硬件中断进入。这正是spin_lock_irq()派上用场的地方。它在那个CPU上禁止中断,然后获取锁。spin_unlock_irq()做相反的工作。


硬件中断服务例程中不需要使用spin_lock_irq(),因为当它在执行的时候softirq是不可能执行的:它可以使用spin_lock(),这个会更快一些。唯一的例外是另一个硬件中断服务例程使用了相同的锁:spin_lock_irq()会禁止那个硬件中断。

你可能感兴趣的:(linux内核)