Skip to content

Commit

Permalink
arm64: atomics: patch in lse instructions when supported by the CPU
Browse files Browse the repository at this point in the history
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 <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
  • Loading branch information
wildea01 committed Jul 27, 2015
1 parent c0385b2 commit c09d6a0
Show file tree
Hide file tree
Showing 6 changed files with 342 additions and 124 deletions.
13 changes: 12 additions & 1 deletion arch/arm64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,18 @@ GZFLAGS :=-9

KBUILD_DEFCONFIG := defconfig

KBUILD_CFLAGS += -mgeneral-regs-only
# Check for binutils support for specific extensions
lseinstr := $(call as-instr,.arch_extension lse,-DCONFIG_AS_LSE=1)

ifeq ($(CONFIG_ARM64_LSE_ATOMICS), y)
ifeq ($(lseinstr),)
$(warning LSE atomics not supported by binutils)
endif
endif

KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr)
KBUILD_AFLAGS += $(lseinstr)

ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
Expand Down
4 changes: 2 additions & 2 deletions arch/arm64/include/asm/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@
#define __ASM_ATOMIC_H

#include <linux/compiler.h>
#include <linux/stringify.h>
#include <linux/types.h>

#include <asm/barrier.h>
#include <asm/cmpxchg.h>
#include <asm/lse.h>

#define ATOMIC_INIT(i) { (i) }

#ifdef __KERNEL__

#define __ARM64_IN_ATOMIC_IMPL

#ifdef CONFIG_ARM64_LSE_ATOMICS
#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
#include <asm/atomic_lse.h>
#else
#include <asm/atomic_ll_sc.h>
Expand Down
12 changes: 0 additions & 12 deletions arch/arm64/include/asm/atomic_ll_sc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,6 @@
* (the optimize attribute silently ignores these options).
*/

#ifndef __LL_SC_INLINE
#define __LL_SC_INLINE static inline
#endif

#ifndef __LL_SC_PREFIX
#define __LL_SC_PREFIX(x) x
#endif

#ifndef __LL_SC_EXPORT
#define __LL_SC_EXPORT(x)
#endif

#define ATOMIC_OP(op, asm_op) \
__LL_SC_INLINE void \
__LL_SC_PREFIX(atomic_##op(int i, atomic_t *v)) \
Expand Down
Loading

0 comments on commit c09d6a0

Please sign in to comment.