linux中__rcu代表什么?

问题描述 投票:0回答:2

我是 Linux 内核新手。我的问题是关于

task_struct
。 我知道每个
task_struct
通过指向父进程
task_struct
的指针来引用其父进程。

查看

task_struct
定义中的 sched.h 后,我注意到以下内容:

struct task_struct __rcu *real_parent; /* real parent process */

我发现它引用了compiler.h。我猜“__rcu”代表“读取副本更新”

有人可以澄清语法吗?

linux-kernel
2个回答
16
投票

读取-复制-更新是一种算法,允许对数据结构的读取器进行并发访问,而无需锁定该结构。可以在这里阅读。

如果内核是使用

CONFIG_SPARSE_RCU_POINTER
配置选项构建的,则
__rcu
include/linux/compiler.h
中定义为

# define __rcu          __attribute__((noderef, address_space(4)))

这是Sparse代码分析工具的注释,可以警告程序员可能忽略的某些事情。

Documentation/RCU/checklist.txt
中解释了这与 RCU 的关系:

__rcu 稀疏检查:标记指向 RCU 保护数据的指针 具有 __rcu 的结构,并且稀疏会警告您,如果您 无需其中之一的服务即可访问该指针 rcu_dereference() 的变体。

rcu_dereference()
返回一个可以被代码安全取消引用的指针,并记录程序员使用 RCU 机制保护指针的意图,使 Sparse 等工具能够检查编程错误和遗漏。


6
投票

RCU 代表“读取、复制、更新”。它是一种允许多个读者访问可以被作者同时更新甚至删除的数据的算法。

在 RCU 下,写入者仍然必须确保彼此之间的互斥,但读取者不会获取锁。必须注意共享数据结构的更新方式不得违反读取完整性。如果必须删除或删除某些内容,则可以与读取器并行完成该项目与数据结构的链接,但内存的实际删除必须等到最后一个读取器完成。

不是让读者获取锁,而是通过其他方式推断读者的行踪。线程可以通过加入“读端临界区”来宣布它们浏览数据结构的意图,“读端临界区”并不是真正的锁,而是一种全局阶段。

例如,假设某些线程在阶段 0 进入 RCU 读端临界区。更新程序执行了删除操作,想要释放一块内存。它必须简单地等待系统中的所有线程腾出阶段 0。与此同时,其他读取器已经在查看数据结构,但是当他们向 RCU 声明其意图时,他们通过进入 RCU 读取侧关键来实现这一点阶段 1 下的部分。只有阶段 0 线程可能仍然拥有指向已删除对象的指针,因此当最后一个线程离开阶段 0 时,可以安全地删除该对象。第一阶段新到达的线程看不到该对象,因为该对象已从数据结构中删除,因此它们无法找到它。

RCU 利用了这样的想法:我们不需要锁定“拥有”的对象来了解“没有线程可以再访问该对象”之类的信息。

© www.soinside.com 2019 - 2024. All rights reserved.