Commit d57f7272 authored by Vineet Gupta's avatar Vineet Gupta

ARC: add compiler barrier to LLSC based cmpxchg

When auditing cmpxchg call sites, Chuck noted that gcc was optimizing
away some of the desired LDs.

|	do {
|		new = old = *ipi_data_ptr;
|		new |= 1U << msg;
|	} while (cmpxchg(ipi_data_ptr, old, new) != old);

was generating to below

| 8015cef8:	ld         r2,[r4,0]  <-- First LD
| 8015cefc:	bset       r1,r2,r1
|
| 8015cf00:	llock      r3,[r4]  <-- atomic op
| 8015cf04:	brne       r3,r2,8015cf10
| 8015cf08:	scond      r1,[r4]
| 8015cf0c:	bnz        8015cf00
|
| 8015cf10:	brne       r3,r2,8015cf00  <-- Branch doesn't go to orig LD

Although this was fixed by adding a ACCESS_ONCE in this call site, it
seems safer (for now at least) to add compiler barrier to LLSC based
cmpxchg
Reported-by: default avatarChuck Jordan <cjordan@synopsys,com>
Cc: <stable@vger.kernel.org>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent eaf0ecc3
...@@ -25,10 +25,11 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) ...@@ -25,10 +25,11 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
" scond %3, [%1] \n" " scond %3, [%1] \n"
" bnz 1b \n" " bnz 1b \n"
"2: \n" "2: \n"
: "=&r"(prev) : "=&r"(prev) /* Early clobber, to prevent reg reuse */
: "r"(ptr), "ir"(expected), : "r"(ptr), /* Not "m": llock only supports reg direct addr mode */
"r"(new) /* can't be "ir". scond can't take limm for "b" */ "ir"(expected),
: "cc"); "r"(new) /* can't be "ir". scond can't take LIMM for "b" */
: "cc", "memory"); /* so that gcc knows memory is being written here */
return prev; return prev;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment