21 May, 2016

1 commit

  • 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.

    The 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
    Suggested-by: Peter Zijlstra
    Suggested-by: Steven Rostedt
    Cc: Jan Kara
    Acked-by: Russell King [arm part]
    Cc: Daniel Thompson
    Cc: Jiri Kosina
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Ralf Baechle
    Cc: Benjamin Herrenschmidt
    Cc: Martin Schwidefsky
    Cc: David Miller
    Cc: Daniel Thompson
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Petr Mladek
     

03 Oct, 2015

1 commit

  • Currently on ARM when is triggered from an interrupt handler
    (e.g. a SysRq issued using UART or kbd) the main CPU will wedge for ten
    seconds with interrupts masked before issuing a backtrace for every CPU
    except itself.

    The new backtrace code introduced by commit 96f0e00378d4 ("ARM: add
    basic support for on-demand backtrace of other CPUs") does not work
    correctly when run from an interrupt handler because IPI_CPU_BACKTRACE
    is used to generate the backtrace on all CPUs but cannot preempt the
    current calling context.

    This can be fixed by detecting that the calling context cannot be
    preempted and issuing the backtrace directly in this case. Issuing
    directly leaves us without any pt_regs to pass to nmi_cpu_backtrace()
    so we also modify the generic code to call dump_stack() when its
    argument is NULL.

    Acked-by: Hillf Danton
    Acked-by: Thomas Gleixner
    Signed-off-by: Daniel Thompson
    Signed-off-by: Russell King

    Daniel Thompson
     

17 Jul, 2015

1 commit

  • x86s NMI backtrace implementation (for arch_trigger_all_cpu_backtrace())
    is fairly generic in nature - the only architecture specific bits are
    the act of raising the NMI to other CPUs, and reporting the status of
    the NMI handler.

    These are fairly simple to factor out, and produce a generic
    implementation which can be shared between ARM and x86.

    Reviewed-by: Thomas Gleixner
    Signed-off-by: Russell King

    Russell King