Message ID | 1507573730-8083-14-git-send-email-mark.rutland@arm.com |
---|---|
State | New |
Headers | show |
Series | Preparatory work to kill off ACCESS_ONCE() | expand |
On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > For several reasons, it is desirable to use {READ,WRITE}_ONCE() in > preference to ACCESS_ONCE(), and new code is expected to use one of the > former. So far, there's been no reason to change most existing uses of > ACCESS_ONCE(), as these aren't currently harmful. > > However, for some features it is necessary to instrument reads and > writes separately, which is not possible with ACCESS_ONCE(). This > distinction is critical to correct operation. > > The bulk of the kernel code can be transformed via Coccinelle to use > {READ,WRITE}_ONCE(), though this only modifies users of ACCESS_ONCE(), > and not the implementation itself. As such, it has the potential to > break homebrew ACCESS_ONCE() macros seen in some user code in the kernel > tree (e.g. the virtio code, as fixed in commit ea9156fb3b71d9f7). > > To avoid fragility if/when that transformation occurs, this patch > reworks the rcutorture formal tests to use an intermediate > __ACCESS_ONCE() helper, which will avoid {READ,WRITE}_ONCE() being > turned into tautological definitions. There should be no functional > change as a result of this patch. > > Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> > Signed-off-by: Mark Rutland <mark.rutland@arm.com> > --- > tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > index 6687acc..ee4e4f8 100644 > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > @@ -34,8 +34,9 @@ > #define rs_smp_mb() do {} while (0) > #endif > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > -#define READ_ONCE(x) ACCESS_ONCE(x) > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > +#define READ_ONCE(x) __ACCESS_ONCE(x) > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) How about something like the following? #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) Thanx, Paul
On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > index 6687acc..ee4e4f8 100644 > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > @@ -34,8 +34,9 @@ > > #define rs_smp_mb() do {} while (0) > > #endif > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > How about something like the following? > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) Sure; folded in and pushed out. :) I've assumed that the ACCESS_ONCE() definition needs to be kept until that's ripped out treewide. Please shout if that's not the case! Thanks, Mark.
On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > index 6687acc..ee4e4f8 100644 > > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > @@ -34,8 +34,9 @@ > > > #define rs_smp_mb() do {} while (0) > > > #endif > > > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > > > How about something like the following? > > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > Sure; folded in and pushed out. :) Thank you! > I've assumed that the ACCESS_ONCE() definition needs to be kept until > that's ripped out treewide. Please shout if that's not the case! You have it right. This case is an exception because this code is used only by RCU, which has long since had ACCESS_ONCE() ripped out. Thanx, Paul
On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > > > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > index 6687acc..ee4e4f8 100644 > > > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > @@ -34,8 +34,9 @@ > > > > #define rs_smp_mb() do {} while (0) > > > > #endif > > > > > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > > > > > How about something like the following? > > > > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > Sure; folded in and pushed out. :) > > Thank you! > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > that's ripped out treewide. Please shout if that's not the case! > > You have it right. This case is an exception because this code is > used only by RCU, which has long since had ACCESS_ONCE() ripped out. Sorry; I meant that in this case, I leave this code as: #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) ... if you mean that we can drop ACCESS_ONCE() in this case, then I can rip that out. Thanks, Mark.
On Tue, Oct 10, 2017 at 01:50:39PM +0100, Mark Rutland wrote: > On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > > On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > > > > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > > > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > index 6687acc..ee4e4f8 100644 > > > > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > @@ -34,8 +34,9 @@ > > > > > #define rs_smp_mb() do {} while (0) > > > > > #endif > > > > > > > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > > > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > > > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > > > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > > > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > > > > > > > How about something like the following? > > > > > > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > Sure; folded in and pushed out. :) > > > > Thank you! > > > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > > that's ripped out treewide. Please shout if that's not the case! > > > > You have it right. This case is an exception because this code is > > used only by RCU, which has long since had ACCESS_ONCE() ripped out. > > Sorry; I meant that in this case, I leave this code as: > > #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > ... if you mean that we can drop ACCESS_ONCE() in this case, then I can > rip that out. We can drop ACCESS_ONCE() in this case. Thanx, Paul
On Tue, Oct 10, 2017 at 07:52:52AM -0700, Paul E. McKenney wrote: > On Tue, Oct 10, 2017 at 01:50:39PM +0100, Mark Rutland wrote: > > On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > > > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > > > that's ripped out treewide. Please shout if that's not the case! > > > > > > You have it right. This case is an exception because this code is > > > used only by RCU, which has long since had ACCESS_ONCE() ripped out. > > > > Sorry; I meant that in this case, I leave this code as: > > > > #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > ... if you mean that we can drop ACCESS_ONCE() in this case, then I can > > rip that out. > > We can drop ACCESS_ONCE() in this case. Done. Sorry for the confusion! Thanks, Mark.
On Tue, 2017-10-10 at 07:52 -0700, Paul E. McKenney wrote: > On Tue, Oct 10, 2017 at 01:50:39PM +0100, Mark Rutland wrote: > > On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > > > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > > > On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > > > > > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > > > > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > index 6687acc..ee4e4f8 100644 > > > > > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > @@ -34,8 +34,9 @@ > > > > > > #define rs_smp_mb() do {} while (0) > > > > > > #endif > > > > > > > > > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > > > > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > > > > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > > > > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > > > > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > > > > > > > > > How about something like the following? > > > > > > > > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > > > Sure; folded in and pushed out. :) > > > > > > Thank you! > > > > > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > > > that's ripped out treewide. Please shout if that's not the case! > > > > > > You have it right. This case is an exception because this code is > > > used only by RCU, which has long since had ACCESS_ONCE() ripped out. > > > > Sorry; I meant that in this case, I leave this code as: > > > > #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > ... if you mean that we can drop ACCESS_ONCE() in this case, then I can > > rip that out. > > We can drop ACCESS_ONCE() in this case. Once ACCESS_ONCE is removed from the code in the tree it can also be removed from checkpatch --- scripts/checkpatch.pl | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2a8c6c3c1bdb..440262a87d26 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6224,28 +6224,6 @@ sub process { } } -# whine about ACCESS_ONCE - if ($^V && $^V ge 5.10.0 && - $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { - my $par = $1; - my $eq = $2; - my $fun = $3; - $par =~ s/^\(\s*(.*)\s*\)$/$1/; - if (defined($eq)) { - if (WARN("PREFER_WRITE_ONCE", - "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; - } - } else { - if (WARN("PREFER_READ_ONCE", - "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; - } - } - } - # check for mutex_trylock_recursive usage if ($line =~ /mutex_trylock_recursive/) { ERROR("LOCKING",
On Tue, Oct 10, 2017 at 09:27:54AM -0700, Joe Perches wrote: > On Tue, 2017-10-10 at 07:52 -0700, Paul E. McKenney wrote: > > On Tue, Oct 10, 2017 at 01:50:39PM +0100, Mark Rutland wrote: > > > On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > > > > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > > > > On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > > > > > > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > > > > > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > > index 6687acc..ee4e4f8 100644 > > > > > > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > > @@ -34,8 +34,9 @@ > > > > > > > #define rs_smp_mb() do {} while (0) > > > > > > > #endif > > > > > > > > > > > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > > > > > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > > > > > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > > > > > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > > > > > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > > > > > > > > > > > How about something like the following? > > > > > > > > > > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > > > > > Sure; folded in and pushed out. :) > > > > > > > > Thank you! > > > > > > > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > > > > that's ripped out treewide. Please shout if that's not the case! > > > > > > > > You have it right. This case is an exception because this code is > > > > used only by RCU, which has long since had ACCESS_ONCE() ripped out. > > > > > > Sorry; I meant that in this case, I leave this code as: > > > > > > #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > ... if you mean that we can drop ACCESS_ONCE() in this case, then I can > > > rip that out. > > > > We can drop ACCESS_ONCE() in this case. > > Once ACCESS_ONCE is removed from the code in the tree > it can also be removed from checkpatch Agreed, but only after all ACCESS_ONCE() definitions are removed. Thanx, Paul > --- > scripts/checkpatch.pl | 22 ---------------------- > 1 file changed, 22 deletions(-) > > diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl > index 2a8c6c3c1bdb..440262a87d26 100755 > --- a/scripts/checkpatch.pl > +++ b/scripts/checkpatch.pl > @@ -6224,28 +6224,6 @@ sub process { > } > } > > -# whine about ACCESS_ONCE > - if ($^V && $^V ge 5.10.0 && > - $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { > - my $par = $1; > - my $eq = $2; > - my $fun = $3; > - $par =~ s/^\(\s*(.*)\s*\)$/$1/; > - if (defined($eq)) { > - if (WARN("PREFER_WRITE_ONCE", > - "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && > - $fix) { > - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; > - } > - } else { > - if (WARN("PREFER_READ_ONCE", > - "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && > - $fix) { > - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; > - } > - } > - } > - > # check for mutex_trylock_recursive usage > if ($line =~ /mutex_trylock_recursive/) { > ERROR("LOCKING", >
On Tue, Oct 10, 2017 at 05:24:42PM +0100, Mark Rutland wrote: > On Tue, Oct 10, 2017 at 07:52:52AM -0700, Paul E. McKenney wrote: > > On Tue, Oct 10, 2017 at 01:50:39PM +0100, Mark Rutland wrote: > > > On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > > > > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > > > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > > > > that's ripped out treewide. Please shout if that's not the case! > > > > > > > > You have it right. This case is an exception because this code is > > > > used only by RCU, which has long since had ACCESS_ONCE() ripped out. > > > > > > Sorry; I meant that in this case, I leave this code as: > > > > > > #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > ... if you mean that we can drop ACCESS_ONCE() in this case, then I can > > > rip that out. > > > > We can drop ACCESS_ONCE() in this case. > > Done. Sorry for the confusion! Very good, thank you! Thanx, Paul
On Tue, Oct 10, 2017 at 09:27:54AM -0700, Joe Perches wrote: > On Tue, 2017-10-10 at 07:52 -0700, Paul E. McKenney wrote: > > On Tue, Oct 10, 2017 at 01:50:39PM +0100, Mark Rutland wrote: > > > On Tue, Oct 10, 2017 at 05:47:12AM -0700, Paul E. McKenney wrote: > > > > On Tue, Oct 10, 2017 at 10:54:14AM +0100, Mark Rutland wrote: > > > > > On Mon, Oct 09, 2017 at 12:51:12PM -0700, Paul E. McKenney wrote: > > > > > > On Mon, Oct 09, 2017 at 07:28:50PM +0100, Mark Rutland wrote: > > > > > > > diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > > index 6687acc..ee4e4f8 100644 > > > > > > > --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > > +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h > > > > > > > @@ -34,8 +34,9 @@ > > > > > > > #define rs_smp_mb() do {} while (0) > > > > > > > #endif > > > > > > > > > > > > > > -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > > -#define READ_ONCE(x) ACCESS_ONCE(x) > > > > > > > -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) > > > > > > > +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > > +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) > > > > > > > +#define READ_ONCE(x) __ACCESS_ONCE(x) > > > > > > > +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) > > > > > > > > > > > > How about something like the following? > > > > > > > > > > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > > > > > Sure; folded in and pushed out. :) > > > > > > > > Thank you! > > > > > > > > > I've assumed that the ACCESS_ONCE() definition needs to be kept until > > > > > that's ripped out treewide. Please shout if that's not the case! > > > > > > > > You have it right. This case is an exception because this code is > > > > used only by RCU, which has long since had ACCESS_ONCE() ripped out. > > > > > > Sorry; I meant that in this case, I leave this code as: > > > > > > #define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define READ_ONCE(x) (*(volatile typeof(x) *) &(x)) > > > #define WRITE_ONCE(x) ((*(volatile typeof(x) *) &(x)) = (val)) > > > > > > ... if you mean that we can drop ACCESS_ONCE() in this case, then I can > > > rip that out. > > > > We can drop ACCESS_ONCE() in this case. > > Once ACCESS_ONCE is removed from the code in the tree > it can also be removed from checkpatch Sure thing. We're expecting to rip that out with the ACCESS_ONCE definitions in a post-Coccinelle patch. If you're happy to give a sign-off for the below, we can drop that into the post-coccienelle patch/series. Thanks, Mark. > --- > scripts/checkpatch.pl | 22 ---------------------- > 1 file changed, 22 deletions(-) > > diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl > index 2a8c6c3c1bdb..440262a87d26 100755 > --- a/scripts/checkpatch.pl > +++ b/scripts/checkpatch.pl > @@ -6224,28 +6224,6 @@ sub process { > } > } > > -# whine about ACCESS_ONCE > - if ($^V && $^V ge 5.10.0 && > - $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { > - my $par = $1; > - my $eq = $2; > - my $fun = $3; > - $par =~ s/^\(\s*(.*)\s*\)$/$1/; > - if (defined($eq)) { > - if (WARN("PREFER_WRITE_ONCE", > - "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && > - $fix) { > - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; > - } > - } else { > - if (WARN("PREFER_READ_ONCE", > - "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && > - $fix) { > - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; > - } > - } > - } > - > # check for mutex_trylock_recursive usage > if ($line =~ /mutex_trylock_recursive/) { > ERROR("LOCKING", >
On Tue, 2017-10-10 at 17:41 +0100, Mark Rutland wrote: > On Tue, Oct 10, 2017 at 09:27:54AM -0700, Joe Perches wrote: > > Once ACCESS_ONCE is removed from the code in the tree > > it can also be removed from checkpatch > > Sure thing. We're expecting to rip that out with the ACCESS_ONCE > definitions in a post-Coccinelle patch. This treewide series is one of the types that would be nice to have done at -rc1 via some external automated script service.
On Tue, Oct 10, 2017 at 09:57:25AM -0700, Joe Perches wrote: > On Tue, 2017-10-10 at 17:41 +0100, Mark Rutland wrote: > > On Tue, Oct 10, 2017 at 09:27:54AM -0700, Joe Perches wrote: > > > Once ACCESS_ONCE is removed from the code in the tree > > > it can also be removed from checkpatch > > > > Sure thing. We're expecting to rip that out with the ACCESS_ONCE > > definitions in a post-Coccinelle patch. > > This treewide series is one of the types that would be nice to > have done at -rc1 via some external automated script service. Agreed, and this is exactly the plan. As mentioned above, the treewide conversion is scripted with Coccinelle (script below). The plan would be to regenerate this at an rc boundary, once the preparatory patches (which cannot be scripted) have been merged. The ACCESS_ONCE() definitions and checkpatch bits would be removed in a subsequent patch or series of patches. Thanks, Mark. ---- // Convert trivial ACCESS_ONCE() uses to equivalent READ_ONCE() and // WRITE_ONCE() virtual patch @ depends on patch @ expression E1, E2; @@ - ACCESS_ONCE(E1) = E2 + WRITE_ONCE(E1, E2) @ depends on patch @ expression E; @@ - ACCESS_ONCE(E) + READ_ONCE(E) ----
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h index 6687acc..ee4e4f8 100644 --- a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h +++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h @@ -34,8 +34,9 @@ #define rs_smp_mb() do {} while (0) #endif -#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) -#define READ_ONCE(x) ACCESS_ONCE(x) -#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val)) +#define __ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x)) +#define ACCESS_ONCE(x) __ACCESS_ONCE(x) +#define READ_ONCE(x) __ACCESS_ONCE(x) +#define WRITE_ONCE(x, val) (__ACCESS_ONCE(x) = (val)) #endif
For several reasons, it is desirable to use {READ,WRITE}_ONCE() in preference to ACCESS_ONCE(), and new code is expected to use one of the former. So far, there's been no reason to change most existing uses of ACCESS_ONCE(), as these aren't currently harmful. However, for some features it is necessary to instrument reads and writes separately, which is not possible with ACCESS_ONCE(). This distinction is critical to correct operation. The bulk of the kernel code can be transformed via Coccinelle to use {READ,WRITE}_ONCE(), though this only modifies users of ACCESS_ONCE(), and not the implementation itself. As such, it has the potential to break homebrew ACCESS_ONCE() macros seen in some user code in the kernel tree (e.g. the virtio code, as fixed in commit ea9156fb3b71d9f7). To avoid fragility if/when that transformation occurs, this patch reworks the rcutorture formal tests to use an intermediate __ACCESS_ONCE() helper, which will avoid {READ,WRITE}_ONCE() being turned into tautological definitions. There should be no functional change as a result of this patch. Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Mark Rutland <mark.rutland@arm.com> --- tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) -- 1.9.1