]> git.karo-electronics.de Git - karo-tx-linux.git/commit
printk/nmi: generic solution for safe printk in NMI
authorPetr Mladek <pmladek@suse.com>
Tue, 9 Feb 2016 23:13:08 +0000 (10:13 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 9 Feb 2016 23:13:08 +0000 (10:13 +1100)
commita491e297b89e1285984fb855054abc9b928bb925
tree996517364ca2efbf3e6fbd8d72419814f9f52f91
parent13cf69131db5784752b6e691ba815c3ba0c06b5c
printk/nmi: generic solution for safe printk in NMI

printk() takes some locks and could not be used a safe way in NMI context.

The chance of a deadlock is real especially when printing stacks from all
CPUs.  This particular problem has been addressed on x86 by the commit
a9edc8809328 ("x86/nmi: Perform a safe NMI stack trace on all CPUs").

The patchset brings two big advantages.  First, it makes the NMI
backtraces safe on all architectures for free.  Second, it makes all NMI
messages almost safe on all architectures (the temporary buffer is
limited.  We still should keep the number of messages in NMI context at
minimum).

Note that there already are several messages printed in NMI context:
WARN_ON(in_nmi()), BUG_ON(in_nmi()), anything being printed out from MCE
handlers.  These are not easy to avoid.

This patch reuses most of the code and makes it generic.  It is useful for
all messages and architectures that support NMI.

The alternative printk_func is set when entering and is reseted when
leaving NMI context.  It queues IRQ work to copy the messages into the
main ring buffer in a safe context.

__printk_nmi_flush() copies all available messages and reset the buffer.
Then we could use a simple cmpxchg operations to get synchronized with
writers.  There is also used a spinlock to get synchronized with other
flushers.

We do not longer use seq_buf because it depends on external lock.  It
would be hard to make all supported operations safe for a lockless use.
It would be confusing and error prone to make only some operations safe.

The code is put into separate printk/nmi.c as suggested by Steven Rostedt.
It needs a per-CPU buffer and is compiled only on architectures that call
nmi_enter().  This is achieved by the new HAVE_NMI Kconfig flag.

One exception is arm where the deferred printing is used for printing
backtraces even without NMI.  For this purpose, we define NEED_PRINTK_NMI
Kconfig flag.  The alternative printk_func is explicitly set when
IPI_CPU_BACKTRACE is handled.

The other exceptions are MN10300 and Xtensa architectures.  We need to
clean up NMI handling there first.  Let's do it separately.

The patch is heavily based on the draft from Peter Zijlstra, see
https://lkml.org/lkml/2015/6/10/327

[arnd@arndb.de: printk-nmi: use %zu format string for size_t]
[akpm@linux-foundation.org: min_t->min - all types are size_t here]
Signed-off-by: Petr Mladek <pmladek@suse.com>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Daniel Thompson <daniel.thompson@linaro.org>
Cc: Jiri Kosina <jkosina@suse.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: David Miller <davem@davemloft.net>
Cc: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
24 files changed:
arch/Kconfig
arch/arm/Kconfig
arch/arm/kernel/smp.c
arch/avr32/Kconfig
arch/blackfin/Kconfig
arch/cris/Kconfig
arch/mips/Kconfig
arch/powerpc/Kconfig
arch/s390/Kconfig
arch/sh/Kconfig
arch/sparc/Kconfig
arch/tile/Kconfig
arch/x86/Kconfig
arch/x86/kernel/apic/hw_nmi.c
include/linux/hardirq.h
include/linux/percpu.h
include/linux/printk.h
init/Kconfig
init/main.c
kernel/printk/Makefile
kernel/printk/internal.h [new file with mode: 0644]
kernel/printk/nmi.c [new file with mode: 0644]
kernel/printk/printk.c
lib/nmi_backtrace.c