C语言 为什么spin_unlock_bh函数在不调用调度程序的情况下启用抢占



我正在研究内核代码(版本 3.10.1(的自旋锁代码,但有一件事不明白。

当通过函数spin_lock_bh()获取自旋锁时,它会继续调用preempt_disable()。这与用于获取(例如spin_lock()spin_lock_irq()(的其他自旋锁函数相同。

但是当通过spin_unlock_bh()释放锁时,它会调用preempt_enable_no_resched(),这会跳过调用调度程序抢占。 其他相应的发布功能(如spin_unlock()spin_unlock_irq()(并非如此。它们调用调用__schedule()的常规preempt_enable()函数。

local_bh_disable()

按特定值递增计数器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

f.e. "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自旋锁的情况下,它只是绕过preempt_check_resched()因为它不是必需的。

相关内容

  • 没有找到相关文章

最新更新