* patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
@ 2006-10-12 18:03 bile
2006-10-13 10:42 ` Ralf Baechle
0 siblings, 1 reply; 9+ messages in thread
From: bile @ 2006-10-12 18:03 UTC (permalink / raw)
To: linux-mips
In include/asm-mips/system.h __cmpxchg_u64 is doing
if(cpu_has_llsc) {
} else if(cpu_has_llsc) {
the first should be (cpu_has_llsc && R10000_LLSC_WAR).
While this probably gets cleaned up during optimization I took
the liberty of cleaning up the code along with the fix so it's
not doing the double check and only includes the R10000 workaround
at compile time.
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index dcb4701..bfae6ff 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -206,7 +206,7 @@ static inline unsigned long __xchg_u32(v
{
__u32 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
+ if (cpu_has_llsc) {
unsigned long dummy;
__asm__ __volatile__(
@@ -216,25 +216,11 @@ static inline unsigned long __xchg_u32(v
" move %2, %z4 \n"
" .set mips3 \n"
" sc %2, %1 \n"
+#ifdef R10000_LLSC_WAR
" beqzl %2, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
- " .set mips0 \n"
- : "=&r" (retval), "=m" (*m), "=&r" (dummy)
- : "R" (*m), "Jr" (val)
- : "memory");
- } else if (cpu_has_llsc) {
- unsigned long dummy;
-
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %0, %3 # xchg_u32 \n"
- " .set mips0 \n"
- " move %2, %z4 \n"
- " .set mips3 \n"
- " sc %2, %1 \n"
+#else
" beqz %2, 1b \n"
+#endif
#ifdef CONFIG_SMP
" sync \n"
#endif
@@ -259,7 +245,7 @@ static inline __u64 __xchg_u64(volatile
{
__u64 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
+ if (cpu_has_llsc) {
unsigned long dummy;
__asm__ __volatile__(
@@ -267,23 +253,11 @@ static inline __u64 __xchg_u64(volatile
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
+#ifdef R10000_LLSC_WAR
" beqzl %2, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
- " .set mips0 \n"
- : "=&r" (retval), "=m" (*m), "=&r" (dummy)
- : "R" (*m), "Jr" (val)
- : "memory");
- } else if (cpu_has_llsc) {
- unsigned long dummy;
-
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: lld %0, %3 # xchg_u64 \n"
- " move %2, %z4 \n"
- " scd %2, %1 \n"
+#else
" beqz %2, 1b \n"
+#endif
#ifdef CONFIG_SMP
" sync \n"
#endif
@@ -333,7 +307,7 @@ static inline unsigned long __cmpxchg_u3
{
__u32 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
+ if (cpu_has_llsc) {
__asm__ __volatile__(
" .set push \n"
" .set noat \n"
@@ -344,27 +318,11 @@ static inline unsigned long __cmpxchg_u3
" move $1, %z4 \n"
" .set mips3 \n"
" sc $1, %1 \n"
+#ifdef R10000_LLSC_WAR
" beqzl $1, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
- "2: \n"
- " .set pop \n"
- : "=&r" (retval), "=R" (*m)
- : "R" (*m), "Jr" (old), "Jr" (new)
- : "memory");
- } else if (cpu_has_llsc) {
- __asm__ __volatile__(
- " .set push \n"
- " .set noat \n"
- " .set mips3 \n"
- "1: ll %0, %2 # __cmpxchg_u32 \n"
- " bne %0, %z3, 2f \n"
- " .set mips0 \n"
- " move $1, %z4 \n"
- " .set mips3 \n"
- " sc $1, %1 \n"
- " beqz $1, 1b \n"
+#else
+ " beqz $1, 1b \n"
+#endif
#ifdef CONFIG_SMP
" sync \n"
#endif
@@ -401,25 +359,11 @@ static inline unsigned long __cmpxchg_u6
" bne %0, %z3, 2f \n"
" move $1, %z4 \n"
" scd $1, %1 \n"
+#ifdef R10000_LLSC_WAR
" beqzl $1, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
- "2: \n"
- " .set pop \n"
- : "=&r" (retval), "=R" (*m)
- : "R" (*m), "Jr" (old), "Jr" (new)
- : "memory");
- } else if (cpu_has_llsc) {
- __asm__ __volatile__(
- " .set push \n"
- " .set noat \n"
- " .set mips3 \n"
- "1: lld %0, %2 # __cmpxchg_u64 \n"
- " bne %0, %z3, 2f \n"
- " move $1, %z4 \n"
- " scd $1, %1 \n"
+#else
" beqz $1, 1b \n"
+#endif
#ifdef CONFIG_SMP
" sync \n"
#endif
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-12 18:03 patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup bile
@ 2006-10-13 10:42 ` Ralf Baechle
2006-10-13 13:53 ` Antonio SJ Musumeci
0 siblings, 1 reply; 9+ messages in thread
From: Ralf Baechle @ 2006-10-13 10:42 UTC (permalink / raw)
To: bile; +Cc: linux-mips
On Thu, Oct 12, 2006 at 02:03:39PM -0400, bile@landofbile.com wrote:
> In include/asm-mips/system.h __cmpxchg_u64 is doing
>
> if(cpu_has_llsc) {
> } else if(cpu_has_llsc) {
>
> the first should be (cpu_has_llsc && R10000_LLSC_WAR).
>
> While this probably gets cleaned up during optimization I took
> the liberty of cleaning up the code along with the fix so it's
> not doing the double check and only includes the R10000 workaround
> at compile time.
Please include a Signed-off-by: line when submitting patches.
> diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
> index dcb4701..bfae6ff 100644
> --- a/include/asm-mips/system.h
> +++ b/include/asm-mips/system.h
> @@ -206,7 +206,7 @@ static inline unsigned long __xchg_u32(v
> {
> __u32 retval;
>
> - if (cpu_has_llsc && R10000_LLSC_WAR) {
> + if (cpu_has_llsc) {
Thanks for spotting this one.
> @@ -216,25 +216,11 @@ static inline unsigned long __xchg_u32(v
> " move %2, %z4 \n"
> " .set mips3 \n"
> " sc %2, %1 \n"
> +#ifdef R10000_LLSC_WAR
This isn't quite right since R10000_LLSC_WAR is defined to 0 if the
workaround is not enabled, so "#if R10000_LLSC_WAR" would be needed
here.
> " beqzl %2, 1b \n"
> -#ifdef CONFIG_SMP
> - " sync \n"
> -#endif
Now the real reason why I don't want to apply your patch is below patch
which is playing fancy tricks with the branch prediction of modern
processors. The R10000 ll/sc workaround _relies_ on the missprediction
of the branch likely branch to work correctly, so this optimization
could not be applied to it that is we need two different versions.
Ralf
commit 23d60625d8a383a7faf632a50c2298c9c65aa0b2
Author: Ralf Baechle <ralf@linux-mips.org>
Date: Thu Sep 28 01:45:21 2006 +0100
[MIPS] Improve branch prediction in ll/sc atomic operations.
Now that finally all supported versions of binutils have functioning
support for .subsection use .subsection to tweak the branch prediction
I did not modify the R10000 errata variants because it seems unclear if
this will invalidate the workaround which actually relies on the cheesy
prediction of branch likely to cause a misspredict if the sc was
successful.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index e64abc0..91bf6a7 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -9,7 +9,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1996, 97, 99, 2000, 03, 04 by Ralf Baechle
+ * Copyright (C) 1996, 97, 99, 2000, 03, 04, 06 Ralf Baechle
*/
/*
@@ -76,7 +76,10 @@ static __inline__ void atomic_add(int i,
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
@@ -118,7 +121,10 @@ static __inline__ void atomic_sub(int i,
"1: ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
@@ -161,9 +167,12 @@ static __inline__ int atomic_add_return(
"1: ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -208,9 +217,12 @@ static __inline__ int atomic_sub_return(
"1: ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -269,11 +281,14 @@ static __inline__ int atomic_sub_if_posi
" bltz %0, 1f \n"
" sc %0, %2 \n"
" .set noreorder \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
" subu %0, %1, %3 \n"
" .set reorder \n"
" sync \n"
"1: \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -430,7 +445,10 @@ static __inline__ void atomic64_add(long
"1: lld %0, %1 # atomic64_add \n"
" addu %0, %2 \n"
" scd %0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
@@ -472,7 +490,10 @@ static __inline__ void atomic64_sub(long
"1: lld %0, %1 # atomic64_sub \n"
" subu %0, %2 \n"
" scd %0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
@@ -515,9 +536,12 @@ static __inline__ long atomic64_add_retu
"1: lld %1, %2 # atomic64_add_return \n"
" addu %0, %1, %3 \n"
" scd %0, %2 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -562,9 +586,12 @@ static __inline__ long atomic64_sub_retu
"1: lld %1, %2 # atomic64_sub_return \n"
" subu %0, %1, %3 \n"
" scd %0, %2 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -623,11 +650,14 @@ static __inline__ long atomic64_sub_if_p
" bltz %0, 1f \n"
" scd %0, %2 \n"
" .set noreorder \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
" dsubu %0, %1, %3 \n"
" .set reorder \n"
" sync \n"
"1: \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 1bb89c5..d10bd56 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 1994 - 1997, 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (c) 1994 - 1997, 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
* Copyright (c) 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_BITOPS_H
@@ -86,7 +86,10 @@ static inline void set_bit(unsigned long
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
" " __SC "%0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
@@ -134,7 +137,10 @@ static inline void clear_bit(unsigned lo
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
@@ -184,7 +190,10 @@ static inline void change_bit(unsigned l
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
" " __SC "%0, %1 \n"
- " beqz %0, 1b \n"
+ " beqz %0, 2f \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
@@ -243,11 +252,14 @@ #endif
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
- " beqz %2, 1b \n"
+ " beqz %2, 2f \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -315,11 +327,14 @@ #endif
" or %2, %0, %3 \n"
" xor %2, %3 \n"
" " __SC "%2, %1 \n"
- " beqz %2, 1b \n"
+ " beqz %2, 2f \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -385,11 +400,14 @@ #endif
"1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
" " __SC "\t%2, %1 \n"
- " beqz %2, 1b \n"
+ " beqz %2, 2f \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index 4c1a1b5..3df6103 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_SPINLOCK_H
@@ -49,11 +49,18 @@ static inline void __raw_spin_lock(raw_s
__asm__ __volatile__(
" .set noreorder # __raw_spin_lock \n"
"1: ll %1, %2 \n"
- " bnez %1, 1b \n"
+ " bnez %1, 2f \n"
" li %1, 1 \n"
" sc %1, %0 \n"
- " beqz %1, 1b \n"
+ " beqz %1, 2f \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: ll %1, %2 \n"
+ " bnez %1, 2b \n"
+ " li %1, 1 \n"
+ " b 1b \n"
+ " nop \n"
+ " .previous \n"
" .set reorder \n"
: "=m" (lock->lock), "=&r" (tmp)
: "m" (lock->lock)
@@ -97,9 +104,12 @@ static inline unsigned int __raw_spin_tr
"1: ll %0, %3 \n"
" ori %2, %0, 1 \n"
" sc %2, %1 \n"
- " beqz %2, 1b \n"
+ " beqz %2, 2f \n"
" andi %2, %0, 1 \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set reorder"
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
: "m" (lock->lock)
@@ -152,11 +162,17 @@ static inline void __raw_read_lock(raw_r
__asm__ __volatile__(
" .set noreorder # __raw_read_lock \n"
"1: ll %1, %2 \n"
- " bltz %1, 1b \n"
+ " bltz %1, 2f \n"
" addu %1, 1 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: ll %1, %2 \n"
+ " bltz %1, 2b \n"
+ " addu %1, 1 \n"
+ " b 1b \n"
+ " .previous \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -187,8 +203,10 @@ static inline void __raw_read_unlock(raw
"1: ll %1, %2 \n"
" sub %1, 1 \n"
" sc %1, %0 \n"
- " beqz %1, 1b \n"
+ " beqz %1, 2f \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -217,11 +235,17 @@ static inline void __raw_write_lock(raw_
__asm__ __volatile__(
" .set noreorder # __raw_write_lock \n"
"1: ll %1, %2 \n"
- " bnez %1, 1b \n"
+ " bnez %1, 2f \n"
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
- " beqz %1, 1b \n"
+ " beqz %1, 2f \n"
" sync \n"
+ " .subsection 2 \n"
+ "2: ll %1, %2 \n"
+ " bnez %1, 1b \n"
+ " lui %1, 0x8000 \n"
+ " b 1b \n"
+ " .previous \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -314,11 +338,15 @@ static inline int __raw_write_trylock(ra
" bnez %1, 2f \n"
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
- " beqz %1, 1b \n"
- " sync \n"
- " li %2, 1 \n"
- " .set reorder \n"
+ " beqz %1, 3f \n"
+ " li %2, 1 \n"
"2: \n"
+ " sync \n"
+ " .subsection 2 \n"
+ "3: b 1b \n"
+ " li %2, 0 \n"
+ " .previous \n"
+ " .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
: "m" (rw->lock)
: "memory");
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index dcb4701..fc35526 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
* Copyright (C) 1996 by Paul M. Antoine
* Copyright (C) 1999 Silicon Graphics
* Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
@@ -234,10 +234,13 @@ #endif
" move %2, %z4 \n"
" .set mips3 \n"
" sc %2, %1 \n"
- " beqz %2, 1b \n"
+ " beqz %2, 2f \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
@@ -283,10 +286,13 @@ #endif
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
- " beqz %2, 1b \n"
+ " beqz %2, 2f \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " .previous \n"
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
@@ -364,11 +370,14 @@ #endif
" move $1, %z4 \n"
" .set mips3 \n"
" sc $1, %1 \n"
- " beqz $1, 1b \n"
+ " beqz $1, 3f \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
+ " .subsection 2 \n"
+ "3: b 1b \n"
+ " .previous \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
@@ -419,11 +428,14 @@ #endif
" bne %0, %z3, 2f \n"
" move $1, %z4 \n"
" scd $1, %1 \n"
- " beqz $1, 1b \n"
+ " beqz $1, 3f \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
+ " .subsection 2 \n"
+ "3: b 1b \n"
+ " .previous \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-13 10:42 ` Ralf Baechle
@ 2006-10-13 13:53 ` Antonio SJ Musumeci
2006-10-13 14:11 ` Ralf Baechle
0 siblings, 1 reply; 9+ messages in thread
From: Antonio SJ Musumeci @ 2006-10-13 13:53 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Should I apply my patch on top of this one?
Ralf Baechle wrote:
> On Thu, Oct 12, 2006 at 02:03:39PM -0400, bile@landofbile.com wrote:
>
>> In include/asm-mips/system.h __cmpxchg_u64 is doing
>>
>> if(cpu_has_llsc) {
>> } else if(cpu_has_llsc) {
>>
>> the first should be (cpu_has_llsc && R10000_LLSC_WAR).
>>
>> While this probably gets cleaned up during optimization I took
>> the liberty of cleaning up the code along with the fix so it's
>> not doing the double check and only includes the R10000 workaround
>> at compile time.
>
> Please include a Signed-off-by: line when submitting patches.
>
>> diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
>> index dcb4701..bfae6ff 100644
>> --- a/include/asm-mips/system.h
>> +++ b/include/asm-mips/system.h
>> @@ -206,7 +206,7 @@ static inline unsigned long __xchg_u32(v
>> {
>> __u32 retval;
>>
>> - if (cpu_has_llsc && R10000_LLSC_WAR) {
>> + if (cpu_has_llsc) {
>
> Thanks for spotting this one.
>
>> @@ -216,25 +216,11 @@ static inline unsigned long __xchg_u32(v
>> " move %2, %z4 \n"
>> " .set mips3 \n"
>> " sc %2, %1 \n"
>> +#ifdef R10000_LLSC_WAR
>
> This isn't quite right since R10000_LLSC_WAR is defined to 0 if the
> workaround is not enabled, so "#if R10000_LLSC_WAR" would be needed
> here.
>
>> " beqzl %2, 1b \n"
>> -#ifdef CONFIG_SMP
>> - " sync \n"
>> -#endif
>
> Now the real reason why I don't want to apply your patch is below patch
> which is playing fancy tricks with the branch prediction of modern
> processors. The R10000 ll/sc workaround _relies_ on the missprediction
> of the branch likely branch to work correctly, so this optimization
> could not be applied to it that is we need two different versions.
>
> Ralf
>
> commit 23d60625d8a383a7faf632a50c2298c9c65aa0b2
> Author: Ralf Baechle <ralf@linux-mips.org>
> Date: Thu Sep 28 01:45:21 2006 +0100
>
> [MIPS] Improve branch prediction in ll/sc atomic operations.
>
> Now that finally all supported versions of binutils have functioning
> support for .subsection use .subsection to tweak the branch prediction
>
> I did not modify the R10000 errata variants because it seems unclear if
> this will invalidate the workaround which actually relies on the cheesy
> prediction of branch likely to cause a misspredict if the sc was
> successful.
>
> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
>
> diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
> index e64abc0..91bf6a7 100644
> --- a/include/asm-mips/atomic.h
> +++ b/include/asm-mips/atomic.h
> @@ -9,7 +9,7 @@
> * License. See the file "COPYING" in the main directory of this archive
> * for more details.
> *
> - * Copyright (C) 1996, 97, 99, 2000, 03, 04 by Ralf Baechle
> + * Copyright (C) 1996, 97, 99, 2000, 03, 04, 06 Ralf Baechle
> */
>
> /*
> @@ -76,7 +76,10 @@ static __inline__ void atomic_add(int i,
> "1: ll %0, %1 # atomic_add \n"
> " addu %0, %2 \n"
> " sc %0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter));
> @@ -118,7 +121,10 @@ static __inline__ void atomic_sub(int i,
> "1: ll %0, %1 # atomic_sub \n"
> " subu %0, %2 \n"
> " sc %0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter));
> @@ -161,9 +167,12 @@ static __inline__ int atomic_add_return(
> "1: ll %1, %2 # atomic_add_return \n"
> " addu %0, %1, %3 \n"
> " sc %0, %2 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> " addu %0, %1, %3 \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (result), "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter)
> @@ -208,9 +217,12 @@ static __inline__ int atomic_sub_return(
> "1: ll %1, %2 # atomic_sub_return \n"
> " subu %0, %1, %3 \n"
> " sc %0, %2 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> " subu %0, %1, %3 \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (result), "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter)
> @@ -269,11 +281,14 @@ static __inline__ int atomic_sub_if_posi
> " bltz %0, 1f \n"
> " sc %0, %2 \n"
> " .set noreorder \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> " subu %0, %1, %3 \n"
> " .set reorder \n"
> " sync \n"
> "1: \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (result), "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter)
> @@ -430,7 +445,10 @@ static __inline__ void atomic64_add(long
> "1: lld %0, %1 # atomic64_add \n"
> " addu %0, %2 \n"
> " scd %0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter));
> @@ -472,7 +490,10 @@ static __inline__ void atomic64_sub(long
> "1: lld %0, %1 # atomic64_sub \n"
> " subu %0, %2 \n"
> " scd %0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter));
> @@ -515,9 +536,12 @@ static __inline__ long atomic64_add_retu
> "1: lld %1, %2 # atomic64_add_return \n"
> " addu %0, %1, %3 \n"
> " scd %0, %2 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> " addu %0, %1, %3 \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (result), "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter)
> @@ -562,9 +586,12 @@ static __inline__ long atomic64_sub_retu
> "1: lld %1, %2 # atomic64_sub_return \n"
> " subu %0, %1, %3 \n"
> " scd %0, %2 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> " subu %0, %1, %3 \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (result), "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter)
> @@ -623,11 +650,14 @@ static __inline__ long atomic64_sub_if_p
> " bltz %0, 1f \n"
> " scd %0, %2 \n"
> " .set noreorder \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> " dsubu %0, %1, %3 \n"
> " .set reorder \n"
> " sync \n"
> "1: \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (result), "=&r" (temp), "=m" (v->counter)
> : "Ir" (i), "m" (v->counter)
> diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
> index 1bb89c5..d10bd56 100644
> --- a/include/asm-mips/bitops.h
> +++ b/include/asm-mips/bitops.h
> @@ -3,7 +3,7 @@
> * License. See the file "COPYING" in the main directory of this archive
> * for more details.
> *
> - * Copyright (c) 1994 - 1997, 1999, 2000 Ralf Baechle (ralf@gnu.org)
> + * Copyright (c) 1994 - 1997, 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
> * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
> */
> #ifndef _ASM_BITOPS_H
> @@ -86,7 +86,10 @@ static inline void set_bit(unsigned long
> "1: " __LL "%0, %1 # set_bit \n"
> " or %0, %2 \n"
> " " __SC "%0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (*m)
> : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
> @@ -134,7 +137,10 @@ static inline void clear_bit(unsigned lo
> "1: " __LL "%0, %1 # clear_bit \n"
> " and %0, %2 \n"
> " " __SC "%0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (*m)
> : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
> @@ -184,7 +190,10 @@ static inline void change_bit(unsigned l
> "1: " __LL "%0, %1 # change_bit \n"
> " xor %0, %2 \n"
> " " __SC "%0, %1 \n"
> - " beqz %0, 1b \n"
> + " beqz %0, 2f \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (temp), "=m" (*m)
> : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
> @@ -243,11 +252,14 @@ #endif
> "1: " __LL "%0, %1 # test_and_set_bit \n"
> " or %2, %0, %3 \n"
> " " __SC "%2, %1 \n"
> - " beqz %2, 1b \n"
> + " beqz %2, 2f \n"
> " and %2, %0, %3 \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set pop \n"
> : "=&r" (temp), "=m" (*m), "=&r" (res)
> : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
> @@ -315,11 +327,14 @@ #endif
> " or %2, %0, %3 \n"
> " xor %2, %3 \n"
> " " __SC "%2, %1 \n"
> - " beqz %2, 1b \n"
> + " beqz %2, 2f \n"
> " and %2, %0, %3 \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set pop \n"
> : "=&r" (temp), "=m" (*m), "=&r" (res)
> : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
> @@ -385,11 +400,14 @@ #endif
> "1: " __LL "%0, %1 # test_and_change_bit \n"
> " xor %2, %0, %3 \n"
> " " __SC "\t%2, %1 \n"
> - " beqz %2, 1b \n"
> + " beqz %2, 2f \n"
> " and %2, %0, %3 \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set pop \n"
> : "=&r" (temp), "=m" (*m), "=&r" (res)
> : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
> diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
> index 4c1a1b5..3df6103 100644
> --- a/include/asm-mips/spinlock.h
> +++ b/include/asm-mips/spinlock.h
> @@ -3,7 +3,7 @@
> * License. See the file "COPYING" in the main directory of this archive
> * for more details.
> *
> - * Copyright (C) 1999, 2000 by Ralf Baechle
> + * Copyright (C) 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
> * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
> */
> #ifndef _ASM_SPINLOCK_H
> @@ -49,11 +49,18 @@ static inline void __raw_spin_lock(raw_s
> __asm__ __volatile__(
> " .set noreorder # __raw_spin_lock \n"
> "1: ll %1, %2 \n"
> - " bnez %1, 1b \n"
> + " bnez %1, 2f \n"
> " li %1, 1 \n"
> " sc %1, %0 \n"
> - " beqz %1, 1b \n"
> + " beqz %1, 2f \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: ll %1, %2 \n"
> + " bnez %1, 2b \n"
> + " li %1, 1 \n"
> + " b 1b \n"
> + " nop \n"
> + " .previous \n"
> " .set reorder \n"
> : "=m" (lock->lock), "=&r" (tmp)
> : "m" (lock->lock)
> @@ -97,9 +104,12 @@ static inline unsigned int __raw_spin_tr
> "1: ll %0, %3 \n"
> " ori %2, %0, 1 \n"
> " sc %2, %1 \n"
> - " beqz %2, 1b \n"
> + " beqz %2, 2f \n"
> " andi %2, %0, 1 \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set reorder"
> : "=&r" (temp), "=m" (lock->lock), "=&r" (res)
> : "m" (lock->lock)
> @@ -152,11 +162,17 @@ static inline void __raw_read_lock(raw_r
> __asm__ __volatile__(
> " .set noreorder # __raw_read_lock \n"
> "1: ll %1, %2 \n"
> - " bltz %1, 1b \n"
> + " bltz %1, 2f \n"
> " addu %1, 1 \n"
> " sc %1, %0 \n"
> " beqz %1, 1b \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: ll %1, %2 \n"
> + " bltz %1, 2b \n"
> + " addu %1, 1 \n"
> + " b 1b \n"
> + " .previous \n"
> " .set reorder \n"
> : "=m" (rw->lock), "=&r" (tmp)
> : "m" (rw->lock)
> @@ -187,8 +203,10 @@ static inline void __raw_read_unlock(raw
> "1: ll %1, %2 \n"
> " sub %1, 1 \n"
> " sc %1, %0 \n"
> - " beqz %1, 1b \n"
> + " beqz %1, 2f \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: b 1b \n"
> " .set reorder \n"
> : "=m" (rw->lock), "=&r" (tmp)
> : "m" (rw->lock)
> @@ -217,11 +235,17 @@ static inline void __raw_write_lock(raw_
> __asm__ __volatile__(
> " .set noreorder # __raw_write_lock \n"
> "1: ll %1, %2 \n"
> - " bnez %1, 1b \n"
> + " bnez %1, 2f \n"
> " lui %1, 0x8000 \n"
> " sc %1, %0 \n"
> - " beqz %1, 1b \n"
> + " beqz %1, 2f \n"
> " sync \n"
> + " .subsection 2 \n"
> + "2: ll %1, %2 \n"
> + " bnez %1, 1b \n"
> + " lui %1, 0x8000 \n"
> + " b 1b \n"
> + " .previous \n"
> " .set reorder \n"
> : "=m" (rw->lock), "=&r" (tmp)
> : "m" (rw->lock)
> @@ -314,11 +338,15 @@ static inline int __raw_write_trylock(ra
> " bnez %1, 2f \n"
> " lui %1, 0x8000 \n"
> " sc %1, %0 \n"
> - " beqz %1, 1b \n"
> - " sync \n"
> - " li %2, 1 \n"
> - " .set reorder \n"
> + " beqz %1, 3f \n"
> + " li %2, 1 \n"
> "2: \n"
> + " sync \n"
> + " .subsection 2 \n"
> + "3: b 1b \n"
> + " li %2, 0 \n"
> + " .previous \n"
> + " .set reorder \n"
> : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
> : "m" (rw->lock)
> : "memory");
> diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
> index dcb4701..fc35526 100644
> --- a/include/asm-mips/system.h
> +++ b/include/asm-mips/system.h
> @@ -3,7 +3,7 @@
> * License. See the file "COPYING" in the main directory of this archive
> * for more details.
> *
> - * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
> + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
> * Copyright (C) 1996 by Paul M. Antoine
> * Copyright (C) 1999 Silicon Graphics
> * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
> @@ -234,10 +234,13 @@ #endif
> " move %2, %z4 \n"
> " .set mips3 \n"
> " sc %2, %1 \n"
> - " beqz %2, 1b \n"
> + " beqz %2, 2f \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (retval), "=m" (*m), "=&r" (dummy)
> : "R" (*m), "Jr" (val)
> @@ -283,10 +286,13 @@ #endif
> "1: lld %0, %3 # xchg_u64 \n"
> " move %2, %z4 \n"
> " scd %2, %1 \n"
> - " beqz %2, 1b \n"
> + " beqz %2, 2f \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> + " .subsection 2 \n"
> + "2: b 1b \n"
> + " .previous \n"
> " .set mips0 \n"
> : "=&r" (retval), "=m" (*m), "=&r" (dummy)
> : "R" (*m), "Jr" (val)
> @@ -364,11 +370,14 @@ #endif
> " move $1, %z4 \n"
> " .set mips3 \n"
> " sc $1, %1 \n"
> - " beqz $1, 1b \n"
> + " beqz $1, 3f \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> "2: \n"
> + " .subsection 2 \n"
> + "3: b 1b \n"
> + " .previous \n"
> " .set pop \n"
> : "=&r" (retval), "=R" (*m)
> : "R" (*m), "Jr" (old), "Jr" (new)
> @@ -419,11 +428,14 @@ #endif
> " bne %0, %z3, 2f \n"
> " move $1, %z4 \n"
> " scd $1, %1 \n"
> - " beqz $1, 1b \n"
> + " beqz $1, 3f \n"
> #ifdef CONFIG_SMP
> " sync \n"
> #endif
> "2: \n"
> + " .subsection 2 \n"
> + "3: b 1b \n"
> + " .previous \n"
> " .set pop \n"
> : "=&r" (retval), "=R" (*m)
> : "R" (*m), "Jr" (old), "Jr" (new)
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-13 13:53 ` Antonio SJ Musumeci
@ 2006-10-13 14:11 ` Ralf Baechle
2006-10-13 19:18 ` Antonio SJ Musumeci
0 siblings, 1 reply; 9+ messages in thread
From: Ralf Baechle @ 2006-10-13 14:11 UTC (permalink / raw)
To: Antonio SJ Musumeci; +Cc: linux-mips
On Fri, Oct 13, 2006 at 09:53:05AM -0400, Antonio SJ Musumeci wrote:
> Should I apply my patch on top of this one?
No, the two patches conflict in what they're doing. The important
part of your patch, the fix to the if condition I've already applied.
Ralf
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-13 14:11 ` Ralf Baechle
@ 2006-10-13 19:18 ` Antonio SJ Musumeci
2006-10-15 18:42 ` Ralf Baechle
0 siblings, 1 reply; 9+ messages in thread
From: Antonio SJ Musumeci @ 2006-10-13 19:18 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Wouldn't it be better to check the macro in the preprocessor instead of
runtime? And why are those defined to 0 instead of explicitly undef'ed?
I've found one bug because it was assumed to be undefined instead of 0.
If no one objects I'll post a patch undefing those and fix any bugs I've
found because of them.
On Fri, 13 Oct 2006 15:11:01 +0100
Ralf Baechle <ralf@linux-mips.org> wrote:
> On Fri, Oct 13, 2006 at 09:53:05AM -0400, Antonio SJ Musumeci wrote:
>
> > Should I apply my patch on top of this one?
>
> No, the two patches conflict in what they're doing. The important
> part of your patch, the fix to the if condition I've already applied.
>
> Ralf
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-13 19:18 ` Antonio SJ Musumeci
@ 2006-10-15 18:42 ` Ralf Baechle
2006-10-18 18:08 ` Antonio SJ Musumeci
0 siblings, 1 reply; 9+ messages in thread
From: Ralf Baechle @ 2006-10-15 18:42 UTC (permalink / raw)
To: Antonio SJ Musumeci; +Cc: linux-mips
On Fri, Oct 13, 2006 at 03:18:41PM -0400, Antonio SJ Musumeci wrote:
> Wouldn't it be better to check the macro in the preprocessor instead of
> runtime? And why are those defined to 0 instead of explicitly undef'ed?
> I've found one bug because it was assumed to be undefined instead of 0.
> If no one objects I'll post a patch undefing those and fix any bugs I've
> found because of them.
Any reasonable system configuration will define cpu_has_llsc to 1 in
order to override the default. R10000_LLSC_WAR is a constant as well.
So only one of the three if blocks will remain. If that's not the case
you either don't have a cpu-feature-overrides.h file for your platform
or it doesn't define cpu_has_llsc to a constant expression.
Ralf
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-15 18:42 ` Ralf Baechle
@ 2006-10-18 18:08 ` Antonio SJ Musumeci
2006-10-18 18:41 ` Thiemo Seufer
0 siblings, 1 reply; 9+ messages in thread
From: Antonio SJ Musumeci @ 2006-10-18 18:08 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
I'm not talking about that. This patch explains it. Moving
the conditional compilation from the optimizer to the preprocessor.
I see no reason to be using hard coded 1's and 0's in runtime logic.
And one could go all the way and check cpu_has_llsc to see if it's
hardcoded or not.
Signed-off-by: Antonio SJ Musumeci <bile@landofbile.com>
--- clean.linux.mips.git/include/asm-mips/system.h 2006-10-15 17:58:08.000000000 -0400
+++ linux.mips.git/include/asm-mips/system.h 2006-10-14 18:21:16.000000000 -0400
@@ -206,9 +206,9 @@ static inline unsigned long __xchg_u32(v
{
__u32 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
+ if (cpu_has_llsc) {
unsigned long dummy;
-
+#if R10000_LLSC_WAR
__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %3 # xchg_u32 \n"
@@ -217,16 +217,14 @@ static inline unsigned long __xchg_u32(v
" .set mips3 \n"
" sc %2, %1 \n"
" beqzl %2, 1b \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
- } else if (cpu_has_llsc) {
- unsigned long dummy;
-
+#else /* !R10000_LLSC_WAR */
__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %3 # xchg_u32 \n"
@@ -235,9 +233,9 @@ static inline unsigned long __xchg_u32(v
" .set mips3 \n"
" sc %2, %1 \n"
" beqz %2, 2f \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
@@ -245,8 +243,9 @@ static inline unsigned long __xchg_u32(v
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
+#endif /* R10000_LLSC_WAR */
} else {
- unsigned long flags;
+ unsigned long flags;
local_irq_save(flags);
retval = *m;
@@ -262,34 +261,32 @@ static inline __u64 __xchg_u64(volatile
{
__u64 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
+ if (cpu_has_llsc) {
unsigned long dummy;
-
+#if R10000_LLSC_WAR
__asm__ __volatile__(
" .set mips3 \n"
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
" beqzl %2, 1b \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
- } else if (cpu_has_llsc) {
- unsigned long dummy;
-
- __asm__ __volatile__(
+#else /* !R10000_LLSC_WAR */
+ __asm__ __volatile__(
" .set mips3 \n"
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
" beqz %2, 2f \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
@@ -297,6 +294,8 @@ static inline __u64 __xchg_u64(volatile
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
+
+#endif /* R10000_LLSC_WAR */
} else {
unsigned long flags;
@@ -339,7 +338,8 @@ static inline unsigned long __cmpxchg_u3
{
__u32 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
+ if (cpu_has_llsc) {
+#if R10000_LLSC_WAR
__asm__ __volatile__(
" .set push \n"
" .set noat \n"
@@ -351,15 +351,15 @@ static inline unsigned long __cmpxchg_u3
" .set mips3 \n"
" sc $1, %1 \n"
" beqzl $1, 1b \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
"2: \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
- } else if (cpu_has_llsc) {
+#else /* !R10000_LLSC_WAR */
__asm__ __volatile__(
" .set push \n"
" .set noat \n"
@@ -371,9 +371,9 @@ static inline unsigned long __cmpxchg_u3
" .set mips3 \n"
" sc $1, %1 \n"
" beqz $1, 3f \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
"2: \n"
" .subsection 2 \n"
"3: b 1b \n"
@@ -382,6 +382,7 @@ static inline unsigned long __cmpxchg_u3
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
+#endif /* R10000_LLSC_WAR */
} else {
unsigned long flags;
@@ -401,8 +402,9 @@ static inline unsigned long __cmpxchg_u6
{
__u64 retval;
- if (cpu_has_llsc && R10000_LLSC_WAR) {
- __asm__ __volatile__(
+ if (cpu_has_llsc) {
+#if R10000_LLSC_WAR
+ __asm__ __volatile__(
" .set push \n"
" .set noat \n"
" .set mips3 \n"
@@ -411,15 +413,15 @@ static inline unsigned long __cmpxchg_u6
" move $1, %z4 \n"
" scd $1, %1 \n"
" beqzl $1, 1b \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
"2: \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
- } else if (cpu_has_llsc) {
+#else /* !R10000_LLSC_WAR */
__asm__ __volatile__(
" .set push \n"
" .set noat \n"
@@ -429,9 +431,9 @@ static inline unsigned long __cmpxchg_u6
" move $1, %z4 \n"
" scd $1, %1 \n"
" beqz $1, 3f \n"
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
" sync \n"
-#endif
+# endif
"2: \n"
" .subsection 2 \n"
"3: b 1b \n"
@@ -440,6 +442,7 @@ static inline unsigned long __cmpxchg_u6
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
+#endif /* R10000_LLSC_WAR */
} else {
unsigned long flags;
On Sun, 15 Oct 2006 19:42:26 +0100
Ralf Baechle <ralf@linux-mips.org> wrote:
> On Fri, Oct 13, 2006 at 03:18:41PM -0400, Antonio SJ Musumeci wrote:
>
> > Wouldn't it be better to check the macro in the preprocessor
> > instead of runtime? And why are those defined to 0 instead of
> > explicitly undef'ed? I've found one bug because it was assumed to
> > be undefined instead of 0. If no one objects I'll post a patch
> > undefing those and fix any bugs I've found because of them.
>
> Any reasonable system configuration will define cpu_has_llsc to 1 in
> order to override the default. R10000_LLSC_WAR is a constant as well.
> So only one of the three if blocks will remain. If that's not the
> case you either don't have a cpu-feature-overrides.h file for your
> platform or it doesn't define cpu_has_llsc to a constant expression.
>
> Ralf
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-18 18:08 ` Antonio SJ Musumeci
@ 2006-10-18 18:41 ` Thiemo Seufer
2006-10-18 19:45 ` Antonio SJ Musumeci
0 siblings, 1 reply; 9+ messages in thread
From: Thiemo Seufer @ 2006-10-18 18:41 UTC (permalink / raw)
To: Antonio SJ Musumeci; +Cc: Ralf Baechle, linux-mips
Antonio SJ Musumeci wrote:
> I'm not talking about that. This patch explains it. Moving
> the conditional compilation from the optimizer to the preprocessor.
> I see no reason to be using hard coded 1's and 0's in runtime logic.
It is easier to read than a ifdef maze, and the net result is the same.
Thiemo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup
2006-10-18 18:41 ` Thiemo Seufer
@ 2006-10-18 19:45 ` Antonio SJ Musumeci
0 siblings, 0 replies; 9+ messages in thread
From: Antonio SJ Musumeci @ 2006-10-18 19:45 UTC (permalink / raw)
To: linux-mips
It's not a good style... you shouldn't be relying on optimization to
protect you from bad coding practices. It goes against the
style of the other macros defined by the config and leads to bugs like
this:
Signed-off-by: Antonio SJ Musumeci <bile@landofbile.com>
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index cc895da..4084dc3 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -842,7 +842,7 @@ static void __init probe_pcache(void)
c->dcache.ways = 4;
c->dcache.waybit = __ffs(dcache_size / c->dcache.ways);
-#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
+#if !defined(CONFIG_SMP) || !RM9000_CDEX_SMP_WAR
c->options |= MIPS_CPU_CACHE_CDEX_P;
#endif
c->options |= MIPS_CPU_PREFETCH;
On Wed, 18 Oct 2006 19:41:59 +0100
Thiemo Seufer <ths@networkno.de> wrote:
> Antonio SJ Musumeci wrote:
> > I'm not talking about that. This patch explains it. Moving
> > the conditional compilation from the optimizer to the preprocessor.
> > I see no reason to be using hard coded 1's and 0's in runtime logic.
>
> It is easier to read than a ifdef maze, and the net result is the
> same.
>
>
> Thiemo
>
>
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-10-18 19:44 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-12 18:03 patch: include/asm-mips/system.h __cmpxchg64 bugfix and cleanup bile
2006-10-13 10:42 ` Ralf Baechle
2006-10-13 13:53 ` Antonio SJ Musumeci
2006-10-13 14:11 ` Ralf Baechle
2006-10-13 19:18 ` Antonio SJ Musumeci
2006-10-15 18:42 ` Ralf Baechle
2006-10-18 18:08 ` Antonio SJ Musumeci
2006-10-18 18:41 ` Thiemo Seufer
2006-10-18 19:45 ` Antonio SJ Musumeci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox