rcu_read_lock 的实现是禁用抢占和屏障。并且 softirq 上下文不会被抢占。那么是否有必要在 softirq 上下文中调用 rcu_read_lock。屏障重要吗?
3 回答
是的,有必要使用它rcu_read_lock
来访问受 rcu 保护的指针,即使在 softirq 上下文中也是如此。
正如您所指出的,一些实现(例如:TINY_RCU)rcu_read_lock
和 softirqs 使得即使您不使用rcu_read_lock
. 但是,这并不是 rcu api 的保证,只是因为具体实现而导致的“hack”。这种 hack 可能会因 rcu 的不同实现而中断(例如:PREEMPT_RCU)。
如果您希望将软中断视为显式 rcu 读取端临界区,则必须使用 RCU-sched api: Documentation/RCU/whatisRCU.txt
RCU 的主要作者撰写的文章的以下部分直接解决了您的问题: RCU 第 1 部分的要求:基础 - 禁用抢占不会阻止宽限期
如果 CONFIG_PROVE_RCU=y ,我将添加在rcu_dereference
外部执行的代码rcu_read_lock
将触发 lockdep 警告。
rcu_read_lock 是为了保护一些内核资源被同时修改而导致竞争条件错误。
资源必须防止的是:同时被两个软件任务/上下文使用和修改。
在 Linux 中,同时修改可能发生在以下任一情况下:
- 从任务到任务的上下文切换,
- 从任务到 IRQ 上下文的上下文切换
- 从不同 VCPU 内核中的任务并发访问
事件在单核 CPU 环境中,1) 和 2) 可能仍会发生。在修改关键资源的任务上,软件 IRQ 引发,进入软件 IRQ 上下文,运行 IRQ 处理程序并同时修改相同的资源。
rcu_read_lock
出于文档目的在上下文中调用是个好主意softirq
,这样您和其他开发人员就知道这里使用了 RCU 保护的数据。