[tip/core/rcu,04/14] rcu: Add a gcc-style structure initializer for RCU pointers

Message ID 1339791195-26389-4-git-send-email-paulmck@linux.vnet.ibm.com
State New
Headers show

Commit Message

Paul E. McKenney June 15, 2012, 8:13 p.m.
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>

RCU_INIT_POINTER() returns a value that is never used, and which should
be abolished due to terminal ugliness:

	q = RCU_INIT_POINTER(global_p, p);

However, there are two uses that cannot be handled by a do-while
formulation because they do gcc-style initialization:

	RCU_INIT_POINTER(.real_cred, &init_cred),
	RCU_INIT_POINTER(.cred, &init_cred),

This usage is clever, but not necessarily the nicest approach.  This
commit therefore creates an INIT_RCU_POINTER() macro that is specifically
designed for gcc-style initialization.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 include/linux/rcupdate.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

Comments

Josh Triplett June 15, 2012, 8:48 p.m. | #1
On Fri, Jun 15, 2012 at 01:13:05PM -0700, Paul E. McKenney wrote:
> From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> 
> RCU_INIT_POINTER() returns a value that is never used, and which should
> be abolished due to terminal ugliness:
> 
> 	q = RCU_INIT_POINTER(global_p, p);
> 
> However, there are two uses that cannot be handled by a do-while
> formulation because they do gcc-style initialization:
> 
> 	RCU_INIT_POINTER(.real_cred, &init_cred),
> 	RCU_INIT_POINTER(.cred, &init_cred),
> 
> This usage is clever, but not necessarily the nicest approach.  This
> commit therefore creates an INIT_RCU_POINTER() macro that is specifically
> designed for gcc-style initialization.

The concept seems fine, but the names seem entirely non-obvious.
RCU_INIT_POINTER versus INIT_RCU_POINTER?

- Josh Triplett
Paul E. McKenney June 15, 2012, 9:22 p.m. | #2
On Fri, Jun 15, 2012 at 01:48:14PM -0700, Josh Triplett wrote:
> On Fri, Jun 15, 2012 at 01:13:05PM -0700, Paul E. McKenney wrote:
> > From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> > 
> > RCU_INIT_POINTER() returns a value that is never used, and which should
> > be abolished due to terminal ugliness:
> > 
> > 	q = RCU_INIT_POINTER(global_p, p);
> > 
> > However, there are two uses that cannot be handled by a do-while
> > formulation because they do gcc-style initialization:
> > 
> > 	RCU_INIT_POINTER(.real_cred, &init_cred),
> > 	RCU_INIT_POINTER(.cred, &init_cred),
> > 
> > This usage is clever, but not necessarily the nicest approach.  This
> > commit therefore creates an INIT_RCU_POINTER() macro that is specifically
> > designed for gcc-style initialization.
> 
> The concept seems fine, but the names seem entirely non-obvious.
> RCU_INIT_POINTER versus INIT_RCU_POINTER?

I was following things like INIT_THREAD_INFO(), with the leading "INIT_"
for gcc initialization.

							Thanx, Paul
Josh Triplett June 15, 2012, 9:50 p.m. | #3
On Fri, Jun 15, 2012 at 01:48:13PM -0700, Josh Triplett wrote:
> On Fri, Jun 15, 2012 at 01:13:05PM -0700, Paul E. McKenney wrote:
> > From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> > 
> > RCU_INIT_POINTER() returns a value that is never used, and which should
> > be abolished due to terminal ugliness:
> > 
> > 	q = RCU_INIT_POINTER(global_p, p);
> > 
> > However, there are two uses that cannot be handled by a do-while
> > formulation because they do gcc-style initialization:
> > 
> > 	RCU_INIT_POINTER(.real_cred, &init_cred),
> > 	RCU_INIT_POINTER(.cred, &init_cred),
> > 
> > This usage is clever, but not necessarily the nicest approach.  This
> > commit therefore creates an INIT_RCU_POINTER() macro that is specifically
> > designed for gcc-style initialization.
> 
> The concept seems fine, but the names seem entirely non-obvious.
> RCU_INIT_POINTER versus INIT_RCU_POINTER?

Suggestion: RCU_POINTER_INITIALIZER, following the example of many other
*_INITIALIZER macros elsewhere in the kernel.

- Josh Triplett
Paul E. McKenney June 15, 2012, 10:47 p.m. | #4
On Fri, Jun 15, 2012 at 02:50:21PM -0700, Josh Triplett wrote:
> On Fri, Jun 15, 2012 at 01:48:13PM -0700, Josh Triplett wrote:
> > On Fri, Jun 15, 2012 at 01:13:05PM -0700, Paul E. McKenney wrote:
> > > From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> > > 
> > > RCU_INIT_POINTER() returns a value that is never used, and which should
> > > be abolished due to terminal ugliness:
> > > 
> > > 	q = RCU_INIT_POINTER(global_p, p);
> > > 
> > > However, there are two uses that cannot be handled by a do-while
> > > formulation because they do gcc-style initialization:
> > > 
> > > 	RCU_INIT_POINTER(.real_cred, &init_cred),
> > > 	RCU_INIT_POINTER(.cred, &init_cred),
> > > 
> > > This usage is clever, but not necessarily the nicest approach.  This
> > > commit therefore creates an INIT_RCU_POINTER() macro that is specifically
> > > designed for gcc-style initialization.
> > 
> > The concept seems fine, but the names seem entirely non-obvious.
> > RCU_INIT_POINTER versus INIT_RCU_POINTER?
> 
> Suggestion: RCU_POINTER_INITIALIZER, following the example of many other
> *_INITIALIZER macros elsewhere in the kernel.

Sold!

							Thanx, Paul

Patch

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 26d1a47..eb92c21 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -906,6 +906,14 @@  static inline notrace void rcu_read_unlock_sched_notrace(void)
 #define RCU_INIT_POINTER(p, v) \
 		p = (typeof(*v) __force __rcu *)(v)
 
+/**
+ * INIT_RCU_POINTER() - statically initialize an RCU protected pointer
+ *
+ * GCC-style initialization for an RCU-protected pointer in a structure field.
+ */
+#define INIT_RCU_POINTER(p, v) \
+		.p = (typeof(*v) __force __rcu *)(v)
+
 static __always_inline bool __is_kfree_rcu_offset(unsigned long offset)
 {
 	return offset < 4096;