Re: [PATCH] MIPS: Loongson, workaround ll/sc weak ordering

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



YunQiang Su <syq@xxxxxxxxxx> 于2018年12月14日周五 下午11:56写道:
>
> On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and
> lld/scd is very weak ordering. We should add sync instructions before
> each ll/lld and after the last sc/scd to workaround. Otherwise, this
> flaw will cause deadlock occationally (e.g. when doing heavy load test
> with LTP).
>
> We introduced an gcc/as option "-mfix-loongson3-llsc", this option
> inserts sync before ll, and so some addresses in __ex_table will need
> to be shift.
>

The binutils patch
  https://sourceware.org/ml/binutils/2018-12/msg00192.html
The gcc patch
  https://gcc.gnu.org/ml/gcc-patches/2018-12/msg01064.html

> This is based on the patch from Huacai Chen.
> ---
>  arch/mips/Makefile            |  5 +++++
>  arch/mips/include/asm/futex.h | 20 ++++++++++++--------
>  2 files changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/arch/mips/Makefile b/arch/mips/Makefile
> index b6303e48d..360ee1c30 100644
> --- a/arch/mips/Makefile
> +++ b/arch/mips/Makefile
> @@ -194,6 +194,11 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
>  endif
>  cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
>  cflags-$(CONFIG_CPU_BMIPS)     += -march=mips32 -Wa,-mips32 -Wa,--trap
> +ifeq ($(CONFIG_CPU_LOONGSON3),y)
> +cflags-y       += $(call cc-option,-mfix-loongson3-llsc,)
> +else
> +cflags-y       += $(call cc-option,-mno-fix-loongson3-llsc,)
> +endif
>
>  cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
>  cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
> diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
> index 8eff134b3..27fceaf1d 100644
> --- a/arch/mips/include/asm/futex.h
> +++ b/arch/mips/include/asm/futex.h
> @@ -18,6 +18,14 @@
>  #include <asm/errno.h>
>  #include <asm/war.h>
>
> +#if defined(__mips_fix_loongson3_llsc) && defined(CONFIG_CPU_LOONGSON3)
> +# define LL_SHIFT_UA __UA_ADDR "\t(1b+0), 4b           \n"     \
> +               __UA_ADDR "\t(1b+4), 4b                 \n"     \
> +               __UA_ADDR "\t(2b+0), 4b                 \n"
> +#else
> +# define LL_SHIFT_UA __UA_ADDR "\t1b, 4b               \n"     \
> +               __UA_ADDR "\t2b, 4b                     \n"
> +#endif
>  #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)             \
>  {                                                                      \
>         if (cpu_has_llsc && R10000_LLSC_WAR) {                          \
> @@ -41,8 +49,7 @@
>                 "       j       3b                              \n"     \
>                 "       .previous                               \n"     \
>                 "       .section __ex_table,\"a\"               \n"     \
> -               "       "__UA_ADDR "\t1b, 4b                    \n"     \
> -               "       "__UA_ADDR "\t2b, 4b                    \n"     \
> +               LL_SHIFT_UA                                             \
>                 "       .previous                               \n"     \
>                 : "=r" (ret), "=&r" (oldval),                           \
>                   "=" GCC_OFF_SMALL_ASM() (*uaddr)                              \
> @@ -70,8 +77,7 @@
>                 "       j       3b                              \n"     \
>                 "       .previous                               \n"     \
>                 "       .section __ex_table,\"a\"               \n"     \
> -               "       "__UA_ADDR "\t1b, 4b                    \n"     \
> -               "       "__UA_ADDR "\t2b, 4b                    \n"     \
> +               LL_SHIFT_UA                                             \
>                 "       .previous                               \n"     \
>                 : "=r" (ret), "=&r" (oldval),                           \
>                   "=" GCC_OFF_SMALL_ASM() (*uaddr)                              \
> @@ -155,8 +161,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
>                 "       j       3b                                      \n"
>                 "       .previous                                       \n"
>                 "       .section __ex_table,\"a\"                       \n"
> -               "       "__UA_ADDR "\t1b, 4b                            \n"
> -               "       "__UA_ADDR "\t2b, 4b                            \n"
> +               LL_SHIFT_UA
>                 "       .previous                                       \n"
>                 : "+r" (ret), "=&r" (val), "=" GCC_OFF_SMALL_ASM() (*uaddr)
>                 : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
> @@ -185,8 +190,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
>                 "       j       3b                                      \n"
>                 "       .previous                                       \n"
>                 "       .section __ex_table,\"a\"                       \n"
> -               "       "__UA_ADDR "\t1b, 4b                            \n"
> -               "       "__UA_ADDR "\t2b, 4b                            \n"
> +               LL_SHIFT_UA
>                 "       .previous                                       \n"
>                 : "+r" (ret), "=&r" (val), "=" GCC_OFF_SMALL_ASM() (*uaddr)
>                 : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
> --
> 2.20.0.rc2
>


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux