diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-08-01 01:33:02 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-09-29 00:38:34 -0400 |
commit | 6846c0c54074d47927c90eab4a805115e1ae3292 (patch) | |
tree | 8f074445ca802a48d976b9a9c8595ac7fe603f22 /include/linux/rcupdate.h | |
parent | d322f45ceed525daa9401154590bbae3222cfefb (diff) |
rcu: Improve rcu_assign_pointer() and RCU_INIT_POINTER() documentation
The differences between rcu_assign_pointer() and RCU_INIT_POINTER() are
subtle, and it is easy to use the the cheaper RCU_INIT_POINTER() when
the more-expensive rcu_assign_pointer() should have been used instead.
The consequences of this mistake are quite severe.
This commit therefore carefully lays out the situations in which it it
permissible to use RCU_INIT_POINTER().
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'include/linux/rcupdate.h')
-rw-r--r-- | include/linux/rcupdate.h | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index d7accc5f8892..af186e260c43 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -754,11 +754,18 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
754 | * any prior initialization. Returns the value assigned. | 754 | * any prior initialization. Returns the value assigned. |
755 | * | 755 | * |
756 | * Inserts memory barriers on architectures that require them | 756 | * Inserts memory barriers on architectures that require them |
757 | * (pretty much all of them other than x86), and also prevents | 757 | * (which is most of them), and also prevents the compiler from |
758 | * the compiler from reordering the code that initializes the | 758 | * reordering the code that initializes the structure after the pointer |
759 | * structure after the pointer assignment. More importantly, this | 759 | * assignment. More importantly, this call documents which pointers |
760 | * call documents which pointers will be dereferenced by RCU read-side | 760 | * will be dereferenced by RCU read-side code. |
761 | * code. | 761 | * |
762 | * In some special cases, you may use RCU_INIT_POINTER() instead | ||
763 | * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due | ||
764 | * to the fact that it does not constrain either the CPU or the compiler. | ||
765 | * That said, using RCU_INIT_POINTER() when you should have used | ||
766 | * rcu_assign_pointer() is a very bad thing that results in | ||
767 | * impossible-to-diagnose memory corruption. So please be careful. | ||
768 | * See the RCU_INIT_POINTER() comment header for details. | ||
762 | */ | 769 | */ |
763 | #define rcu_assign_pointer(p, v) \ | 770 | #define rcu_assign_pointer(p, v) \ |
764 | __rcu_assign_pointer((p), (v), __rcu) | 771 | __rcu_assign_pointer((p), (v), __rcu) |
@@ -766,8 +773,34 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
766 | /** | 773 | /** |
767 | * RCU_INIT_POINTER() - initialize an RCU protected pointer | 774 | * RCU_INIT_POINTER() - initialize an RCU protected pointer |
768 | * | 775 | * |
769 | * Initialize an RCU-protected pointer in such a way to avoid RCU-lockdep | 776 | * Initialize an RCU-protected pointer in special cases where readers |
770 | * splats. | 777 | * do not need ordering constraints on the CPU or the compiler. These |
778 | * special cases are: | ||
779 | * | ||
780 | * 1. This use of RCU_INIT_POINTER() is NULLing out the pointer -or- | ||
781 | * 2. The caller has taken whatever steps are required to prevent | ||
782 | * RCU readers from concurrently accessing this pointer -or- | ||
783 | * 3. The referenced data structure has already been exposed to | ||
784 | * readers either at compile time or via rcu_assign_pointer() -and- | ||
785 | * a. You have not made -any- reader-visible changes to | ||
786 | * this structure since then -or- | ||
787 | * b. It is OK for readers accessing this structure from its | ||
788 | * new location to see the old state of the structure. (For | ||
789 | * example, the changes were to statistical counters or to | ||
790 | * other state where exact synchronization is not required.) | ||
791 | * | ||
792 | * Failure to follow these rules governing use of RCU_INIT_POINTER() will | ||
793 | * result in impossible-to-diagnose memory corruption. As in the structures | ||
794 | * will look OK in crash dumps, but any concurrent RCU readers might | ||
795 | * see pre-initialized values of the referenced data structure. So | ||
796 | * please be very careful how you use RCU_INIT_POINTER()!!! | ||
797 | * | ||
798 | * If you are creating an RCU-protected linked structure that is accessed | ||
799 | * by a single external-to-structure RCU-protected pointer, then you may | ||
800 | * use RCU_INIT_POINTER() to initialize the internal RCU-protected | ||
801 | * pointers, but you must use rcu_assign_pointer() to initialize the | ||
802 | * external-to-structure pointer -after- you have completely initialized | ||
803 | * the reader-accessible portions of the linked structure. | ||
771 | */ | 804 | */ |
772 | #define RCU_INIT_POINTER(p, v) \ | 805 | #define RCU_INIT_POINTER(p, v) \ |
773 | p = (typeof(*v) __force __rcu *)(v) | 806 | p = (typeof(*v) __force __rcu *)(v) |