diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-11-11 12:59:34 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-12-12 15:24:23 -0500 |
commit | 462225ae47d7175f886281d8a91708550cd5178c (patch) | |
tree | 46048d886502e6a177a485a965f5f3371f545d43 | |
parent | 9d162cd06349dfee6b4f254b3abf1355cf0aee43 (diff) |
rcu: Add an RCU_INITIALIZER for global RCU-protected pointers
There is currently no way to initialize a global RCU-protected pointer
without either putting up with sparse complaints or open-coding an
obscure cast. This commit therefore creates RCU_INITIALIZER(), which
is intended to be used as follows:
struct foo __rcu *p = RCU_INITIALIZER(&my_rcu_structure);
This commit also applies RCU_INITIALIZER() to eliminate repeated
open-coded obscure casts in __rcu_assign_pointer(), RCU_INIT_POINTER(),
and RCU_POINTER_INITIALIZER(). This commit also inlines
__rcu_assign_pointer() into its only caller, rcu_assign_pointer().
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
-rw-r--r-- | include/linux/rcupdate.h | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 97853cd2d7b4..ea3816cf1a13 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -548,10 +548,48 @@ static inline void rcu_preempt_sleep_check(void) | |||
548 | smp_read_barrier_depends(); \ | 548 | smp_read_barrier_depends(); \ |
549 | (_________p1); \ | 549 | (_________p1); \ |
550 | }) | 550 | }) |
551 | #define __rcu_assign_pointer(p, v, space) \ | 551 | |
552 | /** | ||
553 | * RCU_INITIALIZER() - statically initialize an RCU-protected global variable | ||
554 | * @v: The value to statically initialize with. | ||
555 | */ | ||
556 | #define RCU_INITIALIZER(v) (typeof(*(v)) __force __rcu *)(v) | ||
557 | |||
558 | /** | ||
559 | * rcu_assign_pointer() - assign to RCU-protected pointer | ||
560 | * @p: pointer to assign to | ||
561 | * @v: value to assign (publish) | ||
562 | * | ||
563 | * Assigns the specified value to the specified RCU-protected | ||
564 | * pointer, ensuring that any concurrent RCU readers will see | ||
565 | * any prior initialization. | ||
566 | * | ||
567 | * Inserts memory barriers on architectures that require them | ||
568 | * (which is most of them), and also prevents the compiler from | ||
569 | * reordering the code that initializes the structure after the pointer | ||
570 | * assignment. More importantly, this call documents which pointers | ||
571 | * will be dereferenced by RCU read-side code. | ||
572 | * | ||
573 | * In some special cases, you may use RCU_INIT_POINTER() instead | ||
574 | * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due | ||
575 | * to the fact that it does not constrain either the CPU or the compiler. | ||
576 | * That said, using RCU_INIT_POINTER() when you should have used | ||
577 | * rcu_assign_pointer() is a very bad thing that results in | ||
578 | * impossible-to-diagnose memory corruption. So please be careful. | ||
579 | * See the RCU_INIT_POINTER() comment header for details. | ||
580 | * | ||
581 | * Note that rcu_assign_pointer() evaluates each of its arguments only | ||
582 | * once, appearances notwithstanding. One of the "extra" evaluations | ||
583 | * is in typeof() and the other visible only to sparse (__CHECKER__), | ||
584 | * neither of which actually execute the argument. As with most cpp | ||
585 | * macros, this execute-arguments-only-once property is important, so | ||
586 | * please be careful when making changes to rcu_assign_pointer() and the | ||
587 | * other macros that it invokes. | ||
588 | */ | ||
589 | #define rcu_assign_pointer(p, v) \ | ||
552 | do { \ | 590 | do { \ |
553 | smp_wmb(); \ | 591 | smp_wmb(); \ |
554 | ACCESS_ONCE(p) = (typeof(*(v)) __force space *)(v); \ | 592 | ACCESS_ONCE(p) = RCU_INITIALIZER(v); \ |
555 | } while (0) | 593 | } while (0) |
556 | 594 | ||
557 | 595 | ||
@@ -890,40 +928,6 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
890 | } | 928 | } |
891 | 929 | ||
892 | /** | 930 | /** |
893 | * rcu_assign_pointer() - assign to RCU-protected pointer | ||
894 | * @p: pointer to assign to | ||
895 | * @v: value to assign (publish) | ||
896 | * | ||
897 | * Assigns the specified value to the specified RCU-protected | ||
898 | * pointer, ensuring that any concurrent RCU readers will see | ||
899 | * any prior initialization. | ||
900 | * | ||
901 | * Inserts memory barriers on architectures that require them | ||
902 | * (which is most of them), and also prevents the compiler from | ||
903 | * reordering the code that initializes the structure after the pointer | ||
904 | * assignment. More importantly, this call documents which pointers | ||
905 | * will be dereferenced by RCU read-side code. | ||
906 | * | ||
907 | * In some special cases, you may use RCU_INIT_POINTER() instead | ||
908 | * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due | ||
909 | * to the fact that it does not constrain either the CPU or the compiler. | ||
910 | * That said, using RCU_INIT_POINTER() when you should have used | ||
911 | * rcu_assign_pointer() is a very bad thing that results in | ||
912 | * impossible-to-diagnose memory corruption. So please be careful. | ||
913 | * See the RCU_INIT_POINTER() comment header for details. | ||
914 | * | ||
915 | * Note that rcu_assign_pointer() evaluates each of its arguments only | ||
916 | * once, appearances notwithstanding. One of the "extra" evaluations | ||
917 | * is in typeof() and the other visible only to sparse (__CHECKER__), | ||
918 | * neither of which actually execute the argument. As with most cpp | ||
919 | * macros, this execute-arguments-only-once property is important, so | ||
920 | * please be careful when making changes to rcu_assign_pointer() and the | ||
921 | * other macros that it invokes. | ||
922 | */ | ||
923 | #define rcu_assign_pointer(p, v) \ | ||
924 | __rcu_assign_pointer((p), (v), __rcu) | ||
925 | |||
926 | /** | ||
927 | * RCU_INIT_POINTER() - initialize an RCU protected pointer | 931 | * RCU_INIT_POINTER() - initialize an RCU protected pointer |
928 | * | 932 | * |
929 | * Initialize an RCU-protected pointer in special cases where readers | 933 | * Initialize an RCU-protected pointer in special cases where readers |
@@ -957,7 +961,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
957 | */ | 961 | */ |
958 | #define RCU_INIT_POINTER(p, v) \ | 962 | #define RCU_INIT_POINTER(p, v) \ |
959 | do { \ | 963 | do { \ |
960 | p = (typeof(*v) __force __rcu *)(v); \ | 964 | p = RCU_INITIALIZER(v); \ |
961 | } while (0) | 965 | } while (0) |
962 | 966 | ||
963 | /** | 967 | /** |
@@ -966,7 +970,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
966 | * GCC-style initialization for an RCU-protected pointer in a structure field. | 970 | * GCC-style initialization for an RCU-protected pointer in a structure field. |
967 | */ | 971 | */ |
968 | #define RCU_POINTER_INITIALIZER(p, v) \ | 972 | #define RCU_POINTER_INITIALIZER(p, v) \ |
969 | .p = (typeof(*v) __force __rcu *)(v) | 973 | .p = RCU_INITIALIZER(v) |
970 | 974 | ||
971 | /* | 975 | /* |
972 | * Does the specified offset indicate that the corresponding rcu_head | 976 | * Does the specified offset indicate that the corresponding rcu_head |