Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/common/vlock.S
26298 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* vlock.S - simple voting lock implementation for ARM
4
*
5
* Created by: Dave Martin, 2012-08-16
6
* Copyright: (C) 2012-2013 Linaro Limited
7
*
8
* This algorithm is described in more detail in
9
* Documentation/arch/arm/vlocks.rst.
10
*/
11
12
#include <linux/linkage.h>
13
#include "vlock.h"
14
15
.arch armv7-a
16
17
/* Select different code if voting flags can fit in a single word. */
18
#if VLOCK_VOTING_SIZE > 4
19
#define FEW(x...)
20
#define MANY(x...) x
21
#else
22
#define FEW(x...) x
23
#define MANY(x...)
24
#endif
25
26
@ voting lock for first-man coordination
27
28
.macro voting_begin rbase:req, rcpu:req, rscratch:req
29
mov \rscratch, #1
30
strb \rscratch, [\rbase, \rcpu]
31
dmb
32
.endm
33
34
.macro voting_end rbase:req, rcpu:req, rscratch:req
35
dmb
36
mov \rscratch, #0
37
strb \rscratch, [\rbase, \rcpu]
38
dsb st
39
sev
40
.endm
41
42
/*
43
* The vlock structure must reside in Strongly-Ordered or Device memory.
44
* This implementation deliberately eliminates most of the barriers which
45
* would be required for other memory types, and assumes that independent
46
* writes to neighbouring locations within a cacheline do not interfere
47
* with one another.
48
*/
49
50
@ r0: lock structure base
51
@ r1: CPU ID (0-based index within cluster)
52
ENTRY(vlock_trylock)
53
add r1, r1, #VLOCK_VOTING_OFFSET
54
55
voting_begin r0, r1, r2
56
57
ldrb r2, [r0, #VLOCK_OWNER_OFFSET] @ check whether lock is held
58
cmp r2, #VLOCK_OWNER_NONE
59
bne trylock_fail @ fail if so
60
61
@ Control dependency implies strb not observable before previous ldrb.
62
63
strb r1, [r0, #VLOCK_OWNER_OFFSET] @ submit my vote
64
65
voting_end r0, r1, r2 @ implies DMB
66
67
@ Wait for the current round of voting to finish:
68
69
MANY( mov r3, #VLOCK_VOTING_OFFSET )
70
0:
71
MANY( ldr r2, [r0, r3] )
72
FEW( ldr r2, [r0, #VLOCK_VOTING_OFFSET] )
73
cmp r2, #0
74
wfene
75
bne 0b
76
MANY( add r3, r3, #4 )
77
MANY( cmp r3, #VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE )
78
MANY( bne 0b )
79
80
@ Check who won:
81
82
dmb
83
ldrb r2, [r0, #VLOCK_OWNER_OFFSET]
84
eor r0, r1, r2 @ zero if I won, else nonzero
85
bx lr
86
87
trylock_fail:
88
voting_end r0, r1, r2
89
mov r0, #1 @ nonzero indicates that I lost
90
bx lr
91
ENDPROC(vlock_trylock)
92
93
@ r0: lock structure base
94
ENTRY(vlock_unlock)
95
dmb
96
mov r1, #VLOCK_OWNER_NONE
97
strb r1, [r0, #VLOCK_OWNER_OFFSET]
98
dsb st
99
sev
100
bx lr
101
ENDPROC(vlock_unlock)
102
103