Commit | Line | Data |
---|---|---|
db8ff907 MN |
1 | Transactional Memory support |
2 | ============================ | |
3 | ||
4 | POWER kernel support for this feature is currently limited to supporting | |
5 | its use by user programs. It is not currently used by the kernel itself. | |
6 | ||
7 | This file aims to sum up how it is supported by Linux and what behaviour you | |
8 | can expect from your user programs. | |
9 | ||
10 | ||
11 | Basic overview | |
12 | ============== | |
13 | ||
14 | Hardware Transactional Memory is supported on POWER8 processors, and is a | |
15 | feature that enables a different form of atomic memory access. Several new | |
16 | instructions are presented to delimit transactions; transactions are | |
17 | guaranteed to either complete atomically or roll back and undo any partial | |
18 | changes. | |
19 | ||
20 | A simple transaction looks like this: | |
21 | ||
22 | begin_move_money: | |
23 | tbegin | |
24 | beq abort_handler | |
25 | ||
26 | ld r4, SAVINGS_ACCT(r3) | |
27 | ld r5, CURRENT_ACCT(r3) | |
28 | subi r5, r5, 1 | |
29 | addi r4, r4, 1 | |
30 | std r4, SAVINGS_ACCT(r3) | |
31 | std r5, CURRENT_ACCT(r3) | |
32 | ||
33 | tend | |
34 | ||
35 | b continue | |
36 | ||
37 | abort_handler: | |
38 | ... test for odd failures ... | |
39 | ||
40 | /* Retry the transaction if it failed because it conflicted with | |
41 | * someone else: */ | |
42 | b begin_move_money | |
43 | ||
44 | ||
45 | The 'tbegin' instruction denotes the start point, and 'tend' the end point. | |
46 | Between these points the processor is in 'Transactional' state; any memory | |
47 | references will complete in one go if there are no conflicts with other | |
48 | transactional or non-transactional accesses within the system. In this | |
49 | example, the transaction completes as though it were normal straight-line code | |
50 | IF no other processor has touched SAVINGS_ACCT(r3) or CURRENT_ACCT(r3); an | |
51 | atomic move of money from the current account to the savings account has been | |
52 | performed. Even though the normal ld/std instructions are used (note no | |
53 | lwarx/stwcx), either *both* SAVINGS_ACCT(r3) and CURRENT_ACCT(r3) will be | |
54 | updated, or neither will be updated. | |
55 | ||
56 | If, in the meantime, there is a conflict with the locations accessed by the | |
57 | transaction, the transaction will be aborted by the CPU. Register and memory | |
58 | state will roll back to that at the 'tbegin', and control will continue from | |
59 | 'tbegin+4'. The branch to abort_handler will be taken this second time; the | |
60 | abort handler can check the cause of the failure, and retry. | |
61 | ||
62 | Checkpointed registers include all GPRs, FPRs, VRs/VSRs, LR, CCR/CR, CTR, FPCSR | |
63 | and a few other status/flag regs; see the ISA for details. | |
64 | ||
65 | Causes of transaction aborts | |
66 | ============================ | |
67 | ||
68 | - Conflicts with cache lines used by other processors | |
69 | - Signals | |
70 | - Context switches | |
71 | - See the ISA for full documentation of everything that will abort transactions. | |
72 | ||
73 | ||
74 | Syscalls | |
75 | ======== | |
76 | ||
b4b56f9e S |
77 | Syscalls made from within an active transaction will not be performed and the |
78 | transaction will be doomed by the kernel with the failure code TM_CAUSE_SYSCALL | |
79 | | TM_CAUSE_PERSISTENT. | |
db8ff907 | 80 | |
b4b56f9e S |
81 | Syscalls made from within a suspended transaction are performed as normal and |
82 | the transaction is not explicitly doomed by the kernel. However, what the | |
83 | kernel does to perform the syscall may result in the transaction being doomed | |
84 | by the hardware. The syscall is performed in suspended mode so any side | |
85 | effects will be persistent, independent of transaction success or failure. No | |
86 | guarantees are provided by the kernel about which syscalls will affect | |
87 | transaction success. | |
db8ff907 | 88 | |
b4b56f9e S |
89 | Care must be taken when relying on syscalls to abort during active transactions |
90 | if the calls are made via a library. Libraries may cache values (which may | |
91 | give the appearance of success) or perform operations that cause transaction | |
92 | failure before entering the kernel (which may produce different failure codes). | |
93 | Examples are glibc's getpid() and lazy symbol resolution. | |
db8ff907 MN |
94 | |
95 | ||
96 | Signals | |
97 | ======= | |
98 | ||
99 | Delivery of signals (both sync and async) during transactions provides a second | |
100 | thread state (ucontext/mcontext) to represent the second transactional register | |
101 | state. Signal delivery 'treclaim's to capture both register states, so signals | |
102 | abort transactions. The usual ucontext_t passed to the signal handler | |
103 | represents the checkpointed/original register state; the signal appears to have | |
104 | arisen at 'tbegin+4'. | |
105 | ||
106 | If the sighandler ucontext has uc_link set, a second ucontext has been | |
107 | delivered. For future compatibility the MSR.TS field should be checked to | |
108 | determine the transactional state -- if so, the second ucontext in uc->uc_link | |
109 | represents the active transactional registers at the point of the signal. | |
110 | ||
111 | For 64-bit processes, uc->uc_mcontext.regs->msr is a full 64-bit MSR and its TS | |
112 | field shows the transactional mode. | |
113 | ||
114 | For 32-bit processes, the mcontext's MSR register is only 32 bits; the top 32 | |
115 | bits are stored in the MSR of the second ucontext, i.e. in | |
116 | uc->uc_link->uc_mcontext.regs->msr. The top word contains the transactional | |
117 | state TS. | |
118 | ||
119 | However, basic signal handlers don't need to be aware of transactions | |
120 | and simply returning from the handler will deal with things correctly: | |
121 | ||
122 | Transaction-aware signal handlers can read the transactional register state | |
123 | from the second ucontext. This will be necessary for crash handlers to | |
124 | determine, for example, the address of the instruction causing the SIGSEGV. | |
125 | ||
126 | Example signal handler: | |
127 | ||
128 | void crash_handler(int sig, siginfo_t *si, void *uc) | |
129 | { | |
130 | ucontext_t *ucp = uc; | |
131 | ucontext_t *transactional_ucp = ucp->uc_link; | |
132 | ||
133 | if (ucp_link) { | |
134 | u64 msr = ucp->uc_mcontext.regs->msr; | |
135 | /* May have transactional ucontext! */ | |
136 | #ifndef __powerpc64__ | |
137 | msr |= ((u64)transactional_ucp->uc_mcontext.regs->msr) << 32; | |
138 | #endif | |
139 | if (MSR_TM_ACTIVE(msr)) { | |
140 | /* Yes, we crashed during a transaction. Oops. */ | |
141 | fprintf(stderr, "Transaction to be restarted at 0x%llx, but " | |
142 | "crashy instruction was at 0x%llx\n", | |
143 | ucp->uc_mcontext.regs->nip, | |
144 | transactional_ucp->uc_mcontext.regs->nip); | |
145 | } | |
146 | } | |
147 | ||
148 | fix_the_problem(ucp->dar); | |
149 | } | |
150 | ||
2b3f8e87 MN |
151 | When in an active transaction that takes a signal, we need to be careful with |
152 | the stack. It's possible that the stack has moved back up after the tbegin. | |
153 | The obvious case here is when the tbegin is called inside a function that | |
154 | returns before a tend. In this case, the stack is part of the checkpointed | |
155 | transactional memory state. If we write over this non transactionally or in | |
156 | suspend, we are in trouble because if we get a tm abort, the program counter and | |
157 | stack pointer will be back at the tbegin but our in memory stack won't be valid | |
158 | anymore. | |
159 | ||
160 | To avoid this, when taking a signal in an active transaction, we need to use | |
161 | the stack pointer from the checkpointed state, rather than the speculated | |
162 | state. This ensures that the signal context (written tm suspended) will be | |
163 | written below the stack required for the rollback. The transaction is aborted | |
c98be0c9 | 164 | because of the treclaim, so any memory written between the tbegin and the |
2b3f8e87 MN |
165 | signal will be rolled back anyway. |
166 | ||
167 | For signals taken in non-TM or suspended mode, we use the | |
168 | normal/non-checkpointed stack pointer. | |
169 | ||
db8ff907 MN |
170 | |
171 | Failure cause codes used by kernel | |
172 | ================================== | |
173 | ||
174 | These are defined in <asm/reg.h>, and distinguish different reasons why the | |
175 | kernel aborted a transaction: | |
176 | ||
177 | TM_CAUSE_RESCHED Thread was rescheduled. | |
d1d91578 | 178 | TM_CAUSE_TLBI Software TLB invalid. |
db8ff907 | 179 | TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap. |
b4b56f9e | 180 | TM_CAUSE_SYSCALL Syscall from active transaction. |
db8ff907 MN |
181 | TM_CAUSE_SIGNAL Signal delivered. |
182 | TM_CAUSE_MISC Currently unused. | |
6ce6c629 MN |
183 | TM_CAUSE_ALIGNMENT Alignment fault. |
184 | TM_CAUSE_EMULATE Emulation that touched memory. | |
db8ff907 | 185 | |
6ce6c629 MN |
186 | These can be checked by the user program's abort handler as TEXASR[0:7]. If |
187 | bit 7 is set, it indicates that the error is consider persistent. For example | |
d1d91578 | 188 | a TM_CAUSE_ALIGNMENT will be persistent while a TM_CAUSE_RESCHED will not. |
db8ff907 MN |
189 | |
190 | GDB | |
191 | === | |
192 | ||
193 | GDB and ptrace are not currently TM-aware. If one stops during a transaction, | |
194 | it looks like the transaction has just started (the checkpointed state is | |
195 | presented). The transaction cannot then be continued and will take the failure | |
196 | handler route. Furthermore, the transactional 2nd register state will be | |
197 | inaccessible. GDB can currently be used on programs using TM, but not sensibly | |
198 | in parts within transactions. |