4

(来自关于LWN的文章)

 1 rcu_read_lock();
 2 list_for_each_entry_rcu(p, head, list) {
 3   do_something_with(p->a, p->b, p->c);
 4 }
 5 rcu_read_unlock();

RCU 更新操作将执行 synchronize_rcu() 以断言每个 CPU 切换了上下文,因此每个 RCU-reader 都完成了它的工作。但是 RCU 必须依赖于 reader 不被抢占。事实上,LWN 接下来说:

尽管这种简单的方法适用于跨 RCU 读取端临界区禁用抢占的内核,换句话说,对于非 CONFIG_PREEMPT 和 CONFIG_PREEMPT 内核,它不适用于 CONFIG_PREEMPT_RT 实时 (-rt) 内核。

我知道非 CONFIG_PREEMPT 内核禁用了抢占,但为什么CONFIG_PREEMPT内核也可以?

4

2 回答 2

5

在 CONFIG_PREEMPT 内核上是可以的,因为在任务被抢占之前要注意完成 rcu 读取临界区。调度程序检查当前任务是否在 rcu 读取临界区,如果是,则提高其优先级以完成临界区。更多详情请看这篇文章: http: //lwn.net/Articles/220677/

于 2015-08-28T17:40:41.997 回答
1

我们需要用于 CONFIG_PREEMPT 内核的 RCU。如果没有抢占或阻塞,那么我们就不会陷入这种同步混乱。有两种类型的 RCU 实现:

1) Non-preemptible RCU implementation
2) Preemptible RCU implementation

当在一个 CPU 上调用 synchronize_rcu() 而其他 CPU 在 RCU 读取端临界区内时,则 synchronize_rcu() 保证会阻塞,直到所有其他 CPU 退出其临界区。类似地,如果在一个 CPU 上调用 call_rcu() 而其他 CPU 在 RCU 读取端临界区中,则相应 RCU 回调的调用将延迟到所有其他 CPU 退出其临界区之后。

在非抢占式 RCU 实现中,在 RCU 读取端临界区中阻塞是非法的。在 CONFIG_PREEMPT 内核构建中的抢占式 RCU 实现 (PREEMPT_RCU) 中,RCU 读取端临界区可能被抢占,但显式阻塞是非法的。最后,在实时(使用 -rt 补丁集)内核构建中的抢占式 RCU 实现中,RCU 读取端临界区可能被抢占并且它们也可能阻塞,但仅在获取受优先级继承影响的自旋锁时。

于 2015-08-28T09:22:39.007 回答