繁体   English   中英

在local_bh_disable()/ local_bh_enable()中使用rcu_dereference()是否安全?

[英]Is it safe to use rcu_dereference() inside local_bh_disable()/local_bh_enable()?

local_bh_disable -function更改per-cpu(如果是x86和最近的内核) __preempt_countcurrent_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM