Skip to content

Commit

Permalink
panic: release stale console lock to always get the logbuf printed out
Browse files Browse the repository at this point in the history
In some cases we may end up killing the CPU holding the console lock
while still having valuable data in logbuf. E.g. I'm observing the
following:

- A crash is happening on one CPU and console_unlock() is being called on
  some other.

- console_unlock() tries to print out the buffer before releasing the lock
  and on slow console it takes time.

- in the meanwhile crashing CPU does lots of printk()-s with valuable data
  (which go to the logbuf) and sends IPIs to all other CPUs.

- console_unlock() finishes printing previous chunk and enables interrupts
  before trying to print out the rest, the CPU catches the IPI and never
  releases console lock.

This is not the only possible case: in VT/fb subsystems we have many other
console_lock()/console_unlock() users.  Non-masked interrupts (or
receiving NMI in case of extreme slowness) will have the same result.
Getting the whole console buffer printed out on crash should be top
priority.

[[email protected]: tweak comment text]
Signed-off-by: Vitaly Kuznetsov <[email protected]>
Cc: HATAYAMA Daisuke <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Jiri Kosina <[email protected]>
Cc: Baoquan He <[email protected]>
Cc: Prarit Bhargava <[email protected]>
Cc: Xie XiuQi <[email protected]>
Cc: Seth Jennings <[email protected]>
Cc: "K. Y. Srinivasan" <[email protected]>
Cc: Jan Kara <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
vittyvk authored and torvalds committed Nov 7, 2015
1 parent 7f83064 commit 08d7865
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions kernel/panic.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/sysrq.h>
#include <linux/init.h>
#include <linux/nmi.h>
#include <linux/console.h>

#define PANIC_TIMER_STEP 100
#define PANIC_BLINK_SPD 18
Expand Down Expand Up @@ -147,6 +148,15 @@ void panic(const char *fmt, ...)

bust_spinlocks(0);

/*
* We may have ended up stopping the CPU holding the lock (in
* smp_send_stop()) while still having some valuable data in the console
* buffer. Try to acquire the lock then release it regardless of the
* result. The release will also print the buffers out.
*/
console_trylock();
console_unlock();

if (!panic_blink)
panic_blink = no_blink;

Expand Down

0 comments on commit 08d7865

Please sign in to comment.