Skip to content

Commit 462225a

Browse files
committed
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>
1 parent 9d162cd commit 462225a

File tree

1 file changed

+42
-38
lines changed

1 file changed

+42
-38
lines changed

include/linux/rcupdate.h

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,48 @@ static inline void rcu_preempt_sleep_check(void)
548548
smp_read_barrier_depends(); \
549549
(_________p1); \
550550
})
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) \
552590
do { \
553591
smp_wmb(); \
554-
ACCESS_ONCE(p) = (typeof(*(v)) __force space *)(v); \
592+
ACCESS_ONCE(p) = RCU_INITIALIZER(v); \
555593
} while (0)
556594

557595

@@ -889,40 +927,6 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
889927
preempt_enable_notrace();
890928
}
891929

892-
/**
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-
926930
/**
927931
* RCU_INIT_POINTER() - initialize an RCU protected pointer
928932
*
@@ -957,7 +961,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
957961
*/
958962
#define RCU_INIT_POINTER(p, v) \
959963
do { \
960-
p = (typeof(*v) __force __rcu *)(v); \
964+
p = RCU_INITIALIZER(v); \
961965
} while (0)
962966

963967
/**
@@ -966,7 +970,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
966970
* GCC-style initialization for an RCU-protected pointer in a structure field.
967971
*/
968972
#define RCU_POINTER_INITIALIZER(p, v) \
969-
.p = (typeof(*v) __force __rcu *)(v)
973+
.p = RCU_INITIALIZER(v)
970974

971975
/*
972976
* Does the specified offset indicate that the corresponding rcu_head

0 commit comments

Comments
 (0)