Re: [RFC PATCH] panic: fix deadlock in panic()

From: Petr Mladek
Date: Fri Jun 05 2020 - 07:37:02 EST


On Fri 2020-06-05 18:42:57, chengjian (D) wrote:
> Hi, Petr
>
> On 2020/6/4 16:29, Petr Mladek wrote:
>
> > It might cause double unlock (deadlock) on architectures that did not
> > use NMI to stop the CPUs.
> >
> > I have created a conservative fix for this problem for SLES, see
> > https://github.com/openSUSE/kernel-source/blob/SLE15-SP2-UPDATE/patches.suse/printk-panic-Avoid-deadlock-in-printk-after-stopping-CPUs-by-NMI.patch
> > It solves the problem only on x86 architecture.
> >
> > There are many hacks that try to solve various scenarios but it
> > is getting too complicated and does not solve all problems.
>
> I have read your conservative fix and I have some question,
>
> 1-- does the console_sem need to be reinitialized ?

No, it is not needed:

+ printk() itself does try_lock() and skips console handling when the
semaphore is not available.

+ panic() tries to push the messages later in console_flush_on_panic().
It ignores the semaphore. Also most console drivers ignore their
internal locks because oops_in_progress is set by bust_spinlocks().


> 2-- Other architectures without NMI, is there no such problem ?

The situation is more complicated when NMI is not used. Non-stopped
CPUs are in unknown state, most likely in a busy loop. Nobody knows
whether printk() is repeatedly called in the loop. When it was called,
re-initializing any lock would cause double unlock and deadlock.

It would be possible to add some more hacks. One problem is that
there are two groups of users. One prefer to risk a deadlock and
have a chance to see the messages. Others prefer to always
reach emergency_restart() and reboot the machine.

This is one big motivation for working on lockless printk().

Best Regards,
Petr