(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?
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/