On Wed, Feb 27, 2019 at 2:16 AM Peter Zijlstra <pet...@infradead.org> wrote: > > Nadav Amit reported that commit: > > b59167ac7baf ("x86/percpu: Fix this_cpu_read()") > > added a bunch of constraints to all sorts of code; and while some of > that was correct and desired, some of that seems superfluous.
Hmm. I have the strong feeling that we should instead relax this_cpu_read() again a bit. In particular, making it "asm volatile" really is a big hammer approach. It's worth noting that the *other* this_cpu_xyz ops don't even do that. I would suggest that instead of making "this_cpu_read()" be asm volatile, we mark it as potentially changing the memory location it is touching - the same way the modify/write ops do. That still means that the read will be forced (like READ_ONCE()), but allows gcc a bit more flexibility in instruction scheduling, I think. Trivial (but entirely untested) patch attached. That said, I didn't actually check how it affects code generation. Nadav, would you check the code sequences you originally noticed? Linus
arch/x86/include/asm/percpu.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 1a19d11cfbbd..63b0f361533f 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -185,24 +185,24 @@ do { \ typeof(var) pfo_ret__; \ switch (sizeof(var)) { \ case 1: \ - asm volatile(op "b "__percpu_arg(1)",%0"\ - : "=q" (pfo_ret__) \ - : "m" (var)); \ + asm(op "b "__percpu_arg(1)",%0"\ + : "=q" (pfo_ret__), \ + "+m" (var)); \ break; \ case 2: \ - asm volatile(op "w "__percpu_arg(1)",%0"\ - : "=r" (pfo_ret__) \ - : "m" (var)); \ + asm(op "w "__percpu_arg(1)",%0"\ + : "=r" (pfo_ret__), \ + "+m" (var)); \ break; \ case 4: \ - asm volatile(op "l "__percpu_arg(1)",%0"\ - : "=r" (pfo_ret__) \ - : "m" (var)); \ + asm(op "l "__percpu_arg(1)",%0"\ + : "=r" (pfo_ret__), \ + "+m" (var)); \ break; \ case 8: \ - asm volatile(op "q "__percpu_arg(1)",%0"\ - : "=r" (pfo_ret__) \ - : "m" (var)); \ + asm(op "q "__percpu_arg(1)",%0"\ + : "=r" (pfo_ret__), \ + "+m" (var)); \ break; \ default: __bad_percpu_size(); \ } \