• S
    ring-buffer: add NMI protection for spinlocks · 78d904b4
    Steven Rostedt 提交于
    Impact: prevent deadlock in NMI
    
    The ring buffers are not yet totally lockless with writing to
    the buffer. When a writer crosses a page, it grabs a per cpu spinlock
    to protect against a reader. The spinlocks taken by a writer are not
    to protect against other writers, since a writer can only write to
    its own per cpu buffer. The spinlocks protect against readers that
    can touch any cpu buffer. The writers are made to be reentrant
    with the spinlocks disabling interrupts.
    
    The problem arises when an NMI writes to the buffer, and that write
    crosses a page boundary. If it grabs a spinlock, it can be racing
    with another writer (since disabling interrupts does not protect
    against NMIs) or with a reader on the same CPU. Luckily, most of the
    users are not reentrant and protects against this issue. But if a
    user of the ring buffer becomes reentrant (which is what the ring
    buffers do allow), if the NMI also writes to the ring buffer then
    we risk the chance of a deadlock.
    
    This patch moves the ftrace_nmi_enter called by nmi_enter() to the
    ring buffer code. It replaces the current ftrace_nmi_enter that is
    used by arch specific code to arch_ftrace_nmi_enter and updates
    the Kconfig to handle it.
    
    When an NMI is called, it will set a per cpu variable in the ring buffer
    code and will clear it when the NMI exits. If a write to the ring buffer
    crosses page boundaries inside an NMI, a trylock is used on the spin
    lock instead. If the spinlock fails to be acquired, then the entry
    is discarded.
    
    This bug appeared in the ftrace work in the RT tree, where event tracing
    is reentrant. This workaround solved the deadlocks that appeared there.
    Signed-off-by: NSteven Rostedt <srostedt@redhat.com>
    78d904b4
ftrace.c 12.6 KB