[PATCH] Update RCU documentation
Update the RCU documentation to allow for the new synchronize_rcu() and
synchronize_sched() primitives. Fix a few other nits as well.
Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index b3a568a..8f3fb77 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -32,7 +32,10 @@
them -- even x86 allows reads to be reordered), and be prepared
to explain why this added complexity is worthwhile. If you
choose #c, be prepared to explain how this single task does not
- become a major bottleneck on big multiprocessor machines.
+ become a major bottleneck on big multiprocessor machines (for
+ example, if the task is updating information relating to itself
+ that other tasks can read, there by definition can be no
+ bottleneck).
2. Do the RCU read-side critical sections make proper use of
rcu_read_lock() and friends? These primitives are needed
@@ -89,27 +92,34 @@
"_rcu()" list-traversal primitives, such as the
list_for_each_entry_rcu().
- b. If the list macros are being used, the list_del_rcu(),
- list_add_tail_rcu(), and list_del_rcu() primitives must
- be used in order to prevent weakly ordered machines from
- misordering structure initialization and pointer planting.
+ b. If the list macros are being used, the list_add_tail_rcu()
+ and list_add_rcu() primitives must be used in order
+ to prevent weakly ordered machines from misordering
+ structure initialization and pointer planting.
Similarly, if the hlist macros are being used, the
- hlist_del_rcu() and hlist_add_head_rcu() primitives
- are required.
+ hlist_add_head_rcu() primitive is required.
- c. Updates must ensure that initialization of a given
+ c. If the list macros are being used, the list_del_rcu()
+ primitive must be used to keep list_del()'s pointer
+ poisoning from inflicting toxic effects on concurrent
+ readers. Similarly, if the hlist macros are being used,
+ the hlist_del_rcu() primitive is required.
+
+ The list_replace_rcu() primitive may be used to
+ replace an old structure with a new one in an
+ RCU-protected list.
+
+ d. Updates must ensure that initialization of a given
structure happens before pointers to that structure are
publicized. Use the rcu_assign_pointer() primitive
when publicizing a pointer to a structure that can
be traversed by an RCU read-side critical section.
- [The rcu_assign_pointer() primitive is in process.]
-
5. If call_rcu(), or a related primitive such as call_rcu_bh(),
is used, the callback function must be written to be called
from softirq context. In particular, it cannot block.
-6. Since synchronize_kernel() blocks, it cannot be called from
+6. Since synchronize_rcu() can block, it cannot be called from
any sort of irq context.
7. If the updater uses call_rcu(), then the corresponding readers
@@ -125,9 +135,9 @@
such cases is a must, of course! And the jury is still out on
whether the increased speed is worth it.
-8. Although synchronize_kernel() is a bit slower than is call_rcu(),
+8. Although synchronize_rcu() is a bit slower than is call_rcu(),
it usually results in simpler code. So, unless update performance
- is important or the updaters cannot block, synchronize_kernel()
+ is important or the updaters cannot block, synchronize_rcu()
should be used in preference to call_rcu().
9. All RCU list-traversal primitives, which include
@@ -155,3 +165,14 @@
you -must- use the "_rcu()" variants of the list macros.
Failing to do so will break Alpha and confuse people reading
your code.
+
+11. Note that synchronize_rcu() -only- guarantees to wait until
+ all currently executing rcu_read_lock()-protected RCU read-side
+ critical sections complete. It does -not- necessarily guarantee
+ that all currently running interrupts, NMIs, preempt_disable()
+ code, or idle loops will complete. Therefore, if you do not have
+ rcu_read_lock()-protected read-side critical sections, do -not-
+ use synchronize_rcu().
+
+ If you want to wait for some of these other things, you might
+ instead need to use synchronize_irq() or synchronize_sched().