aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2013-03-21 12:28:47 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2013-03-21 13:39:31 -0400
commit62479586532715b6da4777374a6f53b32453385e (patch)
tree232004eb56bf36b966ea11ec8295a1b2893ac9e9 /arch
parent2b8cac814cd5a0a305d62dcd1d589faccb705a4d (diff)
arm64: klib: Optimised atomic bitops
This patch implements the AArch64-specific atomic bitops functions using exclusive memory accesses to avoid locking. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/include/asm/bitops.h18
-rw-r--r--arch/arm64/kernel/arm64ksyms.c13
-rw-r--r--arch/arm64/lib/bitops.S70
-rw-r--r--arch/arm64/lib/bitops.c25
4 files changed, 94 insertions, 32 deletions
diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h
index 5e693073b030..aa5b59d6ba43 100644
--- a/arch/arm64/include/asm/bitops.h
+++ b/arch/arm64/include/asm/bitops.h
@@ -32,6 +32,16 @@
32#error only <linux/bitops.h> can be included directly 32#error only <linux/bitops.h> can be included directly
33#endif 33#endif
34 34
35/*
36 * Little endian assembly atomic bitops.
37 */
38extern void set_bit(int nr, volatile unsigned long *p);
39extern void clear_bit(int nr, volatile unsigned long *p);
40extern void change_bit(int nr, volatile unsigned long *p);
41extern int test_and_set_bit(int nr, volatile unsigned long *p);
42extern int test_and_clear_bit(int nr, volatile unsigned long *p);
43extern int test_and_change_bit(int nr, volatile unsigned long *p);
44
35#include <asm-generic/bitops/builtin-__ffs.h> 45#include <asm-generic/bitops/builtin-__ffs.h>
36#include <asm-generic/bitops/builtin-ffs.h> 46#include <asm-generic/bitops/builtin-ffs.h>
37#include <asm-generic/bitops/builtin-__fls.h> 47#include <asm-generic/bitops/builtin-__fls.h>
@@ -45,9 +55,13 @@
45#include <asm-generic/bitops/hweight.h> 55#include <asm-generic/bitops/hweight.h>
46#include <asm-generic/bitops/lock.h> 56#include <asm-generic/bitops/lock.h>
47 57
48#include <asm-generic/bitops/atomic.h>
49#include <asm-generic/bitops/non-atomic.h> 58#include <asm-generic/bitops/non-atomic.h>
50#include <asm-generic/bitops/le.h> 59#include <asm-generic/bitops/le.h>
51#include <asm-generic/bitops/ext2-atomic.h> 60
61/*
62 * Ext2 is defined to use little-endian byte ordering.
63 */
64#define ext2_set_bit_atomic(lock, nr, p) test_and_set_bit_le(nr, p)
65#define ext2_clear_bit_atomic(lock, nr, p) test_and_clear_bit_le(nr, p)
52 66
53#endif /* __ASM_BITOPS_H */ 67#endif /* __ASM_BITOPS_H */
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c
index a5d0d4643109..7df1aad29b67 100644
--- a/arch/arm64/kernel/arm64ksyms.c
+++ b/arch/arm64/kernel/arm64ksyms.c
@@ -39,11 +39,6 @@ EXPORT_SYMBOL(__copy_from_user);
39EXPORT_SYMBOL(__copy_to_user); 39EXPORT_SYMBOL(__copy_to_user);
40EXPORT_SYMBOL(__clear_user); 40EXPORT_SYMBOL(__clear_user);
41 41
42 /* bitops */
43#ifdef CONFIG_SMP
44EXPORT_SYMBOL(__atomic_hash);
45#endif
46
47 /* physical memory */ 42 /* physical memory */
48EXPORT_SYMBOL(memstart_addr); 43EXPORT_SYMBOL(memstart_addr);
49 44
@@ -54,3 +49,11 @@ EXPORT_SYMBOL(memset);
54EXPORT_SYMBOL(memcpy); 49EXPORT_SYMBOL(memcpy);
55EXPORT_SYMBOL(memmove); 50EXPORT_SYMBOL(memmove);
56EXPORT_SYMBOL(memchr); 51EXPORT_SYMBOL(memchr);
52
53 /* atomic bitops */
54EXPORT_SYMBOL(set_bit);
55EXPORT_SYMBOL(test_and_set_bit);
56EXPORT_SYMBOL(clear_bit);
57EXPORT_SYMBOL(test_and_clear_bit);
58EXPORT_SYMBOL(change_bit);
59EXPORT_SYMBOL(test_and_change_bit);
diff --git a/arch/arm64/lib/bitops.S b/arch/arm64/lib/bitops.S
new file mode 100644
index 000000000000..fd1e801b53e7
--- /dev/null
+++ b/arch/arm64/lib/bitops.S
@@ -0,0 +1,70 @@
1/*
2 * Based on arch/arm/lib/bitops.h
3 *
4 * Copyright (C) 2013 ARM Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/linkage.h>
20#include <asm/assembler.h>
21
22/*
23 * x0: bits 5:0 bit offset
24 * bits 63:6 word offset
25 * x1: address
26 */
27 .macro bitop, name, instr
28ENTRY( \name )
29 and x3, x0, #63 // Get bit offset
30 eor x0, x0, x3 // Clear low bits
31 mov x2, #1
32 add x1, x1, x0, lsr #3 // Get word offset
33 lsl x3, x2, x3 // Create mask
341: ldxr x2, [x1]
35 \instr x2, x2, x3
36 stxr w0, x2, [x1]
37 cbnz w0, 1b
38 ret
39ENDPROC(\name )
40 .endm
41
42 .macro testop, name, instr
43ENTRY( \name )
44 and x3, x0, #63 // Get bit offset
45 eor x0, x0, x3 // Clear low bits
46 mov x2, #1
47 add x1, x1, x0, lsr #3 // Get word offset
48 lsl x4, x2, x3 // Create mask
49 smp_dmb ish
501: ldxr x2, [x1]
51 lsr x0, x2, x3 // Save old value of bit
52 \instr x2, x2, x4 // toggle bit
53 stxr w2, x2, [x1]
54 cbnz w2, 1b
55 smp_dmb ish
56 and x0, x0, #1
573: ret
58ENDPROC(\name )
59 .endm
60
61/*
62 * Atomic bit operations.
63 */
64 bitop change_bit, eor
65 bitop clear_bit, bic
66 bitop set_bit, orr
67
68 testop test_and_change_bit, eor
69 testop test_and_clear_bit, bic
70 testop test_and_set_bit, orr
diff --git a/arch/arm64/lib/bitops.c b/arch/arm64/lib/bitops.c
deleted file mode 100644
index aa4965e60acc..000000000000
--- a/arch/arm64/lib/bitops.c
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Copyright (C) 2012 ARM Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kernel.h>
18#include <linux/spinlock.h>
19#include <linux/atomic.h>
20
21#ifdef CONFIG_SMP
22arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
23 [0 ... (ATOMIC_HASH_SIZE-1)] = __ARCH_SPIN_LOCK_UNLOCKED
24};
25#endif