• Petr Mladek's avatar
    printk: Use the main logbuf in NMI when logbuf_lock is available · 719f6a70
    Petr Mladek authored
    The commit 42a0bb3f ("printk/nmi: generic solution for safe
    printk in NMI") caused that printk stores messages into a temporary
    buffer in NMI context.
    
    The buffer is per-CPU and therefore the size is rather limited.
    It works quite well for NMI backtraces. But there are longer logs
    that might get printed in NMI context, for example, lockdep
    warnings, ftrace_dump_on_oops.
    
    The temporary buffer is used to avoid deadlocks caused by
    logbuf_lock. Also it is needed to avoid races with the other
    temporary buffer that is used when PRINTK_SAFE_CONTEXT is entered.
    But the main buffer can be used in NMI if the lock is available
    and we did not interrupt PRINTK_SAFE_CONTEXT.
    
    The lock is checked using raw_spin_is_locked(). It might cause
    false negatives when the lock is taken on another CPU and
    this CPU is in the safe context from other reasons. Note that
    the safe context is used also to get console semaphore or when
    calling console drivers. For this reason, we do the check in
    printk_nmi_enter(). It makes the handling consistent for
    the entire NMI handler and avoids reshuffling of the messages.
    
    The patch also defines special printk context that allows
    to use printk_deferred() in NMI. Note that we could not flush
    the messages to the consoles because console drivers might use
    many other internal locks.
    
    The newly created vprintk_deferred() disables the preemption
    only around the irq work handling. It is needed there to keep
    the consistency between the two per-CPU variables. But there
    is no reason to disable preemption around vprintk_emit().
    
    Finally, the patch puts back explicit serialization of the NMI
    backtraces from different CPUs. It was removed by the
    commit a9edc880 ("x86/nmi: Perform a safe
    NMI stack trace on all CPUs"). It was not needed because
    the flushing of the temporary per-CPU buffers was serialized.
    
    Link: http://lkml.kernel.org/r/1493912763-24873-1-git-send-email-pmladek@suse.com
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Russell King <rack+kernel@arm.linux.org.uk>
    Cc: Daniel Thompson <daniel.thompson@linaro.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Chris Metcalf <cmetcalf@ezchip.com>
    Cc: x86@kernel.org
    Cc: linux-arm-kernel@lists.infradead.org
    Cc: linux-kernel@vger.kernel.org
    Suggested-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
    Acked-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
    Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
    719f6a70
printk.c 79.6 KB