Skip to content

Commit

Permalink
ARC: atomics: Add compiler barrier to atomic operations...
Browse files Browse the repository at this point in the history
... to avoid unwanted gcc optimizations

SMP kernels fail to boot with commit 596ff4a
("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 b64be68
("ARC: atomics: implement relaxed variants") removed the smp_mb() for
the relaxed variants, but failed to add the explicit compiler barrier.

Link: foss-for-synopsys-dwc-arc-processors/linux#135
Cc: <stable@vger.kernel.org> # v6.3+
Fixes: b64be68 ("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]
  • Loading branch information
pavelvkozlov authored and vineetgarc committed Aug 16, 2023
1 parent 4d36968 commit 42f51fb
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 6 deletions.
6 changes: 3 additions & 3 deletions arch/arc/include/asm/atomic-llsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static inline void arch_atomic_##op(int i, atomic_t *v) \
: [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) \
Expand All @@ -34,7 +34,7 @@ static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
: [val] "=&r" (val) \
: [ctr] "r" (&v->counter), \
[i] "ir" (i) \
: "cc"); \
: "cc", "memory"); \
\
return val; \
}
Expand All @@ -56,7 +56,7 @@ static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
[orig] "=&r" (orig) \
: [ctr] "r" (&v->counter), \
[i] "ir" (i) \
: "cc"); \
: "cc", "memory"); \
\
return orig; \
}
Expand Down
6 changes: 3 additions & 3 deletions arch/arc/include/asm/atomic64-arcv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static inline void arch_atomic64_##op(s64 a, atomic64_t *v) \
" bnz 1b \n" \
: "=&r"(val) \
: "r"(&v->counter), "ir"(a) \
: "cc"); \
: "cc", "memory"); \
} \

#define ATOMIC64_OP_RETURN(op, op1, op2) \
Expand All @@ -77,7 +77,7 @@ static inline s64 arch_atomic64_##op##_return_relaxed(s64 a, atomic64_t *v) \
" bnz 1b \n" \
: [val] "=&r"(val) \
: "r"(&v->counter), "ir"(a) \
: "cc"); /* memory clobber comes from smp_mb() */ \
: "cc", "memory"); \
\
return val; \
}
Expand All @@ -99,7 +99,7 @@ static inline s64 arch_atomic64_fetch_##op##_relaxed(s64 a, atomic64_t *v) \
" bnz 1b \n" \
: "=&r"(orig), "=&r"(val) \
: "r"(&v->counter), "ir"(a) \
: "cc"); /* memory clobber comes from smp_mb() */ \
: "cc", "memory"); \
\
return orig; \
}
Expand Down

0 comments on commit 42f51fb

Please sign in to comment.