* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 16:15 ` Linus Torvalds
@ 2015-03-26 16:21 ` Linus Torvalds
2015-03-26 16:36 ` Peter Zijlstra
2015-03-26 16:28 ` Peter Zijlstra
2015-03-26 17:24 ` Christian Borntraeger
2 siblings, 1 reply; 22+ messages in thread
From: Linus Torvalds @ 2015-03-26 16:21 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Will Deacon, Stephen Rothwell, Christian Borntraeger,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
linux-next@vger.kernel.org, linux-kernel@vger.kernel.org,
Davidlohr Bueso, Paul McKenney
On Thu, Mar 26, 2015 at 9:15 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> Really. Just get rid of the checks - they were wrong. They were
> clearly very close to *introducing* a bug, rather than fixing anything
> at all.
Side note: we will continue to expect the compiler to do single-word
accesses as a single acccess, rather than splitting things up. And
that's fine. READ_ONCE() uses "volatile", and it means on a language
level that the actual access is "visible", so it's a reasonable
expectation to have.
So the proper patch looks something like this:
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 1b45e4a0519b..f36e1abf56ea 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -198,10 +198,6 @@ __compiletime_warning("data access exceeds
word size and won't be atomic")
#endif
;
-static __always_inline void data_access_exceeds_word_size(void)
-{
-}
-
static __always_inline void __read_once_size(const volatile void
*p, void *res, int size)
{
switch (size) {
@@ -214,7 +210,6 @@ static __always_inline void
__read_once_size(const volatile void *p, void *res,
default:
barrier();
__builtin_memcpy((void *)res, (const void *)p, size);
- data_access_exceeds_word_size();
barrier();
}
}
@@ -231,7 +226,6 @@ static __always_inline void
__write_once_size(volatile void *p, void *res, int s
default:
barrier();
__builtin_memcpy((void *)p, (const void *)res, size);
- data_access_exceeds_word_size();
barrier();
}
}
and let's just leave it at that.
Note again how the default case just guarantees that it is never
reloaded by the compiler. That's the primary issue this is all about.
The whole "we expect the compiler to not be shit" is secondary and
_may_ be an issue in some places, but is not what the main goal is.
Linus
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 16:21 ` Linus Torvalds
@ 2015-03-26 16:36 ` Peter Zijlstra
2015-03-26 16:44 ` Peter Zijlstra
[not found] ` <CA+55aFw1WHJqSj+z-mJGY-kxrg_OsGp9jK9VBi+wB4zPgCkv_w@mail.gmail.com>
0 siblings, 2 replies; 22+ messages in thread
From: Peter Zijlstra @ 2015-03-26 16:36 UTC (permalink / raw)
To: Linus Torvalds
Cc: Will Deacon, Stephen Rothwell, Christian Borntraeger,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
linux-next@vger.kernel.org, linux-kernel@vger.kernel.org,
Davidlohr Bueso, Paul McKenney
On Thu, Mar 26, 2015 at 09:21:50AM -0700, Linus Torvalds wrote:
> So the proper patch looks something like this:
>
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 1b45e4a0519b..f36e1abf56ea 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -198,10 +198,6 @@ __compiletime_warning("data access exceeds
> word size and won't be atomic")
> #endif
> ;
You also want to get rid of that ^^^ declaration which includes the
compiletime warning.
> -static __always_inline void data_access_exceeds_word_size(void)
> -{
> -}
> -
> static __always_inline void __read_once_size(const volatile void
> *p, void *res, int size)
> {
> switch (size) {
> @@ -214,7 +210,6 @@ static __always_inline void
> __read_once_size(const volatile void *p, void *res,
> default:
> barrier();
> __builtin_memcpy((void *)res, (const void *)p, size);
> - data_access_exceeds_word_size();
> barrier();
> }
> }
> @@ -231,7 +226,6 @@ static __always_inline void
> __write_once_size(volatile void *p, void *res, int s
> default:
> barrier();
> __builtin_memcpy((void *)p, (const void *)res, size);
> - data_access_exceeds_word_size();
> barrier();
> }
> }
So this still has the potential to generate significantly worse code
than the previous ACCESS_ONCE() because of the dual barrier() and god
only knows how memcpy gets implemented.
As it turns out, the ARM version of __builtin_memcpy() does result in a
single double word load because its all smart and such, but a 'trivial'
implementation might just end up doing 8 byte copies.
Can't we make an argument that these barrier calls are not required? The
memcpy() call already guarantees we emit the loads and its opaque so the
compiler cannot 'cache' the value. So I see not immediate reason for the
dual memory clobber.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 16:36 ` Peter Zijlstra
@ 2015-03-26 16:44 ` Peter Zijlstra
2015-03-26 16:45 ` Peter Zijlstra
[not found] ` <CA+55aFw1WHJqSj+z-mJGY-kxrg_OsGp9jK9VBi+wB4zPgCkv_w@mail.gmail.com>
1 sibling, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2015-03-26 16:44 UTC (permalink / raw)
To: Linus Torvalds
Cc: Will Deacon, Stephen Rothwell, Christian Borntraeger,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
linux-next@vger.kernel.org, linux-kernel@vger.kernel.org,
Davidlohr Bueso, Paul McKenney
On Thu, Mar 26, 2015 at 05:36:47PM +0100, Peter Zijlstra wrote:
> Can't we make an argument that these barrier calls are not required? The
> memcpy() call already guarantees we emit the loads and its opaque so the
> compiler cannot 'cache' the value. So I see not immediate reason for the
> dual memory clobber.
Oh wait, it needs to reassess the content of the target variable after
the memcpy of course.
Could we then at least make the 64bit case unconditional as well?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 16:44 ` Peter Zijlstra
@ 2015-03-26 16:45 ` Peter Zijlstra
0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2015-03-26 16:45 UTC (permalink / raw)
To: Linus Torvalds
Cc: Will Deacon, Stephen Rothwell, Christian Borntraeger,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
linux-next@vger.kernel.org, linux-kernel@vger.kernel.org,
Davidlohr Bueso, Paul McKenney
On Thu, Mar 26, 2015 at 05:44:42PM +0100, Peter Zijlstra wrote:
> On Thu, Mar 26, 2015 at 05:36:47PM +0100, Peter Zijlstra wrote:
> > Can't we make an argument that these barrier calls are not required? The
> > memcpy() call already guarantees we emit the loads and its opaque so the
> > compiler cannot 'cache' the value. So I see not immediate reason for the
> > dual memory clobber.
>
> Oh wait, it needs to reassess the content of the target variable after
> the memcpy of course.
>
> Could we then at least make the 64bit case unconditional as well?
Like so.
---
include/linux/compiler.h | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 1b45e4a0519b..0e41ca0e5927 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -192,29 +192,16 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#include <uapi/linux/types.h>
-static __always_inline void data_access_exceeds_word_size(void)
-#ifdef __compiletime_warning
-__compiletime_warning("data access exceeds word size and won't be atomic")
-#endif
-;
-
-static __always_inline void data_access_exceeds_word_size(void)
-{
-}
-
static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
{
switch (size) {
case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
-#ifdef CONFIG_64BIT
case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
-#endif
default:
barrier();
__builtin_memcpy((void *)res, (const void *)p, size);
- data_access_exceeds_word_size();
barrier();
}
}
@@ -225,13 +212,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
-#ifdef CONFIG_64BIT
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
-#endif
default:
barrier();
__builtin_memcpy((void *)p, (const void *)res, size);
- data_access_exceeds_word_size();
barrier();
}
}
^ permalink raw reply related [flat|nested] 22+ messages in thread
[parent not found: <CA+55aFw1WHJqSj+z-mJGY-kxrg_OsGp9jK9VBi+wB4zPgCkv_w@mail.gmail.com>]
* Re: linux-next: build warnings after merge of the access_once tree
[not found] ` <CA+55aFw1WHJqSj+z-mJGY-kxrg_OsGp9jK9VBi+wB4zPgCkv_w@mail.gmail.com>
@ 2015-03-26 17:07 ` Peter Zijlstra
2015-03-26 17:17 ` Will Deacon
2015-03-26 17:23 ` Christian Borntraeger
0 siblings, 2 replies; 22+ messages in thread
From: Peter Zijlstra @ 2015-03-26 17:07 UTC (permalink / raw)
To: Linus Torvalds
Cc: Christian Borntraeger, Thomas Gleixner,
linux-next@vger.kernel.org, Stephen Rothwell, Ingo Molnar,
Davidlohr Bueso, Paul McKenney, linux-kernel@vger.kernel.org,
H. Peter Anvin, Will Deacon
On Thu, Mar 26, 2015 at 09:45:07AM -0700, Linus Torvalds wrote:
> Stop this idiocy.
Yeah, clearly I can type faster than I can think straight :/
In any case, I've the below patch; do you want to take it now or do you
want me to route it through tip/locking/urgent or something like that?
---
Subject: kernel: Remove atomicy checks from {READ,WRITE}_ONCE
From: Peter Zijlstra <peterz@infradead.org>
Date: Thu, 26 Mar 2015 17:45:37 +0100
The fact that volatile allows for atomic load/stores is a special case
not a requirement for {READ,WRITE}_ONCE(). Their primary purpose is to
force the compiler to emit load/stores _once_.
So remove the warning as it is correct behaviour. This also implies that
the u64 case is not 64bit only, so remove the #ifdef so we can generate
better code in that case.
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Cc: Will Deacon <will.deacon@arm.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
include/linux/compiler.h | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 1b45e4a0519b..0e41ca0e5927 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -192,29 +192,16 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#include <uapi/linux/types.h>
-static __always_inline void data_access_exceeds_word_size(void)
-#ifdef __compiletime_warning
-__compiletime_warning("data access exceeds word size and won't be atomic")
-#endif
-;
-
-static __always_inline void data_access_exceeds_word_size(void)
-{
-}
-
static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
{
switch (size) {
case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
-#ifdef CONFIG_64BIT
case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
-#endif
default:
barrier();
__builtin_memcpy((void *)res, (const void *)p, size);
- data_access_exceeds_word_size();
barrier();
}
}
@@ -225,13 +212,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
-#ifdef CONFIG_64BIT
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
-#endif
default:
barrier();
__builtin_memcpy((void *)p, (const void *)res, size);
- data_access_exceeds_word_size();
barrier();
}
}
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 17:07 ` Peter Zijlstra
@ 2015-03-26 17:17 ` Will Deacon
2015-03-26 17:23 ` Christian Borntraeger
1 sibling, 0 replies; 22+ messages in thread
From: Will Deacon @ 2015-03-26 17:17 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Linus Torvalds, Christian Borntraeger, Thomas Gleixner,
linux-next@vger.kernel.org, Stephen Rothwell, Ingo Molnar,
Davidlohr Bueso, Paul McKenney, linux-kernel@vger.kernel.org,
H. Peter Anvin
On Thu, Mar 26, 2015 at 05:07:48PM +0000, Peter Zijlstra wrote:
> On Thu, Mar 26, 2015 at 09:45:07AM -0700, Linus Torvalds wrote:
>
> > Stop this idiocy.
>
> Yeah, clearly I can type faster than I can think straight :/
>
>
> In any case, I've the below patch; do you want to take it now or do you
> want me to route it through tip/locking/urgent or something like that?
This patch also works fine for me. I managed to get the compiler to split a
64-bit load into 2x32-bit loads using memcpy, so I do like keeping the
8-byte case available for 32-bit architectures than can make use of it.
Acked-by: Will Deacon <will.deacon@arm.com>
Will
> Subject: kernel: Remove atomicy checks from {READ,WRITE}_ONCE
> From: Peter Zijlstra <peterz@infradead.org>
> Date: Thu, 26 Mar 2015 17:45:37 +0100
>
> The fact that volatile allows for atomic load/stores is a special case
> not a requirement for {READ,WRITE}_ONCE(). Their primary purpose is to
> force the compiler to emit load/stores _once_.
>
> So remove the warning as it is correct behaviour. This also implies that
> the u64 case is not 64bit only, so remove the #ifdef so we can generate
> better code in that case.
>
> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Davidlohr Bueso <dave@stgolabs.net>
> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> include/linux/compiler.h | 16 ----------------
> 1 file changed, 16 deletions(-)
>
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 1b45e4a0519b..0e41ca0e5927 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -192,29 +192,16 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
>
> #include <uapi/linux/types.h>
>
> -static __always_inline void data_access_exceeds_word_size(void)
> -#ifdef __compiletime_warning
> -__compiletime_warning("data access exceeds word size and won't be atomic")
> -#endif
> -;
> -
> -static __always_inline void data_access_exceeds_word_size(void)
> -{
> -}
> -
> static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
> {
> switch (size) {
> case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
> case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
> case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
> -#ifdef CONFIG_64BIT
> case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
> -#endif
> default:
> barrier();
> __builtin_memcpy((void *)res, (const void *)p, size);
> - data_access_exceeds_word_size();
> barrier();
> }
> }
> @@ -225,13 +212,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
> case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
> case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
> case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
> -#ifdef CONFIG_64BIT
> case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
> -#endif
> default:
> barrier();
> __builtin_memcpy((void *)p, (const void *)res, size);
> - data_access_exceeds_word_size();
> barrier();
> }
> }
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 17:07 ` Peter Zijlstra
2015-03-26 17:17 ` Will Deacon
@ 2015-03-26 17:23 ` Christian Borntraeger
2015-03-26 19:42 ` Christian Borntraeger
1 sibling, 1 reply; 22+ messages in thread
From: Christian Borntraeger @ 2015-03-26 17:23 UTC (permalink / raw)
To: Peter Zijlstra, Linus Torvalds
Cc: Thomas Gleixner, linux-next@vger.kernel.org, Stephen Rothwell,
Ingo Molnar, Davidlohr Bueso, Paul McKenney,
linux-kernel@vger.kernel.org, H. Peter Anvin, Will Deacon
Am 26.03.2015 um 18:07 schrieb Peter Zijlstra:
> On Thu, Mar 26, 2015 at 09:45:07AM -0700, Linus Torvalds wrote:
>
>> Stop this idiocy.
>
> Yeah, clearly I can type faster than I can think straight :/
>
>
> In any case, I've the below patch; do you want to take it now or do you
> want me to route it through tip/locking/urgent or something like that?
Its not urgent. Current upstream has a broken check (gcc will not emit the
warning if the function is static). I just fixed the check in my next tree
but I can certainly drop that tree.
>
> ---
> Subject: kernel: Remove atomicy checks from {READ,WRITE}_ONCE
> From: Peter Zijlstra <peterz@infradead.org>
> Date: Thu, 26 Mar 2015 17:45:37 +0100
>
> The fact that volatile allows for atomic load/stores is a special case
> not a requirement for {READ,WRITE}_ONCE(). Their primary purpose is to
> force the compiler to emit load/stores _once_.
>
> So remove the warning as it is correct behaviour. This also implies that
> the u64 case is not 64bit only, so remove the #ifdef so we can generate
> better code in that case.
>
> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Davidlohr Bueso <dave@stgolabs.net>
> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
> ---
> include/linux/compiler.h | 16 ----------------
> 1 file changed, 16 deletions(-)
>
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 1b45e4a0519b..0e41ca0e5927 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -192,29 +192,16 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
>
> #include <uapi/linux/types.h>
>
> -static __always_inline void data_access_exceeds_word_size(void)
> -#ifdef __compiletime_warning
> -__compiletime_warning("data access exceeds word size and won't be atomic")
> -#endif
> -;
> -
> -static __always_inline void data_access_exceeds_word_size(void)
> -{
> -}
> -
> static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
> {
> switch (size) {
> case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
> case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
> case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
> -#ifdef CONFIG_64BIT
> case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
> -#endif
> default:
> barrier();
> __builtin_memcpy((void *)res, (const void *)p, size);
> - data_access_exceeds_word_size();
> barrier();
> }
> }
> @@ -225,13 +212,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
> case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
> case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
> case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
> -#ifdef CONFIG_64BIT
> case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
> -#endif
> default:
> barrier();
> __builtin_memcpy((void *)p, (const void *)res, size);
> - data_access_exceeds_word_size();
> barrier();
> }
> }
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 17:23 ` Christian Borntraeger
@ 2015-03-26 19:42 ` Christian Borntraeger
0 siblings, 0 replies; 22+ messages in thread
From: Christian Borntraeger @ 2015-03-26 19:42 UTC (permalink / raw)
To: Peter Zijlstra, Linus Torvalds
Cc: Thomas Gleixner, linux-next@vger.kernel.org, Stephen Rothwell,
Ingo Molnar, Davidlohr Bueso, Paul McKenney,
linux-kernel@vger.kernel.org, H. Peter Anvin, Will Deacon
Am 26.03.2015 um 18:23 schrieb Christian Borntraeger:
> Am 26.03.2015 um 18:07 schrieb Peter Zijlstra:
>> On Thu, Mar 26, 2015 at 09:45:07AM -0700, Linus Torvalds wrote:
>>
>>> Stop this idiocy.
>>
>> Yeah, clearly I can type faster than I can think straight :/
>>
>>
>> In any case, I've the below patch; do you want to take it now or do you
>> want me to route it through tip/locking/urgent or something like that?
>
> Its not urgent. Current upstream has a broken check (gcc will not emit the
> warning if the function is static). I just fixed the check in my next tree
> but I can certainly drop that tree.
>
Thinking more about that, the removal of the ifdef for 64bit data might be
a reason to schedule that for 4.0.
>>
>> ---
>> Subject: kernel: Remove atomicy checks from {READ,WRITE}_ONCE
>> From: Peter Zijlstra <peterz@infradead.org>
>> Date: Thu, 26 Mar 2015 17:45:37 +0100
>>
>> The fact that volatile allows for atomic load/stores is a special case
>> not a requirement for {READ,WRITE}_ONCE(). Their primary purpose is to
>> force the compiler to emit load/stores _once_.
>>
>> So remove the warning as it is correct behaviour. This also implies that
>> the u64 case is not 64bit only, so remove the #ifdef so we can generate
>> better code in that case.
>>
>> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
>> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Ingo Molnar <mingo@elte.hu>
>> Cc: "H. Peter Anvin" <hpa@zytor.com>
>> Cc: Davidlohr Bueso <dave@stgolabs.net>
>> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>
> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
>
>
>> ---
>> include/linux/compiler.h | 16 ----------------
>> 1 file changed, 16 deletions(-)
>>
>> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
>> index 1b45e4a0519b..0e41ca0e5927 100644
>> --- a/include/linux/compiler.h
>> +++ b/include/linux/compiler.h
>> @@ -192,29 +192,16 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
>>
>> #include <uapi/linux/types.h>
>>
>> -static __always_inline void data_access_exceeds_word_size(void)
>> -#ifdef __compiletime_warning
>> -__compiletime_warning("data access exceeds word size and won't be atomic")
>> -#endif
>> -;
>> -
>> -static __always_inline void data_access_exceeds_word_size(void)
>> -{
>> -}
>> -
>> static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
>> {
>> switch (size) {
>> case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
>> case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
>> case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
>> -#ifdef CONFIG_64BIT
>> case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
>> -#endif
>> default:
>> barrier();
>> __builtin_memcpy((void *)res, (const void *)p, size);
>> - data_access_exceeds_word_size();
>> barrier();
>> }
>> }
>> @@ -225,13 +212,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>> case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
>> case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
>> case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
>> -#ifdef CONFIG_64BIT
>> case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
>> -#endif
>> default:
>> barrier();
>> __builtin_memcpy((void *)p, (const void *)res, size);
>> - data_access_exceeds_word_size();
>> barrier();
>> }
>> }
>>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 16:15 ` Linus Torvalds
2015-03-26 16:21 ` Linus Torvalds
@ 2015-03-26 16:28 ` Peter Zijlstra
[not found] ` <CA+55aFzUPPSHakwbp-Y-SaXB+o1=V6rOknz7L3AYNXNPU1MSfg@mail.gmail.com>
2015-03-26 17:24 ` Christian Borntraeger
2 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2015-03-26 16:28 UTC (permalink / raw)
To: Linus Torvalds
Cc: Will Deacon, Stephen Rothwell, Christian Borntraeger,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
linux-next@vger.kernel.org, linux-kernel@vger.kernel.org,
Davidlohr Bueso, Paul McKenney
On Thu, Mar 26, 2015 at 09:15:21AM -0700, Linus Torvalds wrote:
> Notice how it is *not* about atomicitiy. The compiler can read the
> value in fifteen pieces, randomly mixing one bit or five. Nobody
> cares.
If you read Documentation/memory-barriers.txt you'll find that it very
much also is about reading it in one go.
"The ACCESS_ONCE() function can prevent any number of optimizations that,
while perfectly safe in single-threaded code, can be fatal in concurrent
code. Here are some examples of these sorts of optimizations:
...
(*) For aligned memory locations whose size allows them to be accessed
with a single memory-reference instruction, prevents "load tearing"
and "store tearing," ..."
There are many places in the kernel where we rely and use ACCESS_ONCE()
in order to 'guarantee' single loads. Paul is the expert here, but from
what I understand the compiler is not allowed to split loads for
volatile reads (assuming the load is both naturally aligned and of
machine word size).
And the size check in READ_ONCE() helps asserting this.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 16:15 ` Linus Torvalds
2015-03-26 16:21 ` Linus Torvalds
2015-03-26 16:28 ` Peter Zijlstra
@ 2015-03-26 17:24 ` Christian Borntraeger
2015-03-26 17:52 ` Linus Torvalds
2 siblings, 1 reply; 22+ messages in thread
From: Christian Borntraeger @ 2015-03-26 17:24 UTC (permalink / raw)
To: Linus Torvalds, Peter Zijlstra
Cc: Will Deacon, Stephen Rothwell, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, linux-next@vger.kernel.org,
linux-kernel@vger.kernel.org, Davidlohr Bueso, Paul McKenney
Am 26.03.2015 um 17:15 schrieb Linus Torvalds:
> On Thu, Mar 26, 2015 at 7:22 AM, Peter Zijlstra <peterz@infradead.org> wrote:
>>
>> So we can either just remove the READ_ONCE(), or replace it with a
>> leading barrier() call just to be on the paranoid side of things.
>
> NOOO!
>
>> Any preferences?
>
> Not a preference: a _requirement_.
>
> Get rid of the f*cking size checks etc on READ_ONCE() and friends.
Oh I just added that check back then because some guy named
Linus suggested something like that ;-)
--- snip ---
(Btw, it's not just aggregate types, even non-aggregate types like
"long long" are not necessarily safe, to give the same 64-bit on
x86-32 example. So adding an assert that it's smaller or equal in size
to a "long" might also not be unreasonable)
--- snip ---
https://www.marc.info/?l=linux-kernel&m=141565366209769&w=1
I am fine with Peters patch :-)
Christian
>
> They are about - wait for it - "reading a value once".
>
> Note how it doesn't say ANYTHING about "atomic" or anything like that.
> It's about reading *ONCE*.
>
>> Something like so, but with a sensible comment I suppose.
>
> Hell f*cking no. The "something like so" is huge and utter crap,
> because the barrier is on the wrong side.
>
>> - old.lock_count = READ_ONCE(lockref->lock_count); \
>> + barrier(); \
>> + old.lock_count = lockref->lock_count; \
>> while (likely(arch_spin_value_unlocked(old.lock.rlock.raw_lock))) { \
>> struct lockref new = old, prev = old; \
>
> The WHOLE point of the READ_ONCE (formerly ACCESS_ONCE) is that it
> tells the compiler that it cannot reload the value.
>
> Notice how it is *not* about atomicitiy. The compiler can read the
> value in fifteen pieces, randomly mixing one bit or five. Nobody
> cares.
>
> But the important thing is that ONCE IT IS READ, it is never read
> again. That's the "once" part.
>
> Why is that important? It's important because we have to absolutely
> guartantee that the value we *test* is the same value we use later.
> That's a common concern with mutable variables, and is the only reason
> for READ_ONCE() in the first place.
>
> The whole atomicity etc crap was just that - crap. It was never about
> atomicitiy. It was about the compiler not reloading values.
>
> So no. No barriers. No "removal of READ_ONCE". Just get rid of the
> broken "sanity" checks in the READ_ONCE implementation that are just
> pure garbage.
>
> The checks in ACCESS_ONCE() were because apparently gcc got things
> wrong - dropping the volatile - for aggregate types. They were never
> supposed to be about atomicity, even if there clearly was some
> confusion about that.
>
> Really. Just get rid of the checks - they were wrong. They were
> clearly very close to *introducing* a bug, rather than fixing anything
> at all.
>
> Linus
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 17:24 ` Christian Borntraeger
@ 2015-03-26 17:52 ` Linus Torvalds
2015-03-26 18:54 ` Christian Borntraeger
0 siblings, 1 reply; 22+ messages in thread
From: Linus Torvalds @ 2015-03-26 17:52 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Peter Zijlstra, Will Deacon, Stephen Rothwell, Thomas Gleixner,
Ingo Molnar, H. Peter Anvin, linux-next@vger.kernel.org,
linux-kernel@vger.kernel.org, Davidlohr Bueso, Paul McKenney
On Thu, Mar 26, 2015 at 10:24 AM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
>
> Oh I just added that check back then because some guy named
> Linus suggested something like that ;-)
Yes, my bad.
In my defense, that was when we were talking about ACCESS_ONCE()
causing bugs with gcc due to the blind use of "volatile" that it turns
out gcc doesn't necessarily like.
With the memcpy fallback (and the simpler "scalar pointer copy by
hand"), I think READ_ONCE() (and WRITE_ONCE()) are safe.
Linus
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: linux-next: build warnings after merge of the access_once tree
2015-03-26 17:52 ` Linus Torvalds
@ 2015-03-26 18:54 ` Christian Borntraeger
0 siblings, 0 replies; 22+ messages in thread
From: Christian Borntraeger @ 2015-03-26 18:54 UTC (permalink / raw)
To: Linus Torvalds
Cc: Peter Zijlstra, Will Deacon, Stephen Rothwell, Thomas Gleixner,
Ingo Molnar, H. Peter Anvin, linux-next@vger.kernel.org,
linux-kernel@vger.kernel.org, Davidlohr Bueso, Paul McKenney
Am 26.03.2015 um 18:52 schrieb Linus Torvalds:
> On Thu, Mar 26, 2015 at 10:24 AM, Christian Borntraeger
> <borntraeger@de.ibm.com> wrote:
>>
>> Oh I just added that check back then because some guy named
>> Linus suggested something like that ;-)
>
> Yes, my bad.
>
> In my defense, that was when we were talking about ACCESS_ONCE()
> causing bugs with gcc due to the blind use of "volatile" that it turns
> out gcc doesn't necessarily like.
>
> With the memcpy fallback (and the simpler "scalar pointer copy by
> hand"), I think READ_ONCE() (and WRITE_ONCE()) are safe.
>
> Linus
>
FWIW, I dropped the warning fixp patch from my linux-next branch so
everything should be back to normal and we can merge Peters patch for 4.0 or
4.1.
Christian
^ permalink raw reply [flat|nested] 22+ messages in thread