【问题标题】:Is it necessary invoke rcu_read_lock in softirq context是否有必要在 softirq 上下文中调用 rcu_read_lock
【发布时间】:2014-01-22 16:04:08
【问题描述】:

rcu_read_lock 的实现是禁用抢占和屏障。并且 softirq 上下文不会被抢占。 那么是否有必要在 softirq 上下文中调用 rcu_read_lock。屏障重要吗?

【问题讨论】:

    标签: linux kernel rcu


    【解决方案1】:

    是的,必须使用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 警告。

    【讨论】:

      【解决方案2】:

      rcu_read_lock 是为了保护一些内核资源被同时修改而导致竞争条件错误。

      资源必须防止的是:被两个软件任务/上下文同时使用和修改。

      在 Linux 中,同时修改可能发生在以下任一环境中:

      1. 从任务到任务的上下文切换,
      2. 上下文从任务切换到 IRQ 上下文
      3. 从不同 VCPU 内核中的任务并发访问

      单核 CPU 环境中的事件,1) 和 2) 可能仍会发生。 在修改关键资源的任务上,软件 IRQ 引发,进入软件 IRQ 上下文,运行 IRQ 处理程序并同时修改相同的资源。

      【讨论】:

      • 但是softirq并没有被其他softirq和正常任务抢占。
      • 如果资源可以被并发访问,需要加锁保护。例如,一个线程正在修改一个资源并且资源处于准状态,软件 irq 进入并修改该资源会导致竞争条件。
      • 另外,可能有多个 VCPU 同时运行软件 irq 和任务。如果该资源不仅被软件中断访问,则应保护它不被同时访问。
      • 但我的问题是 rcu_read_lock 在 softirq 上下文中是必需的吗?因为 rcu_read_lock 只实现了 preempt_disable。
      • 哦,我错过了这部分。如果从下半部分读取资源,则必须使用 MACRO: rcu_read_lock_bh。此宏禁用线程和下半部分的抢占。
      【解决方案3】:

      最好在 softirq 上下文中调用 rcu_read_lock 以用于文档目的,这样您和其他开发人员就知道 RCU 此处使用受保护的数据。

      【讨论】:

        猜你喜欢
        • 2018-06-18
        • 2013-01-21
        • 2012-11-07
        • 1970-01-01
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        相关资源
        最近更新 更多