printk, lockdep: Disable lock debugging on zap_locks()
authorPeter Zijlstra <a.p.zijlstra@chello.nl>
Tue, 7 Jun 2011 09:17:30 +0000 (11:17 +0200)
committerIngo Molnar <mingo@elte.hu>
Mon, 14 Nov 2011 12:35:16 +0000 (13:35 +0100)
zap_locks() is used by printk() in a last ditch effort to get data
out, clearly we cannot trust lock state after this so make it disable
lock debugging.

Also don't treat printk recursion through lockdep as a normal
recursion bug but try hard to get the lockdep splat out.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-kqxwmo4xz37e1s8w0xopvr0q@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
include/linux/lockdep.h
kernel/printk.c

index b6a56e37284c41e0954a7a794ddab4b617ebf547..d36619ead3baee89555505ade8c8f0fcc060f587 100644 (file)
@@ -343,6 +343,8 @@ extern void lockdep_trace_alloc(gfp_t mask);
 
 #define lockdep_assert_held(l) WARN_ON(debug_locks && !lockdep_is_held(l))
 
+#define lockdep_recursing(tsk) ((tsk)->lockdep_recursion)
+
 #else /* !LOCKDEP */
 
 static inline void lockdep_off(void)
@@ -392,6 +394,8 @@ struct lock_class_key { };
 
 #define lockdep_assert_held(l)                 do { } while (0)
 
+#define lockdep_recursing(tsk)                 (0)
+
 #endif /* !LOCKDEP */
 
 #ifdef CONFIG_LOCK_STAT
index 1455a0d4eedd4b386c759d689f939ba5d7a9007a..6d087944e72abc9dbb0b72066453764e67637dfe 100644 (file)
@@ -688,6 +688,7 @@ static void zap_locks(void)
 
        oops_timestamp = jiffies;
 
+       debug_locks_off();
        /* If a crash is occurring, make sure we can't deadlock */
        raw_spin_lock_init(&logbuf_lock);
        /* And make sure that we print immediately */
@@ -856,7 +857,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                 * recursion and return - but flag the recursion so that
                 * it can be printed at the next appropriate moment:
                 */
-               if (!oops_in_progress) {
+               if (!oops_in_progress && !lockdep_recursing(current)) {
                        recursion_bug = 1;
                        goto out_restore_irqs;
                }