... to avoid unwanted gcc optimizations
SMP kernels fail to boot with commit 
596ff4a09b89
("cpumask: re-introduce constant-sized cpumask optimizations").
|
| percpu: BUG: failure at mm/percpu.c:2981/pcpu_build_alloc_info()!
|
The write operation performed by the SCOND instruction in the atomic
inline asm code is not properly passed to the compiler. The compiler
cannot correctly optimize a nested loop that runs through the cpumask
in the pcpu_build_alloc_info() function.
Fix this by add a compiler barrier (memory clobber in inline asm).
Apparently atomic ops used to have memory clobber implicitly via
surrounding smp_mb(). However commit 
b64be6836993c431e
("ARC: atomics: implement relaxed variants") removed the smp_mb() for
the relaxed variants, but failed to add the explicit compiler barrier.
Link: https://github.com/foss-for-synopsys-dwc-arc-processors/linux/issues/135
Cc: <stable@vger.kernel.org> # v6.3+
Fixes: b64be6836993c43 ("ARC: atomics: implement relaxed variants")
Signed-off-by: Pavel Kozlov <pavel.kozlov@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
[vgupta: tweaked the changelog and added Fixes tag]
 
        : [val] "=&r"   (val) /* Early clobber to prevent reg reuse */  \
        : [ctr] "r"     (&v->counter), /* Not "m": llock only supports reg direct addr mode */  \
          [i]   "ir"    (i)                                             \
-       : "cc");                                                        \
+       : "cc", "memory");                                              \
 }                                                                      \
 
 #define ATOMIC_OP_RETURN(op, asm_op)                           \
        : [val] "=&r"   (val)                                           \
        : [ctr] "r"     (&v->counter),                                  \
          [i]   "ir"    (i)                                             \
-       : "cc");                                                        \
+       : "cc", "memory");                                              \
                                                                        \
        return val;                                                     \
 }
          [orig] "=&r" (orig)                                           \
        : [ctr] "r"     (&v->counter),                                  \
          [i]   "ir"    (i)                                             \
-       : "cc");                                                        \
+       : "cc", "memory");                                              \
                                                                        \
        return orig;                                                    \
 }
 
        "       bnz     1b              \n"                             \
        : "=&r"(val)                                                    \
        : "r"(&v->counter), "ir"(a)                                     \
-       : "cc");                                                        \
+       : "cc", "memory");                                              \
 }                                                                      \
 
 #define ATOMIC64_OP_RETURN(op, op1, op2)                               \
        "       bnz     1b              \n"                             \
        : [val] "=&r"(val)                                              \
        : "r"(&v->counter), "ir"(a)                                     \
-       : "cc");        /* memory clobber comes from smp_mb() */        \
+       : "cc", "memory");                                              \
                                                                        \
        return val;                                                     \
 }
        "       bnz     1b              \n"                             \
        : "=&r"(orig), "=&r"(val)                                       \
        : "r"(&v->counter), "ir"(a)                                     \
-       : "cc");        /* memory clobber comes from smp_mb() */        \
+       : "cc", "memory");                                              \
                                                                        \
        return orig;                                                    \
 }