local_bh_disable()
将 counter增加preempt_count
一个特定值,也preempt_disable()
将其增加1
. 就是__raw_spin_lock_bh()
这样。
preempt_enable()
函数(从__raw_spin_unlock()
和调用__raw_spin_unlock_irq()
)调用preempt_check_resched()
。但是,当抢占仍然被禁用时,无需尝试安排。它将_local_bh_enable_ip()
在函数退出时在内部完成。
查看源代码可以看到真正的“BH”自旋锁调用序列是:
spin_release(&lock->dep_map, 1, _RET_IP_);
do_raw_spin_unlock(lock);
preempt_enable_no_resched();
\____barrier();
\____dec_preempt_count(); // <--- decrease counter, but we can't schedule here
local_bh_enable_ip();
\____sub_preempt_count() // <--- real disabling preemption
\____preempt_check_resched(); // <--- schedule
但是fe “IRQ”自旋锁调用序列:
spin_release(&lock->dep_map, 1, _RET_IP_);
do_raw_spin_unlock(lock);
local_irq_enable();
preempt_enable();
\____barrier();
\____dec_preempt_count(); // <--- real disabling preemption
\____barrier();
\____preempt_check_resched(); // <--- schedule
总结一下:在 BH-spinlock 的情况下,它只是绕过它,preempt_check_resched()
因为它不是必需的。