• S
    tracing/lockdep: Disable lockdep first in entering NMI · 0f1ac8fd
    Steven Rostedt 提交于
    When function tracing with either debug locks enabled or tracing
    preempt disabled, the add_preempt_count() is traced. This is an
    issue with lockdep and function tracing. As function tracing
    can disable interrupts, and lockdep records that change,
    lockdep may not be able to handle this recursion if it happens from
    an NMI context.
    
    The first thing that an NMI does is:
    
     #define nmi_enter()					\
    	do {							\
    		ftrace_nmi_enter();				\
    		BUG_ON(in_nmi());				\
    		add_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET);	\
    		lockdep_off();					\
    		rcu_nmi_enter();				\
    		trace_hardirq_enter();				\
    	} while (0)
    
    When the add_preempt_count() is traced, and the tracing callback
    disables interrupts, it will jump into the lockdep code. There's
    some places in lockdep that can't handle this re-entrance, and
    causes lockdep to fail.
    
    As the lockdep_off() (and lockdep_on) is a simple:
    
    void lockdep_off(void)
    {
    	current->lockdep_recursion++;
    }
    
    and is never traced, it can be called first in nmi_enter()
    and lockdep_on() last in nmi_exit().
    
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
    0f1ac8fd
hardirq.h 5.5 KB