4pie0
4pie0

Reputation: 29724

How RCU reader section is protected from preemption?

(From an article on 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();

The RCU update operation will do synchronize_rcu() in order to assert each CPU switched the context and therefore each RCU-reader has completed it's job. But RCU must rely on reader not being preempted. And indeed, LWN says next:

Although this simple approach works for kernels in which preemption is disabled across RCU read-side critical sections, in other words, for non-CONFIG_PREEMPT and CONFIG_PREEMPT kernels, it does not work for CONFIG_PREEMPT_RT realtime (-rt) kernels.

I understand preemption is disabled for non-CONFIG_PREEMPT kernels, but why is it OK for CONFIG_PREEMPT kernels too?

Upvotes: 4

Views: 1187

Answers (2)

pranith
pranith

Reputation: 879

It is OK on CONFIG_PREEMPT kernels since care is taken to finish the rcu read critical section before the task is preempted. The scheduler checks if the current task is in a rcu read critical section and if so, it boosts its priority so that it finishes the critical section. For more details see this article: http://lwn.net/Articles/220677/

Upvotes: 5

skaushal
skaushal

Reputation: 705

We need RCU for CONFIG_PREEMPT kernels. If there was no pre-emption or blocking then we wouldn't in this synchronization mess. There are two types of RCU implementations:

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

When synchronize_rcu() is invoked on one CPU while other CPUs are within RCU read-side critical sections, then the synchronize_rcu() is guaranteed to block until after all the other CPUs exit their critical sections. Similarly, if call_rcu() is invoked on one CPU while other CPUs are within RCU read-side critical sections, invocation of the corresponding RCU callback is deferred until after the all the other CPUs exit their critical sections.

In non-preemptible RCU implementations it is illegal to block while in an RCU read-side critical section. In preemptible RCU implementations (PREEMPT_RCU) in CONFIG_PREEMPT kernel builds, RCU read-side critical sections may be preempted, but explicit blocking is illegal. Finally, in preemptible RCU implementations in real-time (with -rt patchset) kernel builds, RCU read-side critical sections may be preempted and they may also block, but only when acquiring spinlocks that are subject to priority inheritance.

Upvotes: 1

Related Questions