linux-mips
[Top] [All Lists]

[PATCH]: Improve atomic.h robustness

To: Linux MIPS List <linux-mips@linux-mips.org>
Subject: [PATCH]: Improve atomic.h robustness
From: Joshua Kinard <kumba@gentoo.org>
Date: Sun, 24 Jun 2012 21:01:34 -0400
Cc: Ralf Baechle <ralf@linux-mips.org>
List-archive: <http://www.linux-mips.org/archives/linux-mips/>
List-help: <mailto:ecartis@linux-mips.org?Subject=help>
List-id: linux-mips <linux-mips.eddie.linux-mips.org>
List-owner: <mailto:ralf@linux-mips.org>
List-post: <mailto:linux-mips@linux-mips.org>
List-software: Ecartis version 1.0.0
List-subscribe: <mailto:ecartis@linux-mips.org?subject=subscribe%20linux-mips>
List-unsubscribe: <mailto:ecartis@linux-mips.org?subject=unsubscribe%20linux-mips>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20120614 Thunderbird/13.0.1
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>
---

 atomic.h |   64 ++++++++++++++++++++++++++++-----------------------------------
 1 file changed, 29 insertions(+), 35 deletions(-)


diff -Naurp a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -59,8 +59,8 @@ static __inline__ void atomic_add(int i,
                "       sc      %0, %1                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               : "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else if (kernel_uses_llsc) {
                int temp;

@@ -71,8 +71,8 @@ static __inline__ void atomic_add(int i,
                        "       addu    %0, %2                          \n"
                        "       sc      %0, %1                          \n"
                        "       .set    mips0                           \n"
-                       : "=&r" (temp), "=m" (v->counter)
-                       : "Ir" (i), "m" (v->counter));
+                       : "=&r" (temp), "+m" (v->counter)
+                       : "Ir" (i));
                } while (unlikely(!temp));
        } else {
                unsigned long flags;
@@ -102,8 +102,8 @@ static __inline__ void atomic_sub(int i,
                "       sc      %0, %1                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               : "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else if (kernel_uses_llsc) {
                int temp;

@@ -114,8 +114,8 @@ static __inline__ void atomic_sub(int i,
                        "       subu    %0, %2                          \n"
                        "       sc      %0, %1                          \n"
                        "       .set    mips0                           \n"
-                       : "=&r" (temp), "=m" (v->counter)
-                       : "Ir" (i), "m" (v->counter));
+                       : "=&r" (temp), "+m" (v->counter)
+                       : "Ir" (i));
                } while (unlikely(!temp));
        } else {
                unsigned long flags;
@@ -146,9 +146,8 @@ static __inline__ int atomic_add_return(
                "       beqzl   %0, 1b                                  \n"
                "       addu    %0, %1, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else if (kernel_uses_llsc) {
                int temp;

@@ -159,9 +158,8 @@ static __inline__ int atomic_add_return(
                        "       addu    %0, %1, %3                      \n"
                        "       sc      %0, %2                          \n"
                        "       .set    mips0                           \n"
-                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-                       : "Ir" (i), "m" (v->counter)
-                       : "memory");
+                       : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+                       : "Ir" (i));
                } while (unlikely(!result));

                result = temp + i;
@@ -212,9 +210,8 @@ static __inline__ int atomic_sub_return(
                        "       subu    %0, %1, %3                      \n"
                        "       sc      %0, %2                          \n"
                        "       .set    mips0                           \n"
-                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-                       : "Ir" (i), "m" (v->counter)
-                       : "memory");
+                       : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+                       : "Ir" (i));
                } while (unlikely(!result));

                result = temp - i;
@@ -262,7 +259,7 @@ static __inline__ int atomic_sub_if_posi
                "       .set    reorder                                 \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
        } else if (kernel_uses_llsc) {
@@ -280,9 +277,8 @@ static __inline__ int atomic_sub_if_posi
                "       .set    reorder                                 \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else {
                unsigned long flags;

@@ -430,8 +426,8 @@ static __inline__ void atomic64_add(long
                "       scd     %0, %1                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               : "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else if (kernel_uses_llsc) {
                long temp;

@@ -442,8 +438,8 @@ static __inline__ void atomic64_add(long
                        "       daddu   %0, %2                          \n"
                        "       scd     %0, %1                          \n"
                        "       .set    mips0                           \n"
-                       : "=&r" (temp), "=m" (v->counter)
-                       : "Ir" (i), "m" (v->counter));
+                       : "=&r" (temp), "+m" (v->counter)
+                       : "Ir" (i));
                } while (unlikely(!temp));
        } else {
                unsigned long flags;
@@ -473,8 +469,8 @@ static __inline__ void atomic64_sub(long
                "       scd     %0, %1                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               : "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else if (kernel_uses_llsc) {
                long temp;

@@ -485,8 +481,8 @@ static __inline__ void atomic64_sub(long
                        "       dsubu   %0, %2                          \n"
                        "       scd     %0, %1                          \n"
                        "       .set    mips0                           \n"
-                       : "=&r" (temp), "=m" (v->counter)
-                       : "Ir" (i), "m" (v->counter));
+                       : "=&r" (temp), "+m" (v->counter)
+                       : "Ir" (i));
                } while (unlikely(!temp));
        } else {
                unsigned long flags;
@@ -517,9 +513,8 @@ static __inline__ long atomic64_add_retu
                "       beqzl   %0, 1b                                  \n"
                "       daddu   %0, %1, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else if (kernel_uses_llsc) {
                long temp;

@@ -649,9 +644,8 @@ static __inline__ long atomic64_sub_if_p
                "       .set    reorder                                 \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i));
        } else {
                unsigned long flags;


<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH]: Improve atomic.h robustness, Joshua Kinard <=