]> www.infradead.org Git - users/dwmw2/linux.git/commit
lockdep: add lockdep_cleanup_dead_cpu() lockdep_cleanup_dead_cpu
authorDavid Woodhouse <dwmw@amazon.co.uk>
Sat, 28 Oct 2023 10:11:51 +0000 (11:11 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 26 Sep 2024 15:03:23 +0000 (16:03 +0100)
commit3a2e83956996681e0e3920847a6d01cd6ba37418
treeb28940ab54a4e26c1d92699ee9314b62faa8feb1
parentabf2050f51fdca0fd146388f83cddd95a57a008d
lockdep: add lockdep_cleanup_dead_cpu()

Add a function to check that an offline CPU has left the tracing
infrastructure in a sane state.

Commit 9bb69ba4c177 ("ACPI: processor_idle: use raw_safe_halt() in
acpi_idle_play_dead()") fixed an issue where the acpi_idle_play_dead()
function called safe_halt() instead of raw_safe_halt(), which had the
side-effect of setting the hardirqs_enabled flag for the offline CPU.

On x86 this triggered warnings from lockdep_assert_irqs_disabled() when
the CPU was brought back online again later. These warnings were too
early for the exception to be handled correctly.

So lockdep turned a perfectly harmless bug into a system crash with a
triple-fault.

Add lockdep_cleanup_dead_cpu() to check for this kind of failure mode,
print the events leading up to it, and correct it so that the CPU can
come online again correctly. Re-introducing the original bug now merely
results in this warning instead:

[   61.556652] smpboot: CPU 1 is now offline
[   61.556769] CPU 1 left hardirqs enabled!
[   61.556915] irq event stamp: 128149
[   61.556965] hardirqs last  enabled at (128149): [<ffffffff81720a36>] acpi_idle_play_dead+0x46/0x70
[   61.557055] hardirqs last disabled at (128148): [<ffffffff81124d50>] do_idle+0x90/0xe0
[   61.557117] softirqs last  enabled at (128078): [<ffffffff81cec74c>] __do_softirq+0x31c/0x423
[   61.557199] softirqs last disabled at (128065): [<ffffffff810baae1>] __irq_exit_rcu+0x91/0x100

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/irqflags.h
kernel/cpu.c
kernel/locking/lockdep.c