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>
This commit is contained in:
parent
3983520491
commit
9734fe4dc2
|
@ -192,14 +192,15 @@ atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);
|
||||||
*/
|
*/
|
||||||
void nmi_panic(struct pt_regs *regs, const char *msg)
|
void nmi_panic(struct pt_regs *regs, const char *msg)
|
||||||
{
|
{
|
||||||
int old_cpu, cpu;
|
int old_cpu, this_cpu;
|
||||||
|
|
||||||
cpu = raw_smp_processor_id();
|
old_cpu = PANIC_CPU_INVALID;
|
||||||
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, cpu);
|
this_cpu = raw_smp_processor_id();
|
||||||
|
|
||||||
if (old_cpu == PANIC_CPU_INVALID)
|
/* atomic_try_cmpxchg updates old_cpu on failure */
|
||||||
|
if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu))
|
||||||
panic("%s", msg);
|
panic("%s", msg);
|
||||||
else if (old_cpu != cpu)
|
else if (old_cpu != this_cpu)
|
||||||
nmi_panic_self_stop(regs);
|
nmi_panic_self_stop(regs);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(nmi_panic);
|
EXPORT_SYMBOL(nmi_panic);
|
||||||
|
@ -311,15 +312,18 @@ void panic(const char *fmt, ...)
|
||||||
* stop themself or will wait until they are stopped by the 1st CPU
|
* stop themself or will wait until they are stopped by the 1st CPU
|
||||||
* with smp_send_stop().
|
* with smp_send_stop().
|
||||||
*
|
*
|
||||||
* `old_cpu == PANIC_CPU_INVALID' means this is the 1st CPU which
|
* cmpxchg success means this is the 1st CPU which comes here,
|
||||||
* comes here, so go ahead.
|
* so go ahead.
|
||||||
* `old_cpu == this_cpu' means we came from nmi_panic() which sets
|
* `old_cpu == this_cpu' means we came from nmi_panic() which sets
|
||||||
* panic_cpu to this CPU. In this case, this is also the 1st CPU.
|
* panic_cpu to this CPU. In this case, this is also the 1st CPU.
|
||||||
*/
|
*/
|
||||||
|
old_cpu = PANIC_CPU_INVALID;
|
||||||
this_cpu = raw_smp_processor_id();
|
this_cpu = raw_smp_processor_id();
|
||||||
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu);
|
|
||||||
|
|
||||||
if (old_cpu != PANIC_CPU_INVALID && old_cpu != this_cpu)
|
/* atomic_try_cmpxchg updates old_cpu on failure */
|
||||||
|
if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) {
|
||||||
|
/* go ahead */
|
||||||
|
} else if (old_cpu != this_cpu)
|
||||||
panic_smp_self_stop();
|
panic_smp_self_stop();
|
||||||
|
|
||||||
console_verbose();
|
console_verbose();
|
||||||
|
|
Loading…
Reference in New Issue