[英]Is it safe to use rcu_dereference() inside local_bh_disable()/local_bh_enable()?
local_bh_disable
-function更改per-cpu(如果是x86和最近的内核) __preempt_count
或current_thread_info()->preempt_count
否则。
无论如何,这给了我们宽限期,所以我们可以假设在local_bh_disable()
执行rcu_read_lock()
是多余的。 确实: 在早期的内核中,我们可以看到 local_bh_disable()
用于RCU, rcu_dereference()
随后在例如dev_queue_xmit
rcu_dereference()
中被dev_queue_xmit
。 后来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中使用。
但是,它还不够清楚。 我可以在local_bh_disable
/ local_bh_enable
-markers中使用(在现代内核的情况下) rcu_dereference()
而不会出现任何错误吗?
PS在我的情况下,我无法更改调用local_bh_disable
的代码来调用例如rcu_read_lock_bh
,所以我的代码运行已经禁用了bh。 还使用通常的RCU API。 因此,它充满了嵌套在local_bh_disable
rcu_read_lock
。
您不应该混合使用API。 如果需要使用RCU-bh API,则需要使用rcu_dereference_bh
。
你可以看到,如果你在rcu_read_lock_bh
之后调用了rcu_dereference_check
,它会正确推测它不会在RCU读取端关键部分调用 ; lock_is_held(&rcu_lock_map)
的调用与lock_is_held(&rcu_lock_map)
进行rcu_lock_acquire(&rcu_bh_lock_map);
在上面的代码段中。
对于RCU内核文件在这里 (搜索的“rcu_dereference()”一节)给出了正确用法的一个明显的例子; rcu_dereference*
只能在相应的rcu_read_lock*
函数完成后才能正确调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.