public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: [PATCH 4/7] lockdep: Printk nice description for irq inversion bug
Date: Wed, 20 Apr 2011 21:41:57 -0400	[thread overview]
Message-ID: <20110421014259.910720381@goodmis.org> (raw)
In-Reply-To: 20110421014153.126662477@goodmis.org

[-- Attachment #1: 0004-lockdep-Printk-nice-description-for-irq-inversion-bu.patch --]
[-- Type: text/plain, Size: 3925 bytes --]

From: Steven Rostedt <srostedt@redhat.com>

The irq inversion and irq dependency bug are only subtly different.
The diffenerence lies where the interrupt occurred.

For irq dependency:

	irq_disable
	lock(A)
	lock(B)
	unlock(B)
	unlock(A)
	irq_enable

	lock(B)
	unlock(B)

 	<interrupt>
	  lock(A)

The interrupt comes in after it has been established that lock A
can be held when taking an irq unsafe lock. Lockdep detects the problem
when taking lock A in interrupt context.

 	<interrupt>
	  lock(A)

	irq_disable
	lock(A)
	lock(B)
	unlock(B)
	unlock(A)
	irq_enable

	lock(B)
	unlock(B)

With the irq_inversion the irq happens before it is established
and lockdep detects the problem with the taking of lock B.

Since the problem with the locking for both of these issues are
in actuality the same, they both should report the same scenario.

other info that might help us debug this:

Chain exists of:
  &rq->lock --> lockA --> lockC

 Possible interrupt unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(lockC);
                               local_irq_disable();
                               lock(&rq->lock);
                               lock(lockA);
  <Interrupt>
    lock(&rq->lock);

 *** DEADLOCK ***

Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/lockdep.c |   34 +++++++++++++++++++++++++++++-----
 1 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index a0f253b..8646b8c 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -1395,15 +1395,15 @@ print_shortest_lock_dependencies(struct lock_list *leaf,
 static void
 print_irq_lock_scenario(struct lock_list *safe_entry,
 			struct lock_list *unsafe_entry,
-			struct held_lock *prev,
-			struct held_lock *next)
+			struct lock_class *prev_class,
+			struct lock_class *next_class)
 {
 	struct lock_class *safe_class = safe_entry->class;
 	struct lock_class *unsafe_class = unsafe_entry->class;
-	struct lock_class *middle_class = hlock_class(prev);
+	struct lock_class *middle_class = prev_class;
 
 	if (middle_class == safe_class)
-		middle_class = hlock_class(next);
+		middle_class = next_class;
 
 	/*
 	 * A direct locking problem where unsafe_class lock is taken
@@ -1499,7 +1499,8 @@ print_bad_irq_dependency(struct task_struct *curr,
 	print_stack_trace(forwards_entry->class->usage_traces + bit2, 1);
 
 	printk("\nother info that might help us debug this:\n\n");
-	print_irq_lock_scenario(backwards_entry, forwards_entry, prev, next);
+	print_irq_lock_scenario(backwards_entry, forwards_entry,
+				hlock_class(prev), hlock_class(next));
 
 	lockdep_print_held_locks(curr);
 
@@ -2219,6 +2220,10 @@ print_irq_inversion_bug(struct task_struct *curr,
 			struct held_lock *this, int forwards,
 			const char *irqclass)
 {
+	struct lock_list *entry = other;
+	struct lock_list *middle = NULL;
+	int depth;
+
 	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
 		return 0;
 
@@ -2237,6 +2242,25 @@ print_irq_inversion_bug(struct task_struct *curr,
 	printk("\n\nand interrupts could create inverse lock ordering between them.\n\n");
 
 	printk("\nother info that might help us debug this:\n");
+
+	/* Find a middle lock (if one exists) */
+	depth = get_lock_depth(other);
+	do {
+		if (depth == 0 && (entry != root)) {
+			printk("lockdep:%s bad path found in chain graph\n", __func__);
+			break;
+		}
+		middle = entry;
+		entry = get_lock_parent(entry);
+		depth--;
+	} while (entry && entry != root && (depth >= 0));
+	if (forwards)
+		print_irq_lock_scenario(root, other,
+			middle ? middle->class : root->class, other->class);
+	else
+		print_irq_lock_scenario(other, root,
+			middle ? middle->class : other->class, root->class);
+
 	lockdep_print_held_locks(curr);
 
 	printk("\nthe shortest dependencies between 2nd lock and 1st lock:\n");
-- 
1.7.2.3



  parent reply	other threads:[~2011-04-21  1:43 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-21  1:41 [PATCH 0/7] [GIT PULL] lockdep: Show description of lockdep problems Steven Rostedt
2011-04-21  1:41 ` [PATCH 1/7] lockdep: Print a nice description of an irq locking issue Steven Rostedt
2011-04-21  6:43   ` Yong Zhang
2011-04-21  7:02   ` Yong Zhang
2011-04-21  7:08     ` Yong Zhang
2011-04-21 11:40     ` Steven Rostedt
2011-04-21 13:35       ` Yong Zhang
2011-04-21 14:24         ` Steven Rostedt
2011-04-22  1:41           ` Yong Zhang
2011-04-22  2:34             ` Steven Rostedt
2011-04-22  6:10               ` Ingo Molnar
2011-04-22 12:19   ` [tip:core/locking] lockdep: Print a nicer description for irq lock inversions tip-bot for Steven Rostedt
2011-04-21  1:41 ` [PATCH 2/7] lockdep: Print a nice description of normal deadlocks Steven Rostedt
2011-04-22 12:20   ` [tip:core/locking] lockdep: Print a nicer description for " tip-bot for Steven Rostedt
2011-04-21  1:41 ` [PATCH 3/7] lockdep: Print a nice description of simple deadlock Steven Rostedt
2011-04-22 12:20   ` [tip:core/locking] lockdep: Print a nicer description for simple deadlocks tip-bot for Steven Rostedt
2011-04-21  1:41 ` Steven Rostedt [this message]
2011-04-22 12:20   ` [tip:core/locking] lockdep: Print a nicer description for irq inversion bugs tip-bot for Steven Rostedt
2011-04-21  1:41 ` [PATCH 5/7] lockdep: Replace bad path error message with something sane Steven Rostedt
2011-04-22 12:21   ` [tip:core/locking] lockdep: Replace "Bad BFS generated tree" message with something less cryptic tip-bot for Steven Rostedt
2011-04-21  1:41 ` [PATCH 6/7] lockdep: Print a nice description of simple irq inversion Steven Rostedt
2011-04-22 12:21   ` [tip:core/locking] lockdep: Print a nicer description for simple irq lock inversions tip-bot for Steven Rostedt
2011-04-21  1:42 ` [PATCH 7/7] lockdep: Remove cmpxchg to update nr_chain_hlocks Steven Rostedt
2011-04-21  6:50   ` Yong Zhang
2011-04-22 12:22   ` [tip:core/locking] " tip-bot for Steven Rostedt
2011-04-21  6:25 ` [PATCH 0/7] [GIT PULL] lockdep: Show description of lockdep problems Yong Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110421014259.910720381@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=fweisbec@gmail.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox