MIPS: Remove open-coded cmpxchg() in set_pte()
authorPaul Burton <paul.burton@mips.com>
Sat, 2 Feb 2019 02:01:02 +0000 (02:01 +0000)
committerPaul Burton <paul.burton@mips.com>
Mon, 4 Feb 2019 18:56:48 +0000 (10:56 -0800)
set_pte() contains an open coded version of cmpxchg() - it atomically
replaces the buddy pte's value if it is currently zero. Simplify the
code considerably by just using cmpxchg() instead of reinventing it.

Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: linux-mips@vger.kernel.org
arch/mips/include/asm/pgtable.h

index 57933fc8fd9877d09b4f885a6cb4b4412978e4c2..6c13c1d44045a35af5af615231ca6007216c901e 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/pgtable-64.h>
 #endif
 
+#include <asm/cmpxchg.h>
 #include <asm/io.h>
 #include <asm/pgtable-bits.h>
 
@@ -204,49 +205,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
                 * Make sure the buddy is global too (if it's !none,
                 * it better already be global)
                 */
-#ifdef CONFIG_SMP
-               /*
-                * For SMP, multiple CPUs can race, so we need to do
-                * this atomically.
-                */
-               unsigned long page_global = _PAGE_GLOBAL;
-               unsigned long tmp;
-
-               if (kernel_uses_llsc && R10000_LLSC_WAR) {
-                       __asm__ __volatile__ (
-                       "       .set    push                            \n"
-                       "       .set    arch=r4000                      \n"
-                       "       .set    noreorder                       \n"
-                       "1:"    __LL    "%[tmp], %[buddy]               \n"
-                       "       bnez    %[tmp], 2f                      \n"
-                       "        or     %[tmp], %[tmp], %[global]       \n"
-                               __SC    "%[tmp], %[buddy]               \n"
-                       "       beqzl   %[tmp], 1b                      \n"
-                       "       nop                                     \n"
-                       "2:                                             \n"
-                       "       .set    pop                             \n"
-                       : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
-                       : [global] "r" (page_global));
-               } else if (kernel_uses_llsc) {
-                       __asm__ __volatile__ (
-                       "       .set    push                            \n"
-                       "       .set    "MIPS_ISA_ARCH_LEVEL"           \n"
-                       "       .set    noreorder                       \n"
-                       "1:"    __LL    "%[tmp], %[buddy]               \n"
-                       "       bnez    %[tmp], 2f                      \n"
-                       "        or     %[tmp], %[tmp], %[global]       \n"
-                               __SC    "%[tmp], %[buddy]               \n"
-                       "       beqz    %[tmp], 1b                      \n"
-                       "       nop                                     \n"
-                       "2:                                             \n"
-                       "       .set    pop                             \n"
-                       : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
-                       : [global] "r" (page_global));
-               }
-#else /* !CONFIG_SMP */
-               if (pte_none(*buddy))
-                       pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
-#endif /* CONFIG_SMP */
+               cmpxchg(&buddy->pte, 0, _PAGE_GLOBAL);
        }
 #endif
 }