public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] rcu: Don't return a value from rcu_assign_pointer()
@ 2019-05-27  8:49 Andrea Parri
  2019-05-27 16:10 ` Paul E. McKenney
  0 siblings, 1 reply; 6+ messages in thread
From: Andrea Parri @ 2019-05-27  8:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrea Parri, Paul E. McKenney, Josh Triplett, Steven Rostedt,
	Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes, rcu,
	Peter Zijlstra, Will Deacon, Mark Rutland, Matthew Wilcox,
	Sasha Levin

Quoting Paul [1]:

  "Given that a quick (and perhaps error-prone) search of the uses
   of rcu_assign_pointer() in v5.1 didn't find a single use of the
   return value, let's please instead change the documentation and
   implementation to eliminate the return value."

[1] https://lkml.kernel.org/r/20190523135013.GL28207@linux.ibm.com

Signed-off-by: Andrea Parri <andrea.parri@amarulasolutions.com>
Cc: "Paul E. McKenney" <paulmck@linux.ibm.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Joel Fernandes <joel@joelfernandes.org>
Cc: rcu@vger.kernel.org
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Sasha Levin <sashal@kernel.org>
---
Changes in v2:
  - Fix documentation and style (Paul E. McKenney)
  - Improve subject line (Mark Rutland) 
---
 Documentation/RCU/whatisRCU.txt           | 8 ++++----
 include/linux/rcupdate.h                  | 5 ++---
 tools/include/linux/rcu.h                 | 4 ++--
 tools/testing/radix-tree/linux/rcupdate.h | 2 +-
 4 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 981651a8b65d2..7e1a8721637ab 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -212,7 +212,7 @@ synchronize_rcu()
 
 rcu_assign_pointer()
 
-	typeof(p) rcu_assign_pointer(p, typeof(p) v);
+	void rcu_assign_pointer(p, typeof(p) v);
 
 	Yes, rcu_assign_pointer() -is- implemented as a macro, though it
 	would be cool to be able to declare a function in this manner.
@@ -220,9 +220,9 @@ rcu_assign_pointer()
 
 	The updater uses this function to assign a new value to an
 	RCU-protected pointer, in order to safely communicate the change
-	in value from the updater to the reader.  This function returns
-	the new value, and also executes any memory-barrier instructions
-	required for a given CPU architecture.
+	in value from the updater to the reader.  This macro does not
+	evaluate to an rvalue, but it does execute any memory-barrier
+	instructions required for a given CPU architecture.
 
 	Perhaps just as important, it serves to document (1) which
 	pointers are protected by RCU and (2) the point at which a
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index a8ed624da5556..0c9b92799abc7 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -367,7 +367,7 @@ static inline void rcu_preempt_sleep_check(void) { }
  * other macros that it invokes.
  */
 #define rcu_assign_pointer(p, v)					      \
-({									      \
+do {									      \
 	uintptr_t _r_a_p__v = (uintptr_t)(v);				      \
 	rcu_check_sparse(p, __rcu);					      \
 									      \
@@ -375,8 +375,7 @@ static inline void rcu_preempt_sleep_check(void) { }
 		WRITE_ONCE((p), (typeof(p))(_r_a_p__v));		      \
 	else								      \
 		smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \
-	_r_a_p__v;							      \
-})
+} while (0)
 
 /**
  * rcu_swap_protected() - swap an RCU and a regular pointer
diff --git a/tools/include/linux/rcu.h b/tools/include/linux/rcu.h
index 7d02527e5bcea..9554d3fa54f33 100644
--- a/tools/include/linux/rcu.h
+++ b/tools/include/linux/rcu.h
@@ -19,7 +19,7 @@ static inline bool rcu_is_watching(void)
 	return false;
 }
 
-#define rcu_assign_pointer(p, v) ((p) = (v))
-#define RCU_INIT_POINTER(p, v) p=(v)
+#define rcu_assign_pointer(p, v)	do { (p) = (v); } while (0)
+#define RCU_INIT_POINTER(p, v)	do { (p) = (v); } while (0)
 
 #endif
diff --git a/tools/testing/radix-tree/linux/rcupdate.h b/tools/testing/radix-tree/linux/rcupdate.h
index fd280b070fdb1..fed468fb0c78d 100644
--- a/tools/testing/radix-tree/linux/rcupdate.h
+++ b/tools/testing/radix-tree/linux/rcupdate.h
@@ -7,6 +7,6 @@
 #define rcu_dereference_raw(p) rcu_dereference(p)
 #define rcu_dereference_protected(p, cond) rcu_dereference(p)
 #define rcu_dereference_check(p, cond) rcu_dereference(p)
-#define RCU_INIT_POINTER(p, v)	(p) = (v)
+#define RCU_INIT_POINTER(p, v)	do { (p) = (v); } while (0)
 
 #endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] rcu: Don't return a value from rcu_assign_pointer()
  2019-05-27  8:49 [PATCH v2] rcu: Don't return a value from rcu_assign_pointer() Andrea Parri
@ 2019-05-27 16:10 ` Paul E. McKenney
  2019-05-27 17:21   ` Joe Perches
  0 siblings, 1 reply; 6+ messages in thread
From: Paul E. McKenney @ 2019-05-27 16:10 UTC (permalink / raw)
  To: Andrea Parri
  Cc: linux-kernel, Josh Triplett, Steven Rostedt, Mathieu Desnoyers,
	Lai Jiangshan, Joel Fernandes, rcu, Peter Zijlstra, Will Deacon,
	Mark Rutland, Matthew Wilcox, Sasha Levin, apw, joe

On Mon, May 27, 2019 at 10:49:57AM +0200, Andrea Parri wrote:
> Quoting Paul [1]:
> 
>   "Given that a quick (and perhaps error-prone) search of the uses
>    of rcu_assign_pointer() in v5.1 didn't find a single use of the
>    return value, let's please instead change the documentation and
>    implementation to eliminate the return value."
> 
> [1] https://lkml.kernel.org/r/20190523135013.GL28207@linux.ibm.com

Queued, thank you!

Adding the checkpatch maintainers on CC as well.  The "do { } while
(0)" prevents the return value from being used, by design.  Given the
checkpatch complaint, is there some better way to achieve this?

							Thanx, Paul

> Signed-off-by: Andrea Parri <andrea.parri@amarulasolutions.com>
> Cc: "Paul E. McKenney" <paulmck@linux.ibm.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Cc: Lai Jiangshan <jiangshanlai@gmail.com>
> Cc: Joel Fernandes <joel@joelfernandes.org>
> Cc: rcu@vger.kernel.org
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Sasha Levin <sashal@kernel.org>
> ---
> Changes in v2:
>   - Fix documentation and style (Paul E. McKenney)
>   - Improve subject line (Mark Rutland) 
> ---
>  Documentation/RCU/whatisRCU.txt           | 8 ++++----
>  include/linux/rcupdate.h                  | 5 ++---
>  tools/include/linux/rcu.h                 | 4 ++--
>  tools/testing/radix-tree/linux/rcupdate.h | 2 +-
>  4 files changed, 9 insertions(+), 10 deletions(-)
> 
> diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
> index 981651a8b65d2..7e1a8721637ab 100644
> --- a/Documentation/RCU/whatisRCU.txt
> +++ b/Documentation/RCU/whatisRCU.txt
> @@ -212,7 +212,7 @@ synchronize_rcu()
>  
>  rcu_assign_pointer()
>  
> -	typeof(p) rcu_assign_pointer(p, typeof(p) v);
> +	void rcu_assign_pointer(p, typeof(p) v);
>  
>  	Yes, rcu_assign_pointer() -is- implemented as a macro, though it
>  	would be cool to be able to declare a function in this manner.
> @@ -220,9 +220,9 @@ rcu_assign_pointer()
>  
>  	The updater uses this function to assign a new value to an
>  	RCU-protected pointer, in order to safely communicate the change
> -	in value from the updater to the reader.  This function returns
> -	the new value, and also executes any memory-barrier instructions
> -	required for a given CPU architecture.
> +	in value from the updater to the reader.  This macro does not
> +	evaluate to an rvalue, but it does execute any memory-barrier
> +	instructions required for a given CPU architecture.
>  
>  	Perhaps just as important, it serves to document (1) which
>  	pointers are protected by RCU and (2) the point at which a
> diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> index a8ed624da5556..0c9b92799abc7 100644
> --- a/include/linux/rcupdate.h
> +++ b/include/linux/rcupdate.h
> @@ -367,7 +367,7 @@ static inline void rcu_preempt_sleep_check(void) { }
>   * other macros that it invokes.
>   */
>  #define rcu_assign_pointer(p, v)					      \
> -({									      \
> +do {									      \
>  	uintptr_t _r_a_p__v = (uintptr_t)(v);				      \
>  	rcu_check_sparse(p, __rcu);					      \
>  									      \
> @@ -375,8 +375,7 @@ static inline void rcu_preempt_sleep_check(void) { }
>  		WRITE_ONCE((p), (typeof(p))(_r_a_p__v));		      \
>  	else								      \
>  		smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \
> -	_r_a_p__v;							      \
> -})
> +} while (0)
>  
>  /**
>   * rcu_swap_protected() - swap an RCU and a regular pointer
> diff --git a/tools/include/linux/rcu.h b/tools/include/linux/rcu.h
> index 7d02527e5bcea..9554d3fa54f33 100644
> --- a/tools/include/linux/rcu.h
> +++ b/tools/include/linux/rcu.h
> @@ -19,7 +19,7 @@ static inline bool rcu_is_watching(void)
>  	return false;
>  }
>  
> -#define rcu_assign_pointer(p, v) ((p) = (v))
> -#define RCU_INIT_POINTER(p, v) p=(v)
> +#define rcu_assign_pointer(p, v)	do { (p) = (v); } while (0)
> +#define RCU_INIT_POINTER(p, v)	do { (p) = (v); } while (0)
>  
>  #endif
> diff --git a/tools/testing/radix-tree/linux/rcupdate.h b/tools/testing/radix-tree/linux/rcupdate.h
> index fd280b070fdb1..fed468fb0c78d 100644
> --- a/tools/testing/radix-tree/linux/rcupdate.h
> +++ b/tools/testing/radix-tree/linux/rcupdate.h
> @@ -7,6 +7,6 @@
>  #define rcu_dereference_raw(p) rcu_dereference(p)
>  #define rcu_dereference_protected(p, cond) rcu_dereference(p)
>  #define rcu_dereference_check(p, cond) rcu_dereference(p)
> -#define RCU_INIT_POINTER(p, v)	(p) = (v)
> +#define RCU_INIT_POINTER(p, v)	do { (p) = (v); } while (0)
>  
>  #endif
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] rcu: Don't return a value from rcu_assign_pointer()
  2019-05-27 16:10 ` Paul E. McKenney
@ 2019-05-27 17:21   ` Joe Perches
  2019-05-27 17:49     ` Paul E. McKenney
  0 siblings, 1 reply; 6+ messages in thread
From: Joe Perches @ 2019-05-27 17:21 UTC (permalink / raw)
  To: paulmck, Andrea Parri
  Cc: linux-kernel, Josh Triplett, Steven Rostedt, Mathieu Desnoyers,
	Lai Jiangshan, Joel Fernandes, rcu, Peter Zijlstra, Will Deacon,
	Mark Rutland, Matthew Wilcox, Sasha Levin, apw

On Mon, 2019-05-27 at 09:10 -0700, Paul E. McKenney wrote:
> On Mon, May 27, 2019 at 10:49:57AM +0200, Andrea Parri wrote:
> > Quoting Paul [1]:
> > 
> >   "Given that a quick (and perhaps error-prone) search of the uses
> >    of rcu_assign_pointer() in v5.1 didn't find a single use of the
> >    return value, let's please instead change the documentation and
> >    implementation to eliminate the return value."
> > 
> > [1] https://lkml.kernel.org/r/20190523135013.GL28207@linux.ibm.com
> 
> Queued, thank you!
> 
> Adding the checkpatch maintainers on CC as well.  The "do { } while
> (0)" prevents the return value from being used, by design.  Given the
> checkpatch complaint, is there some better way to achieve this?

Not sure what the checkpatch complaint is here.
Reading the link above, there seems to be a compiler warning.

Perhaps a statement expression macro with no return value?

#define rcu_assign_pointer(p, v)	({ (p) = (v); ; })



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] rcu: Don't return a value from rcu_assign_pointer()
  2019-05-27 17:21   ` Joe Perches
@ 2019-05-27 17:49     ` Paul E. McKenney
  2019-05-27 17:57       ` Joe Perches
  0 siblings, 1 reply; 6+ messages in thread
From: Paul E. McKenney @ 2019-05-27 17:49 UTC (permalink / raw)
  To: Joe Perches
  Cc: Andrea Parri, linux-kernel, Josh Triplett, Steven Rostedt,
	Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes, rcu,
	Peter Zijlstra, Will Deacon, Mark Rutland, Matthew Wilcox,
	Sasha Levin, apw

On Mon, May 27, 2019 at 10:21:22AM -0700, Joe Perches wrote:
> On Mon, 2019-05-27 at 09:10 -0700, Paul E. McKenney wrote:
> > On Mon, May 27, 2019 at 10:49:57AM +0200, Andrea Parri wrote:
> > > Quoting Paul [1]:
> > > 
> > >   "Given that a quick (and perhaps error-prone) search of the uses
> > >    of rcu_assign_pointer() in v5.1 didn't find a single use of the
> > >    return value, let's please instead change the documentation and
> > >    implementation to eliminate the return value."
> > > 
> > > [1] https://lkml.kernel.org/r/20190523135013.GL28207@linux.ibm.com
> > 
> > Queued, thank you!
> > 
> > Adding the checkpatch maintainers on CC as well.  The "do { } while
> > (0)" prevents the return value from being used, by design.  Given the
> > checkpatch complaint, is there some better way to achieve this?
> 
> Not sure what the checkpatch complaint is here.

Checkpatch seems to want at least two statements in each
"do { } while (0)" macro definition:

WARNING: Single statement macros should not use a do {} while (0) loop

> Reading the link above, there seems to be a compiler warning.

The compiler warning is a theoretical issue that is being fixed by this
patch, and the patch is giving the checkpatch warning.

> Perhaps a statement expression macro with no return value?
> 
> #define rcu_assign_pointer(p, v)	({ (p) = (v); ; })

This is at best an acquired taste for me...

							Thanx, Paul


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] rcu: Don't return a value from rcu_assign_pointer()
  2019-05-27 17:49     ` Paul E. McKenney
@ 2019-05-27 17:57       ` Joe Perches
  2019-05-27 19:23         ` Paul E. McKenney
  0 siblings, 1 reply; 6+ messages in thread
From: Joe Perches @ 2019-05-27 17:57 UTC (permalink / raw)
  To: paulmck
  Cc: Andrea Parri, linux-kernel, Josh Triplett, Steven Rostedt,
	Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes, rcu,
	Peter Zijlstra, Will Deacon, Mark Rutland, Matthew Wilcox,
	Sasha Levin, apw

On Mon, 2019-05-27 at 10:49 -0700, Paul E. McKenney wrote:
> On Mon, May 27, 2019 at 10:21:22AM -0700, Joe Perches wrote:
> > On Mon, 2019-05-27 at 09:10 -0700, Paul E. McKenney wrote:
> > > On Mon, May 27, 2019 at 10:49:57AM +0200, Andrea Parri wrote:
> > > > Quoting Paul [1]:
> > > > 
> > > >   "Given that a quick (and perhaps error-prone) search of the uses
> > > >    of rcu_assign_pointer() in v5.1 didn't find a single use of the
> > > >    return value, let's please instead change the documentation and
> > > >    implementation to eliminate the return value."
> > > > 
> > > > [1] https://lkml.kernel.org/r/20190523135013.GL28207@linux.ibm.com
> > > 
> > > Queued, thank you!
> > > 
> > > Adding the checkpatch maintainers on CC as well.  The "do { } while
> > > (0)" prevents the return value from being used, by design.  Given the
> > > checkpatch complaint, is there some better way to achieve this?
> > 
> > Not sure what the checkpatch complaint is here.
> 
> Checkpatch seems to want at least two statements in each
> "do { } while (0)" macro definition:
> 
> WARNING: Single statement macros should not use a do {} while (0) loop
> 
> > Reading the link above, there seems to be a compiler warning.
> 
> The compiler warning is a theoretical issue that is being fixed by this
> patch, and the patch is giving the checkpatch warning.
> 
> > Perhaps a statement expression macro with no return value?
> > 
> > #define rcu_assign_pointer(p, v)	({ (p) = (v); ; })
> 
> This is at best an acquired taste for me...

Another ugly possibility could be:

#define rcu_assign_pointer(p, v) do {if (1) (p) = (v); } while (0)

Possibly the best option would be to ignore checkpatch here
and just add a comment above the use.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] rcu: Don't return a value from rcu_assign_pointer()
  2019-05-27 17:57       ` Joe Perches
@ 2019-05-27 19:23         ` Paul E. McKenney
  0 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2019-05-27 19:23 UTC (permalink / raw)
  To: Joe Perches
  Cc: Andrea Parri, linux-kernel, Josh Triplett, Steven Rostedt,
	Mathieu Desnoyers, Lai Jiangshan, Joel Fernandes, rcu,
	Peter Zijlstra, Will Deacon, Mark Rutland, Matthew Wilcox,
	Sasha Levin, apw

On Mon, May 27, 2019 at 10:57:52AM -0700, Joe Perches wrote:
> On Mon, 2019-05-27 at 10:49 -0700, Paul E. McKenney wrote:
> > On Mon, May 27, 2019 at 10:21:22AM -0700, Joe Perches wrote:
> > > On Mon, 2019-05-27 at 09:10 -0700, Paul E. McKenney wrote:
> > > > On Mon, May 27, 2019 at 10:49:57AM +0200, Andrea Parri wrote:
> > > > > Quoting Paul [1]:
> > > > > 
> > > > >   "Given that a quick (and perhaps error-prone) search of the uses
> > > > >    of rcu_assign_pointer() in v5.1 didn't find a single use of the
> > > > >    return value, let's please instead change the documentation and
> > > > >    implementation to eliminate the return value."
> > > > > 
> > > > > [1] https://lkml.kernel.org/r/20190523135013.GL28207@linux.ibm.com
> > > > 
> > > > Queued, thank you!
> > > > 
> > > > Adding the checkpatch maintainers on CC as well.  The "do { } while
> > > > (0)" prevents the return value from being used, by design.  Given the
> > > > checkpatch complaint, is there some better way to achieve this?
> > > 
> > > Not sure what the checkpatch complaint is here.
> > 
> > Checkpatch seems to want at least two statements in each
> > "do { } while (0)" macro definition:
> > 
> > WARNING: Single statement macros should not use a do {} while (0) loop
> > 
> > > Reading the link above, there seems to be a compiler warning.
> > 
> > The compiler warning is a theoretical issue that is being fixed by this
> > patch, and the patch is giving the checkpatch warning.
> > 
> > > Perhaps a statement expression macro with no return value?
> > > 
> > > #define rcu_assign_pointer(p, v)	({ (p) = (v); ; })
> > 
> > This is at best an acquired taste for me...
> 
> Another ugly possibility could be:
> 
> #define rcu_assign_pointer(p, v) do {if (1) (p) = (v); } while (0)

And, not to be left out, another ugly possibility might be:

#define rcu_assign_pointer(p, v) ((void)((p) = (v)))

> Possibly the best option would be to ignore checkpatch here
> and just add a comment above the use.

Works for me!

							Thanx, Paul


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-05-27 19:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-27  8:49 [PATCH v2] rcu: Don't return a value from rcu_assign_pointer() Andrea Parri
2019-05-27 16:10 ` Paul E. McKenney
2019-05-27 17:21   ` Joe Perches
2019-05-27 17:49     ` Paul E. McKenney
2019-05-27 17:57       ` Joe Perches
2019-05-27 19:23         ` Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox