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();			\
 	}						\

Reply via email to