Skip to content

Commit c09d6a0

Browse files
committed
arm64: atomics: patch in lse instructions when supported by the CPU
On CPUs which support the LSE atomic instructions introduced in ARMv8.1, it makes sense to use them in preference to ll/sc sequences. This patch introduces runtime patching of atomic_t and atomic64_t routines so that the call-site for the out-of-line ll/sc sequences is patched with an LSE atomic instruction when we detect that the CPU supports it. If binutils is not recent enough to assemble the LSE instructions, then the ll/sc sequences are inlined as though CONFIG_ARM64_LSE_ATOMICS=n. Reviewed-by: Catalin Marinas <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent c0385b2 commit c09d6a0

File tree

6 files changed

+342
-124
lines changed

6 files changed

+342
-124
lines changed

arch/arm64/Makefile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,18 @@ GZFLAGS :=-9
1717

1818
KBUILD_DEFCONFIG := defconfig
1919

20-
KBUILD_CFLAGS += -mgeneral-regs-only
20+
# Check for binutils support for specific extensions
21+
lseinstr := $(call as-instr,.arch_extension lse,-DCONFIG_AS_LSE=1)
22+
23+
ifeq ($(CONFIG_ARM64_LSE_ATOMICS), y)
24+
ifeq ($(lseinstr),)
25+
$(warning LSE atomics not supported by binutils)
26+
endif
27+
endif
28+
29+
KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr)
30+
KBUILD_AFLAGS += $(lseinstr)
31+
2132
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
2233
KBUILD_CPPFLAGS += -mbig-endian
2334
AS += -EB

arch/arm64/include/asm/atomic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@
2121
#define __ASM_ATOMIC_H
2222

2323
#include <linux/compiler.h>
24-
#include <linux/stringify.h>
2524
#include <linux/types.h>
2625

2726
#include <asm/barrier.h>
2827
#include <asm/cmpxchg.h>
28+
#include <asm/lse.h>
2929

3030
#define ATOMIC_INIT(i) { (i) }
3131

3232
#ifdef __KERNEL__
3333

3434
#define __ARM64_IN_ATOMIC_IMPL
3535

36-
#ifdef CONFIG_ARM64_LSE_ATOMICS
36+
#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
3737
#include <asm/atomic_lse.h>
3838
#else
3939
#include <asm/atomic_ll_sc.h>

arch/arm64/include/asm/atomic_ll_sc.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,6 @@
3737
* (the optimize attribute silently ignores these options).
3838
*/
3939

40-
#ifndef __LL_SC_INLINE
41-
#define __LL_SC_INLINE static inline
42-
#endif
43-
44-
#ifndef __LL_SC_PREFIX
45-
#define __LL_SC_PREFIX(x) x
46-
#endif
47-
48-
#ifndef __LL_SC_EXPORT
49-
#define __LL_SC_EXPORT(x)
50-
#endif
51-
5240
#define ATOMIC_OP(op, asm_op) \
5341
__LL_SC_INLINE void \
5442
__LL_SC_PREFIX(atomic_##op(int i, atomic_t *v)) \

0 commit comments

Comments
 (0)