RCU 概念

RCU(读取-复制更新)背后的基本思想是将破坏性操作分为两部分:一部分阻止任何人看到正在被破坏的数据项,另一部分实际执行破坏。这两部分之间必须经过一个“宽限期”,并且这个宽限期必须足够长,以确保访问被删除项的任何读取者都已经放弃了他们的引用。 例如,从链接列表中受 RCU 保护的删除将首先从列表中删除该项,等待宽限期过去,然后释放该元素。 有关将 RCU 与链接列表一起使用的更多信息,请参见 使用 RCU 保护主要为读取操作的链接列表

常见问题解答

  • 为什么有人想使用 RCU?

    RCU 的两部分方法的优点是,RCU 读取者无需获取任何锁,执行任何原子指令,写入共享内存,或者(在 Alpha 以外的 CPU 上)执行任何内存屏障。 事实上,这些操作在现代 CPU 上非常昂贵,这正是 RCU 在主要为读取操作的情况下具有性能优势的原因。 RCU 读取者无需获取锁的事实还可以大大简化避免死锁的代码。

  • 如果 RCU 读取者没有指示他们何时完成,那么更新者如何知道宽限期何时完成?

    与自旋锁一样,RCU 读取者不允许阻塞、切换到用户模式执行或进入空闲循环。 因此,一旦看到 CPU 正在经历这三种状态中的任何一种,我们就知道该 CPU 已经退出了任何先前的 RCU 读取端关键区域。 因此,如果我们从链接列表中删除一个项目,然后等待所有 CPU 切换上下文、在用户模式下执行或在空闲循环中执行,我们可以安全地释放该项目。

    RCU 的可抢占变体 (CONFIG_PREEMPT_RCU) 具有相同的效果,但要求读取者操作 CPU 本地计数器。 这些计数器允许在 RCU 读取端关键区域内进行有限类型的阻塞。 SRCU 也使用 CPU 本地计数器,并允许在 RCU 读取端关键区域内进行一般阻塞。 RCU 的这些变体通过采样这些计数器来检测宽限期。

  • 如果我在单处理器内核上运行,它一次只能做一件事,为什么我应该等待宽限期?

    有关更多信息,请参见 单处理器系统上的 RCU

  • 我如何查看 RCU 当前在 Linux 内核中的使用位置?

    搜索“rcu_read_lock”、“rcu_read_unlock”、“call_rcu”、“rcu_read_lock_bh”、“rcu_read_unlock_bh”、“srcu_read_lock”、“srcu_read_unlock”、“synchronize_rcu”、“synchronize_net”、“synchronize_srcu”和其他 RCU 原语。 或者从以下位置获取 cscope 数据库之一

    (http://www.rdrop.com/users/paulmck/RCU/linuxusage/rculocktab.html)。

  • 编写使用 RCU 的代码时,我应该遵循哪些准则?

    参见 RCU 补丁的审查清单

  • 为什么命名为“RCU”?

    “RCU”代表“读取-复制更新”。 使用 RCU 保护主要为读取操作的链接列表 有关此名称来源的更多信息,搜索“read-copy update”即可找到。

  • 我听说 RCU 有专利? 那是什么情况?

    是的,它是。 有几个与 RCU 相关的已知专利,请在 Documentation/RCU/RTFP.txt 中搜索字符串“Patent”以找到它们。 其中,一项已被受让人放弃,其他已被贡献给 GPL 下的 Linux 内核。 许多(但不是全部)早已过期。 现在还有用户级 RCU 的 LGPL 实现可用 (https://liburcu.org/)。

  • 我听说 RCU 需要进行一些工作才能支持实时内核?

    通过 CONFIG_PREEMPTION 内核配置参数启用对实时友好的 RCU。

  • 在哪里可以找到有关 RCU 的更多信息?

    参见 Documentation/RCU/RTFP.txt 文件。 或者将您的浏览器指向 (https://docs.google.com/document/d/1X0lThx8OK0ZgLMqVoXiR4ZrGURHrXK6NyLRbeXe3Xac/edit) 或 (https://docs.google.com/document/d/1GCdQC8SDbb54W1shjEXqGZ0Rq8a6kIeYutdSIajfpLA/edit?usp=sharing)。