【发布时间】:2014-01-22 16:04:08
【问题描述】:
rcu_read_lock 的实现是禁用抢占和屏障。并且 softirq 上下文不会被抢占。 那么是否有必要在 softirq 上下文中调用 rcu_read_lock。屏障重要吗?
【问题讨论】:
rcu_read_lock 的实现是禁用抢占和屏障。并且 softirq 上下文不会被抢占。 那么是否有必要在 softirq 上下文中调用 rcu_read_lock。屏障重要吗?
【问题讨论】:
是的,必须使用rcu_read_lock 来访问受 rcu 保护的指针,即使在 softirq 上下文中也是如此。
正如您所指出的,rcu_read_lock 和 softirqs 的一些实现(例如:TINY_RCU)使得即使您不使用rcu_read_lock 分隔 rcu 读取端临界区也不会存在损坏风险。但是,这并不是 rcu api 的保证,只是因为具体实现而导致的“hack”。这种 hack 可能会因 rcu 的不同实现而中断(例如:PREEMPT_RCU)。
如果您希望将软中断视为显式 rcu 读取端临界区,则必须使用 RCU-sched api: Documentation/RCU/whatisRCU.txt
RCU 主要作者撰写的文章的以下部分直接解决了您的问题: Requirements for RCU part 1: the fundamentals - Disabling preemption does not block grace periods
如果 CONFIG_PROVE_RCU=y,我会添加在 rcu_read_lock 之外执行 rcu_dereference 的代码将触发 lockdep 警告。
【讨论】:
rcu_read_lock 是为了保护一些内核资源被同时修改而导致竞争条件错误。
资源必须防止的是:被两个软件任务/上下文同时使用和修改。
在 Linux 中,同时修改可能发生在以下任一环境中:
单核 CPU 环境中的事件,1) 和 2) 可能仍会发生。 在修改关键资源的任务上,软件 IRQ 引发,进入软件 IRQ 上下文,运行 IRQ 处理程序并同时修改相同的资源。
【讨论】:
最好在 softirq 上下文中调用 rcu_read_lock 以用于文档目的,这样您和其他开发人员就知道 RCU
此处使用受保护的数据。
【讨论】: