* [PATCH v2 tip/core/rcu 2/4] bonding: Use RCU_INIT_POINTER() for better overhead and for sparse
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 1/4] rcu: Add comment on evaluate-once properties of rcu_assign_pointer() Paul E. McKenney
@ 2013-12-11 23:08 ` Paul E. McKenney
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 3/4] rcu: Make rcu_assign_pointer's assignment volatile and type-safe Paul E. McKenney
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 4/4] rcu: Add an RCU_INITIALIZER for global RCU-protected pointers Paul E. McKenney
2 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2013-12-11 23:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, niv, tglx,
peterz, rostedt, dhowells, edumazet, darren, fweisbec, oleg, sbw,
Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Although rcu_assign_pointer() can be used to assign a constant
NULL pointer, doing so gets you an unnecessary memory barrier and
in some circumstances, sparse warnings. This commit therefore
changes the rcu_assign_pointer() of NULL in __bond_release_one() to
RCU_INIT_POINTER().
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
drivers/net/bonding/bond_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4dd5ee2a34cc..a0b97c4c655d 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1763,7 +1763,7 @@ static int __bond_release_one(struct net_device *bond_dev,
}
if (all) {
- rcu_assign_pointer(bond->curr_active_slave, NULL);
+ RCU_INIT_POINTER(bond->curr_active_slave, NULL);
} else if (oldcurrent == slave) {
/*
* Note that we hold RTNL over this sequence, so there
--
1.8.1.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 tip/core/rcu 3/4] rcu: Make rcu_assign_pointer's assignment volatile and type-safe
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 1/4] rcu: Add comment on evaluate-once properties of rcu_assign_pointer() Paul E. McKenney
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 2/4] bonding: Use RCU_INIT_POINTER() for better overhead and for sparse Paul E. McKenney
@ 2013-12-11 23:08 ` Paul E. McKenney
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 4/4] rcu: Add an RCU_INITIALIZER for global RCU-protected pointers Paul E. McKenney
2 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2013-12-11 23:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, niv, tglx,
peterz, rostedt, dhowells, edumazet, darren, fweisbec, oleg, sbw,
Paul E. McKenney
From: Josh Triplett <josh@joshtriplett.org>
The rcu_assign_pointer() primitive needs to use ACCESS_ONCE to make
the assignment to the destination pointer volatile, to protect against
compilers too clever for their own good.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
include/linux/rcupdate.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 00ad28168ef0..97853cd2d7b4 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -551,7 +551,7 @@ static inline void rcu_preempt_sleep_check(void)
#define __rcu_assign_pointer(p, v, space) \
do { \
smp_wmb(); \
- (p) = (typeof(*v) __force space *)(v); \
+ ACCESS_ONCE(p) = (typeof(*(v)) __force space *)(v); \
} while (0)
--
1.8.1.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 tip/core/rcu 4/4] rcu: Add an RCU_INITIALIZER for global RCU-protected pointers
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 1/4] rcu: Add comment on evaluate-once properties of rcu_assign_pointer() Paul E. McKenney
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 2/4] bonding: Use RCU_INIT_POINTER() for better overhead and for sparse Paul E. McKenney
2013-12-11 23:08 ` [PATCH v2 tip/core/rcu 3/4] rcu: Make rcu_assign_pointer's assignment volatile and type-safe Paul E. McKenney
@ 2013-12-11 23:08 ` Paul E. McKenney
2 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2013-12-11 23:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, niv, tglx,
peterz, rostedt, dhowells, edumazet, darren, fweisbec, oleg, sbw,
Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
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>
Conflicts:
include/linux/rcupdate.h
---
include/linux/rcupdate.h | 80 +++++++++++++++++++++++++-----------------------
1 file 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)
smp_read_barrier_depends(); \
(_________p1); \
})
-#define __rcu_assign_pointer(p, v, space) \
+
+/**
+ * RCU_INITIALIZER() - statically initialize an RCU-protected global variable
+ * @v: The value to statically initialize with.
+ */
+#define RCU_INITIALIZER(v) (typeof(*(v)) __force __rcu *)(v)
+
+/**
+ * rcu_assign_pointer() - assign to RCU-protected pointer
+ * @p: pointer to assign to
+ * @v: value to assign (publish)
+ *
+ * Assigns the specified value to the specified RCU-protected
+ * pointer, ensuring that any concurrent RCU readers will see
+ * any prior initialization.
+ *
+ * Inserts memory barriers on architectures that require them
+ * (which is most of them), and also prevents the compiler from
+ * reordering the code that initializes the structure after the pointer
+ * assignment. More importantly, this call documents which pointers
+ * will be dereferenced by RCU read-side code.
+ *
+ * In some special cases, you may use RCU_INIT_POINTER() instead
+ * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due
+ * to the fact that it does not constrain either the CPU or the compiler.
+ * That said, using RCU_INIT_POINTER() when you should have used
+ * rcu_assign_pointer() is a very bad thing that results in
+ * impossible-to-diagnose memory corruption. So please be careful.
+ * See the RCU_INIT_POINTER() comment header for details.
+ *
+ * Note that rcu_assign_pointer() evaluates each of its arguments only
+ * once, appearances notwithstanding. One of the "extra" evaluations
+ * is in typeof() and the other visible only to sparse (__CHECKER__),
+ * neither of which actually execute the argument. As with most cpp
+ * macros, this execute-arguments-only-once property is important, so
+ * please be careful when making changes to rcu_assign_pointer() and the
+ * other macros that it invokes.
+ */
+#define rcu_assign_pointer(p, v) \
do { \
smp_wmb(); \
- ACCESS_ONCE(p) = (typeof(*(v)) __force space *)(v); \
+ ACCESS_ONCE(p) = RCU_INITIALIZER(v); \
} while (0)
@@ -890,40 +928,6 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
}
/**
- * rcu_assign_pointer() - assign to RCU-protected pointer
- * @p: pointer to assign to
- * @v: value to assign (publish)
- *
- * Assigns the specified value to the specified RCU-protected
- * pointer, ensuring that any concurrent RCU readers will see
- * any prior initialization.
- *
- * Inserts memory barriers on architectures that require them
- * (which is most of them), and also prevents the compiler from
- * reordering the code that initializes the structure after the pointer
- * assignment. More importantly, this call documents which pointers
- * will be dereferenced by RCU read-side code.
- *
- * In some special cases, you may use RCU_INIT_POINTER() instead
- * of rcu_assign_pointer(). RCU_INIT_POINTER() is a bit faster due
- * to the fact that it does not constrain either the CPU or the compiler.
- * That said, using RCU_INIT_POINTER() when you should have used
- * rcu_assign_pointer() is a very bad thing that results in
- * impossible-to-diagnose memory corruption. So please be careful.
- * See the RCU_INIT_POINTER() comment header for details.
- *
- * Note that rcu_assign_pointer() evaluates each of its arguments only
- * once, appearances notwithstanding. One of the "extra" evaluations
- * is in typeof() and the other visible only to sparse (__CHECKER__),
- * neither of which actually execute the argument. As with most cpp
- * macros, this execute-arguments-only-once property is important, so
- * please be careful when making changes to rcu_assign_pointer() and the
- * other macros that it invokes.
- */
-#define rcu_assign_pointer(p, v) \
- __rcu_assign_pointer((p), (v), __rcu)
-
-/**
* RCU_INIT_POINTER() - initialize an RCU protected pointer
*
* Initialize an RCU-protected pointer in special cases where readers
@@ -957,7 +961,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
*/
#define RCU_INIT_POINTER(p, v) \
do { \
- p = (typeof(*v) __force __rcu *)(v); \
+ p = RCU_INITIALIZER(v); \
} while (0)
/**
@@ -966,7 +970,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
* GCC-style initialization for an RCU-protected pointer in a structure field.
*/
#define RCU_POINTER_INITIALIZER(p, v) \
- .p = (typeof(*v) __force __rcu *)(v)
+ .p = RCU_INITIALIZER(v)
/*
* Does the specified offset indicate that the corresponding rcu_head
--
1.8.1.5
^ permalink raw reply related [flat|nested] 6+ messages in thread