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.

panic: use atomic_try_cmpxchg in panic() and nmi_panic()

Use atomic_try_cmpxchg instead of atomic_cmpxchg (*ptr, old, new) == old
in panic() and nmi_panic(). x86 CMPXCHG instruction returns success in ZF
flag, so this change saves a compare after cmpxchg (and related move
instruction in front of cmpxchg).

Also, rename cpu variable to this_cpu in nmi_panic() and try to unify
logic flow between panic() and nmi_panic().

No functional change intended.

[ubizjak@gmail.com: clean up if/else block]
Link: https://lkml.kernel.org/r/20230906191200.68707-1-ubizjak@gmail.com
Link: https://lkml.kernel.org/r/20230904152230.9227-1-ubizjak@gmail.com
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Uros Bizjak and committed by
Andrew Morton
9734fe4d 39835204

+13 -9
+13 -9
kernel/panic.c
··· 192 192 */ 193 193 void nmi_panic(struct pt_regs *regs, const char *msg) 194 194 { 195 - int old_cpu, cpu; 195 + int old_cpu, this_cpu; 196 196 197 - cpu = raw_smp_processor_id(); 198 - old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, cpu); 197 + old_cpu = PANIC_CPU_INVALID; 198 + this_cpu = raw_smp_processor_id(); 199 199 200 - if (old_cpu == PANIC_CPU_INVALID) 200 + /* atomic_try_cmpxchg updates old_cpu on failure */ 201 + if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) 201 202 panic("%s", msg); 202 - else if (old_cpu != cpu) 203 + else if (old_cpu != this_cpu) 203 204 nmi_panic_self_stop(regs); 204 205 } 205 206 EXPORT_SYMBOL(nmi_panic); ··· 312 311 * stop themself or will wait until they are stopped by the 1st CPU 313 312 * with smp_send_stop(). 314 313 * 315 - * `old_cpu == PANIC_CPU_INVALID' means this is the 1st CPU which 316 - * comes here, so go ahead. 314 + * cmpxchg success means this is the 1st CPU which comes here, 315 + * so go ahead. 317 316 * `old_cpu == this_cpu' means we came from nmi_panic() which sets 318 317 * panic_cpu to this CPU. In this case, this is also the 1st CPU. 319 318 */ 319 + old_cpu = PANIC_CPU_INVALID; 320 320 this_cpu = raw_smp_processor_id(); 321 - old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu); 322 321 323 - if (old_cpu != PANIC_CPU_INVALID && old_cpu != this_cpu) 322 + /* atomic_try_cmpxchg updates old_cpu on failure */ 323 + if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) { 324 + /* go ahead */ 325 + } else if (old_cpu != this_cpu) 324 326 panic_smp_self_stop(); 325 327 326 328 console_verbose();