|
@@ -128,10 +128,9 @@ ____xchg(, volatile void *ptr, unsigned long x, int size)
|
|
|
* store NEW in MEM. Return the initial value in MEM. Success is
|
|
|
* indicated by comparing RETURN with OLD.
|
|
|
*
|
|
|
- * The memory barrier should be placed in SMP only when we actually
|
|
|
- * make the change. If we don't change anything (so if the returned
|
|
|
- * prev is equal to old) then we aren't acquiring anything new and
|
|
|
- * we don't need any memory barrier as far I can tell.
|
|
|
+ * The memory barrier is placed in SMP unconditionally, in order to
|
|
|
+ * guarantee that dependency ordering is preserved when a dependency
|
|
|
+ * is headed by an unsuccessful operation.
|
|
|
*/
|
|
|
|
|
|
static inline unsigned long
|
|
@@ -150,8 +149,8 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
|
|
|
" or %1,%2,%2\n"
|
|
|
" stq_c %2,0(%4)\n"
|
|
|
" beq %2,3f\n"
|
|
|
- __ASM__MB
|
|
|
"2:\n"
|
|
|
+ __ASM__MB
|
|
|
".subsection 2\n"
|
|
|
"3: br 1b\n"
|
|
|
".previous"
|
|
@@ -177,8 +176,8 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
|
|
|
" or %1,%2,%2\n"
|
|
|
" stq_c %2,0(%4)\n"
|
|
|
" beq %2,3f\n"
|
|
|
- __ASM__MB
|
|
|
"2:\n"
|
|
|
+ __ASM__MB
|
|
|
".subsection 2\n"
|
|
|
"3: br 1b\n"
|
|
|
".previous"
|
|
@@ -200,8 +199,8 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
|
|
|
" mov %4,%1\n"
|
|
|
" stl_c %1,%2\n"
|
|
|
" beq %1,3f\n"
|
|
|
- __ASM__MB
|
|
|
"2:\n"
|
|
|
+ __ASM__MB
|
|
|
".subsection 2\n"
|
|
|
"3: br 1b\n"
|
|
|
".previous"
|
|
@@ -223,8 +222,8 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
|
|
|
" mov %4,%1\n"
|
|
|
" stq_c %1,%2\n"
|
|
|
" beq %1,3f\n"
|
|
|
- __ASM__MB
|
|
|
"2:\n"
|
|
|
+ __ASM__MB
|
|
|
".subsection 2\n"
|
|
|
"3: br 1b\n"
|
|
|
".previous"
|