Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rseq: Move algorithm comment to top

Move the comment which documents the RSEQ algorithm to the top of the file,
so it does not create horrible diffs later when the actual implementation
is fed into the mincer.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027084306.149519580@linutronix.de

authored by

Thomas Gleixner and committed by
Ingo Molnar
77f19e4d fdc0f39d

+59 -60
+59 -60
kernel/rseq.c
··· 8 8 * Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 9 9 */ 10 10 11 + /* 12 + * Restartable sequences are a lightweight interface that allows 13 + * user-level code to be executed atomically relative to scheduler 14 + * preemption and signal delivery. Typically used for implementing 15 + * per-cpu operations. 16 + * 17 + * It allows user-space to perform update operations on per-cpu data 18 + * without requiring heavy-weight atomic operations. 19 + * 20 + * Detailed algorithm of rseq user-space assembly sequences: 21 + * 22 + * init(rseq_cs) 23 + * cpu = TLS->rseq::cpu_id_start 24 + * [1] TLS->rseq::rseq_cs = rseq_cs 25 + * [start_ip] ---------------------------- 26 + * [2] if (cpu != TLS->rseq::cpu_id) 27 + * goto abort_ip; 28 + * [3] <last_instruction_in_cs> 29 + * [post_commit_ip] ---------------------------- 30 + * 31 + * The address of jump target abort_ip must be outside the critical 32 + * region, i.e.: 33 + * 34 + * [abort_ip] < [start_ip] || [abort_ip] >= [post_commit_ip] 35 + * 36 + * Steps [2]-[3] (inclusive) need to be a sequence of instructions in 37 + * userspace that can handle being interrupted between any of those 38 + * instructions, and then resumed to the abort_ip. 39 + * 40 + * 1. Userspace stores the address of the struct rseq_cs assembly 41 + * block descriptor into the rseq_cs field of the registered 42 + * struct rseq TLS area. This update is performed through a single 43 + * store within the inline assembly instruction sequence. 44 + * [start_ip] 45 + * 46 + * 2. Userspace tests to check whether the current cpu_id field match 47 + * the cpu number loaded before start_ip, branching to abort_ip 48 + * in case of a mismatch. 49 + * 50 + * If the sequence is preempted or interrupted by a signal 51 + * at or after start_ip and before post_commit_ip, then the kernel 52 + * clears TLS->__rseq_abi::rseq_cs, and sets the user-space return 53 + * ip to abort_ip before returning to user-space, so the preempted 54 + * execution resumes at abort_ip. 55 + * 56 + * 3. Userspace critical section final instruction before 57 + * post_commit_ip is the commit. The critical section is 58 + * self-terminating. 59 + * [post_commit_ip] 60 + * 61 + * 4. <success> 62 + * 63 + * On failure at [2], or if interrupted by preempt or signal delivery 64 + * between [1] and [3]: 65 + * 66 + * [abort_ip] 67 + * F1. <failure> 68 + */ 69 + 11 70 #include <linux/sched.h> 12 71 #include <linux/uaccess.h> 13 72 #include <linux/syscalls.h> ··· 156 97 #define rseq_unsafe_put_user(t, value, field, error_label) \ 157 98 unsafe_put_user(value, &t->rseq->field, error_label) 158 99 #endif 159 - 160 - /* 161 - * 162 - * Restartable sequences are a lightweight interface that allows 163 - * user-level code to be executed atomically relative to scheduler 164 - * preemption and signal delivery. Typically used for implementing 165 - * per-cpu operations. 166 - * 167 - * It allows user-space to perform update operations on per-cpu data 168 - * without requiring heavy-weight atomic operations. 169 - * 170 - * Detailed algorithm of rseq user-space assembly sequences: 171 - * 172 - * init(rseq_cs) 173 - * cpu = TLS->rseq::cpu_id_start 174 - * [1] TLS->rseq::rseq_cs = rseq_cs 175 - * [start_ip] ---------------------------- 176 - * [2] if (cpu != TLS->rseq::cpu_id) 177 - * goto abort_ip; 178 - * [3] <last_instruction_in_cs> 179 - * [post_commit_ip] ---------------------------- 180 - * 181 - * The address of jump target abort_ip must be outside the critical 182 - * region, i.e.: 183 - * 184 - * [abort_ip] < [start_ip] || [abort_ip] >= [post_commit_ip] 185 - * 186 - * Steps [2]-[3] (inclusive) need to be a sequence of instructions in 187 - * userspace that can handle being interrupted between any of those 188 - * instructions, and then resumed to the abort_ip. 189 - * 190 - * 1. Userspace stores the address of the struct rseq_cs assembly 191 - * block descriptor into the rseq_cs field of the registered 192 - * struct rseq TLS area. This update is performed through a single 193 - * store within the inline assembly instruction sequence. 194 - * [start_ip] 195 - * 196 - * 2. Userspace tests to check whether the current cpu_id field match 197 - * the cpu number loaded before start_ip, branching to abort_ip 198 - * in case of a mismatch. 199 - * 200 - * If the sequence is preempted or interrupted by a signal 201 - * at or after start_ip and before post_commit_ip, then the kernel 202 - * clears TLS->__rseq_abi::rseq_cs, and sets the user-space return 203 - * ip to abort_ip before returning to user-space, so the preempted 204 - * execution resumes at abort_ip. 205 - * 206 - * 3. Userspace critical section final instruction before 207 - * post_commit_ip is the commit. The critical section is 208 - * self-terminating. 209 - * [post_commit_ip] 210 - * 211 - * 4. <success> 212 - * 213 - * On failure at [2], or if interrupted by preempt or signal delivery 214 - * between [1] and [3]: 215 - * 216 - * [abort_ip] 217 - * F1. <failure> 218 - */ 219 100 220 101 static int rseq_update_cpu_node_id(struct task_struct *t) 221 102 {