-functionlocal_bh_disable
改变每个 cpu(在 x86 和最近的内核的情况下)__preempt_count
或current_thread_info()->preempt_count
其他。
无论如何,这给了我们一个宽限期,所以我们可以假设在rcu_read_lock()
里面做是多余的local_bh_disable()
。确实:在早期的内核中,我们可以看到它local_bh_disable()
用于 RCU,rcu_dereference()
随后在例如dev_queue_xmit
-function 内部被调用。后来local_bh_disable()
被替换为rcu_read_lock_bh()
,最终变得比调用更复杂一些local_bh_disable()
。现在看起来像这样:
static inline void rcu_read_lock_bh(void)
{
local_bh_disable();
__acquire(RCU_BH);
rcu_lock_acquire(&rcu_bh_lock_map);
RCU_LOCKDEP_WARN(!rcu_is_watching(),"rcu_read_lock_bh() used illegally while idle");
}
还有足够多的文章描述 RCU API。在这里我们可以看到:
您是否需要将 NMI 处理程序、hardirq 处理程序和禁用抢占的代码段(无论是通过 preempt_disable()、local_irq_save()、local_bh_disable() 还是其他机制)视为显式 RCU 读取器?如果是这样,RCU-sched 是唯一适合您的选择。
这告诉我们在这种情况下使用RCU Sched API,所以rcu_dereference_sched()
应该有所帮助。从这个综合表中我们可以意识到rcu_dereference()
应该只在rcu_read_lock
/ rcu_read_unlock
-markers 内部使用。
但是,还不够清楚。我可以在/ -markersrcu_dereference()
内部使用(在现代内核的情况下)而不担心会出现任何问题吗?local_bh_disable
local_bh_enable
PS 在我的情况下,我无法更改local_bh_disable
调用 eg的代码rcu_read_lock_bh
,因此我的代码在 bh 已禁用的情况下运行。还使用了通常的 RCU API。因此,它充满了rcu_read_lock
嵌套在local_bh_disable
.