• Joel Fernandes (Google)'s avatar
    softirq: Reorder trace_softirqs_on to prevent lockdep splat · 1a63dcd8
    Joel Fernandes (Google) authored
    I'm able to reproduce a lockdep splat with config options:
    CONFIG_PROVE_LOCKING=y,
    CONFIG_DEBUG_LOCK_ALLOC=y and
    CONFIG_PREEMPTIRQ_EVENTS=y
    
    $ echo 1 > /d/tracing/events/preemptirq/preempt_enable/enable
    
    [   26.112609] DEBUG_LOCKS_WARN_ON(current->softirqs_enabled)
    [   26.112636] WARNING: CPU: 0 PID: 118 at kernel/locking/lockdep.c:3854
    [...]
    [   26.144229] Call Trace:
    [   26.144926]  <IRQ>
    [   26.145506]  lock_acquire+0x55/0x1b0
    [   26.146499]  ? __do_softirq+0x46f/0x4d9
    [   26.147571]  ? __do_softirq+0x46f/0x4d9
    [   26.148646]  trace_preempt_on+0x8f/0x240
    [   26.149744]  ? trace_preempt_on+0x4d/0x240
    [   26.150862]  ? __do_softirq+0x46f/0x4d9
    [   26.151930]  preempt_count_sub+0x18a/0x1a0
    [   26.152985]  __do_softirq+0x46f/0x4d9
    [   26.153937]  irq_exit+0x68/0xe0
    [   26.154755]  smp_apic_timer_interrupt+0x271/0x280
    [   26.156056]  apic_timer_interrupt+0xf/0x20
    [   26.157105]  </IRQ>
    
    The issue was this:
    
    preempt_count = 1 << SOFTIRQ_SHIFT
    
    	__local_bh_enable(cnt = 1 << SOFTIRQ_SHIFT) {
    		if (softirq_count() == (cnt && SOFTIRQ_MASK)) {
    			trace_softirqs_on() {
    				current->softirqs_enabled = 1;
    			}
    		}
    		preempt_count_sub(cnt) {
    			trace_preempt_on() {
    				tracepoint() {
    					rcu_read_lock_sched() {
    						// jumps into lockdep
    
    Where preempt_count still has softirqs disabled, but
    current->softirqs_enabled is true, and we get a splat.
    
    Link: http://lkml.kernel.org/r/20180607201143.247775-1-joel@joelfernandes.org
    
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
    Cc: Tom Zanussi <tom.zanussi@linux.intel.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Thomas Glexiner <tglx@linutronix.de>
    Cc: Boqun Feng <boqun.feng@gmail.com>
    Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Todd Kjos <tkjos@google.com>
    Cc: Erick Reyes <erickreyes@google.com>
    Cc: Julia Cartwright <julia@ni.com>
    Cc: Byungchul Park <byungchul.park@lge.com>
    Cc: stable@vger.kernel.org
    Reviewed-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
    Fixes: d5915816 ("tracing: Add support for preempt and irq enable/disable events")
    Signed-off-by: default avatarJoel Fernandes (Google) <joel@joelfernandes.org>
    Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
    1a63dcd8
softirq.c 18.3 KB