]>
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 | ||
77 | Performing syscalls from within transaction is not recommended, and can lead | |
78 | to unpredictable results. | |
79 | ||
80 | Syscalls do not by design abort transactions, but beware: The kernel code will | |
81 | not be running in transactional state. The effect of syscalls will always | |
82 | remain visible, but depending on the call they may abort your transaction as a | |
83 | side-effect, read soon-to-be-aborted transactional data that should not remain | |
84 | invisible, etc. If you constantly retry a transaction that constantly aborts | |
85 | itself by calling a syscall, you'll have a livelock & make no progress. | |
86 | ||
87 | Simple syscalls (e.g. sigprocmask()) "could" be OK. Even things like write() | |
88 | from, say, printf() should be OK as long as the kernel does not access any | |
89 | memory that was accessed transactionally. | |
90 | ||
91 | Consider any syscalls that happen to work as debug-only -- not recommended for | |
92 | production use. Best to queue them up till after the transaction is over. | |
93 | ||
94 | ||
95 | Signals | |
96 | ======= | |
97 | ||
98 | Delivery of signals (both sync and async) during transactions provides a second | |
99 | thread state (ucontext/mcontext) to represent the second transactional register | |
100 | state. Signal delivery 'treclaim's to capture both register states, so signals | |
101 | abort transactions. The usual ucontext_t passed to the signal handler | |
102 | represents the checkpointed/original register state; the signal appears to have | |
103 | arisen at 'tbegin+4'. | |
104 | ||
105 | If the sighandler ucontext has uc_link set, a second ucontext has been | |
106 | delivered. For future compatibility the MSR.TS field should be checked to | |
107 | determine the transactional state -- if so, the second ucontext in uc->uc_link | |
108 | represents the active transactional registers at the point of the signal. | |
109 | ||
110 | For 64-bit processes, uc->uc_mcontext.regs->msr is a full 64-bit MSR and its TS | |
111 | field shows the transactional mode. | |
112 | ||
113 | For 32-bit processes, the mcontext's MSR register is only 32 bits; the top 32 | |
114 | bits are stored in the MSR of the second ucontext, i.e. in | |
115 | uc->uc_link->uc_mcontext.regs->msr. The top word contains the transactional | |
116 | state TS. | |
117 | ||
118 | However, basic signal handlers don't need to be aware of transactions | |
119 | and simply returning from the handler will deal with things correctly: | |
120 | ||
121 | Transaction-aware signal handlers can read the transactional register state | |
122 | from the second ucontext. This will be necessary for crash handlers to | |
123 | determine, for example, the address of the instruction causing the SIGSEGV. | |
124 | ||
125 | Example signal handler: | |
126 | ||
127 | void crash_handler(int sig, siginfo_t *si, void *uc) | |
128 | { | |
129 | ucontext_t *ucp = uc; | |
130 | ucontext_t *transactional_ucp = ucp->uc_link; | |
131 | ||
132 | if (ucp_link) { | |
133 | u64 msr = ucp->uc_mcontext.regs->msr; | |
134 | /* May have transactional ucontext! */ | |
135 | #ifndef __powerpc64__ | |
136 | msr |= ((u64)transactional_ucp->uc_mcontext.regs->msr) << 32; | |
137 | #endif | |
138 | if (MSR_TM_ACTIVE(msr)) { | |
139 | /* Yes, we crashed during a transaction. Oops. */ | |
140 | fprintf(stderr, "Transaction to be restarted at 0x%llx, but " | |
141 | "crashy instruction was at 0x%llx\n", | |
142 | ucp->uc_mcontext.regs->nip, | |
143 | transactional_ucp->uc_mcontext.regs->nip); | |
144 | } | |
145 | } | |
146 | ||
147 | fix_the_problem(ucp->dar); | |
148 | } | |
149 | ||
150 | ||
151 | Failure cause codes used by kernel | |
152 | ================================== | |
153 | ||
154 | These are defined in <asm/reg.h>, and distinguish different reasons why the | |
155 | kernel aborted a transaction: | |
156 | ||
157 | TM_CAUSE_RESCHED Thread was rescheduled. | |
24b92375 | 158 | TM_CAUSE_TLBI Software TLB invalide. |
db8ff907 MN |
159 | TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap. |
160 | TM_CAUSE_SYSCALL Currently unused; future syscalls that must abort | |
161 | transactions for consistency will use this. | |
162 | TM_CAUSE_SIGNAL Signal delivered. | |
163 | TM_CAUSE_MISC Currently unused. | |
164 | ||
165 | These can be checked by the user program's abort handler as TEXASR[0:7]. | |
166 | ||
167 | ||
168 | GDB | |
169 | === | |
170 | ||
171 | GDB and ptrace are not currently TM-aware. If one stops during a transaction, | |
172 | it looks like the transaction has just started (the checkpointed state is | |
173 | presented). The transaction cannot then be continued and will take the failure | |
174 | handler route. Furthermore, the transactional 2nd register state will be | |
175 | inaccessible. GDB can currently be used on programs using TM, but not sensibly | |
176 | in parts within transactions. |