Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Improve atomic.h robustness

I've maintained this patch, originally from Thiemo Seufer in 2004, for a
really long time, but I think it's time for it to get a look at for
possible inclusion. I have had no problems with it across various SGI
systems over the years.

To quote the post here:
http://www.linux-mips.org/archives/linux-mips/2004-12/msg00000.html

"the atomic functions use so far memory references for the inline
assembler to access the semaphore. This can lead to additional
instructions in the ll/sc loop, because newer compilers don't
expand the memory reference any more but leave it to the assembler.

The appended patch uses registers instead, and makes the ll/sc
arguments more explicit. In some cases it will lead also to better
register scheduling because the register isn't bound to an output
any more."

Signed-off-by: Joshua Kinard <kumba@gentoo.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/4029/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Joshua Kinard and committed by
Ralf Baechle
b4f2a17b 12250d84

+29 -35
+29 -35
arch/mips/include/asm/atomic.h
··· 59 59 " sc %0, %1 \n" 60 60 " beqzl %0, 1b \n" 61 61 " .set mips0 \n" 62 - : "=&r" (temp), "=m" (v->counter) 63 - : "Ir" (i), "m" (v->counter)); 62 + : "=&r" (temp), "+m" (v->counter) 63 + : "Ir" (i)); 64 64 } else if (kernel_uses_llsc) { 65 65 int temp; 66 66 ··· 71 71 " addu %0, %2 \n" 72 72 " sc %0, %1 \n" 73 73 " .set mips0 \n" 74 - : "=&r" (temp), "=m" (v->counter) 75 - : "Ir" (i), "m" (v->counter)); 74 + : "=&r" (temp), "+m" (v->counter) 75 + : "Ir" (i)); 76 76 } while (unlikely(!temp)); 77 77 } else { 78 78 unsigned long flags; ··· 102 102 " sc %0, %1 \n" 103 103 " beqzl %0, 1b \n" 104 104 " .set mips0 \n" 105 - : "=&r" (temp), "=m" (v->counter) 106 - : "Ir" (i), "m" (v->counter)); 105 + : "=&r" (temp), "+m" (v->counter) 106 + : "Ir" (i)); 107 107 } else if (kernel_uses_llsc) { 108 108 int temp; 109 109 ··· 114 114 " subu %0, %2 \n" 115 115 " sc %0, %1 \n" 116 116 " .set mips0 \n" 117 - : "=&r" (temp), "=m" (v->counter) 118 - : "Ir" (i), "m" (v->counter)); 117 + : "=&r" (temp), "+m" (v->counter) 118 + : "Ir" (i)); 119 119 } while (unlikely(!temp)); 120 120 } else { 121 121 unsigned long flags; ··· 146 146 " beqzl %0, 1b \n" 147 147 " addu %0, %1, %3 \n" 148 148 " .set mips0 \n" 149 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 150 - : "Ir" (i), "m" (v->counter) 151 - : "memory"); 149 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 150 + : "Ir" (i)); 152 151 } else if (kernel_uses_llsc) { 153 152 int temp; 154 153 ··· 158 159 " addu %0, %1, %3 \n" 159 160 " sc %0, %2 \n" 160 161 " .set mips0 \n" 161 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 162 - : "Ir" (i), "m" (v->counter) 163 - : "memory"); 162 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 163 + : "Ir" (i)); 164 164 } while (unlikely(!result)); 165 165 166 166 result = temp + i; ··· 210 212 " subu %0, %1, %3 \n" 211 213 " sc %0, %2 \n" 212 214 " .set mips0 \n" 213 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 214 - : "Ir" (i), "m" (v->counter) 215 - : "memory"); 215 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 216 + : "Ir" (i)); 216 217 } while (unlikely(!result)); 217 218 218 219 result = temp - i; ··· 259 262 " .set reorder \n" 260 263 "1: \n" 261 264 " .set mips0 \n" 262 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 265 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 263 266 : "Ir" (i), "m" (v->counter) 264 267 : "memory"); 265 268 } else if (kernel_uses_llsc) { ··· 277 280 " .set reorder \n" 278 281 "1: \n" 279 282 " .set mips0 \n" 280 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 281 - : "Ir" (i), "m" (v->counter) 282 - : "memory"); 283 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 284 + : "Ir" (i)); 283 285 } else { 284 286 unsigned long flags; 285 287 ··· 426 430 " scd %0, %1 \n" 427 431 " beqzl %0, 1b \n" 428 432 " .set mips0 \n" 429 - : "=&r" (temp), "=m" (v->counter) 430 - : "Ir" (i), "m" (v->counter)); 433 + : "=&r" (temp), "+m" (v->counter) 434 + : "Ir" (i)); 431 435 } else if (kernel_uses_llsc) { 432 436 long temp; 433 437 ··· 438 442 " daddu %0, %2 \n" 439 443 " scd %0, %1 \n" 440 444 " .set mips0 \n" 441 - : "=&r" (temp), "=m" (v->counter) 442 - : "Ir" (i), "m" (v->counter)); 445 + : "=&r" (temp), "+m" (v->counter) 446 + : "Ir" (i)); 443 447 } while (unlikely(!temp)); 444 448 } else { 445 449 unsigned long flags; ··· 469 473 " scd %0, %1 \n" 470 474 " beqzl %0, 1b \n" 471 475 " .set mips0 \n" 472 - : "=&r" (temp), "=m" (v->counter) 473 - : "Ir" (i), "m" (v->counter)); 476 + : "=&r" (temp), "+m" (v->counter) 477 + : "Ir" (i)); 474 478 } else if (kernel_uses_llsc) { 475 479 long temp; 476 480 ··· 481 485 " dsubu %0, %2 \n" 482 486 " scd %0, %1 \n" 483 487 " .set mips0 \n" 484 - : "=&r" (temp), "=m" (v->counter) 485 - : "Ir" (i), "m" (v->counter)); 488 + : "=&r" (temp), "+m" (v->counter) 489 + : "Ir" (i)); 486 490 } while (unlikely(!temp)); 487 491 } else { 488 492 unsigned long flags; ··· 513 517 " beqzl %0, 1b \n" 514 518 " daddu %0, %1, %3 \n" 515 519 " .set mips0 \n" 516 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 517 - : "Ir" (i), "m" (v->counter) 518 - : "memory"); 520 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 521 + : "Ir" (i)); 519 522 } else if (kernel_uses_llsc) { 520 523 long temp; 521 524 ··· 644 649 " .set reorder \n" 645 650 "1: \n" 646 651 " .set mips0 \n" 647 - : "=&r" (result), "=&r" (temp), "=m" (v->counter) 648 - : "Ir" (i), "m" (v->counter) 649 - : "memory"); 652 + : "=&r" (result), "=&r" (temp), "+m" (v->counter) 653 + : "Ir" (i)); 650 654 } else { 651 655 unsigned long flags; 652 656