From: tip-bot for Ming Lei <tom.leiming@gmail.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@redhat.com,
a.p.zijlstra@chello.nl, tglx@linutronix.de,
tom.leiming@gmail.com, mingo@elte.hu
Subject: [tip:core/locking] lockdep: Implement check_noncircular() by BFS
Date: Sun, 2 Aug 2009 13:02:00 GMT [thread overview]
Message-ID: <tip-db0002a32f31060ca900b533d93a074ddf7d5b61@git.kernel.org> (raw)
In-Reply-To: <1246201486-7308-5-git-send-email-tom.leiming@gmail.com>
Commit-ID: db0002a32f31060ca900b533d93a074ddf7d5b61
Gitweb: http://git.kernel.org/tip/db0002a32f31060ca900b533d93a074ddf7d5b61
Author: Ming Lei <tom.leiming@gmail.com>
AuthorDate: Thu, 16 Jul 2009 15:44:29 +0200
Committer: Peter Zijlstra <a.p.zijlstra@chello.nl>
CommitDate: Fri, 24 Jul 2009 10:49:50 +0200
lockdep: Implement check_noncircular() by BFS
This patch uses BFS to implement check_noncircular() and
prints the generated shortest circle if exists.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1246201486-7308-5-git-send-email-tom.leiming@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/lockdep.c | 89 ++++++++++++++++++++++-------------------------------
1 files changed, 37 insertions(+), 52 deletions(-)
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index ce6d09e..5609d30 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -985,12 +985,7 @@ static inline int __bfs_backward(struct lock_list *src_entry,
* Recursive, forwards-direction lock-dependency checking, used for
* both noncyclic checking and for hardirq-unsafe/softirq-unsafe
* checking.
- *
- * (to keep the stackframe of the recursive functions small we
- * use these global variables, and we also mark various helper
- * functions as noinline.)
*/
-static struct held_lock *check_source, *check_target;
/*
* Print a dependency chain entry (this is only done when a deadlock
@@ -1014,7 +1009,9 @@ print_circular_bug_entry(struct lock_list *target, unsigned int depth)
* header first:
*/
static noinline int
-print_circular_bug_header(struct lock_list *entry, unsigned int depth)
+print_circular_bug_header(struct lock_list *entry, unsigned int depth,
+ struct held_lock *check_src,
+ struct held_lock *check_tgt)
{
struct task_struct *curr = current;
@@ -1027,9 +1024,9 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
printk( "-------------------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
curr->comm, task_pid_nr(curr));
- print_lock(check_source);
+ print_lock(check_src);
printk("\nbut task is already holding lock:\n");
- print_lock(check_target);
+ print_lock(check_tgt);
printk("\nwhich lock already depends on the new lock.\n\n");
printk("\nthe existing dependency chain (in reverse order) is:\n");
@@ -1043,36 +1040,24 @@ static inline int class_equal(struct lock_list *entry, void *data)
return entry->class == data;
}
-static noinline int print_circular_bug(void)
+static noinline int print_circular_bug(struct lock_list *this,
+ struct lock_list *target,
+ struct held_lock *check_src,
+ struct held_lock *check_tgt)
{
struct task_struct *curr = current;
- struct lock_list this;
- struct lock_list *target;
struct lock_list *parent;
- int result;
unsigned long depth;
if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
- this.class = hlock_class(check_source);
- this.parent = NULL;
- if (!save_trace(&this.trace))
+ if (!save_trace(&this->trace))
return 0;
- result = __bfs_forward(&this,
- hlock_class(check_target),
- class_equal,
- &target);
- if (result) {
- printk("\n%s:search shortest path failed:%d\n", __func__,
- result);
- return 0;
- }
-
depth = get_lock_depth(target);
- print_circular_bug_header(target, depth);
+ print_circular_bug_header(target, depth, check_src, check_tgt);
parent = get_lock_parent(target);
@@ -1090,6 +1075,16 @@ static noinline int print_circular_bug(void)
return 0;
}
+static noinline int print_bfs_bug(int ret)
+{
+ if (!debug_locks_off_graph_unlock())
+ return 0;
+
+ WARN(1, "lockdep bfs error:%d\n", ret);
+
+ return 0;
+}
+
#define RECURSION_LIMIT 40
static int noinline print_infinite_recursion_bug(void)
@@ -1168,31 +1163,17 @@ unsigned long lockdep_count_backward_deps(struct lock_class *class)
* lead to <target>. Print an error and return 0 if it does.
*/
static noinline int
-check_noncircular(struct lock_class *source, unsigned int depth)
+check_noncircular(struct lock_list *root, struct lock_class *target,
+ struct lock_list **target_entry)
{
- struct lock_list *entry;
+ int result;
- if (lockdep_dependency_visit(source, depth))
- return 1;
+ debug_atomic_inc(&nr_cyclic_checks);
- debug_atomic_inc(&nr_cyclic_check_recursions);
- if (depth > max_recursion_depth)
- max_recursion_depth = depth;
- if (depth >= RECURSION_LIMIT)
- return print_infinite_recursion_bug();
- /*
- * Check this lock's dependency list:
- */
- list_for_each_entry(entry, &source->locks_after, entry) {
- if (entry->class == hlock_class(check_target))
- return 2;
- debug_atomic_inc(&nr_cyclic_checks);
- if (check_noncircular(entry->class, depth+1) == 2)
- return 2;
- }
- return 1;
-}
+ result = __bfs_forward(root, target, class_equal, target_entry);
+ return result;
+}
#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING)
/*
@@ -1586,6 +1567,8 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
{
struct lock_list *entry;
int ret;
+ struct lock_list this;
+ struct lock_list *uninitialized_var(target_entry);
/*
* Prove that the new <prev> -> <next> dependency would not
@@ -1596,11 +1579,13 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
* We are using global variables to control the recursion, to
* keep the stackframe size of the recursive functions low:
*/
- check_source = next;
- check_target = prev;
-
- if (check_noncircular(hlock_class(next), 0) == 2)
- return print_circular_bug();
+ this.class = hlock_class(next);
+ this.parent = NULL;
+ ret = check_noncircular(&this, hlock_class(prev), &target_entry);
+ if (unlikely(!ret))
+ return print_circular_bug(&this, target_entry, next, prev);
+ else if (unlikely(ret < 0))
+ return print_bfs_bug(ret);
if (!check_prev_add_irq(curr, prev, next))
return 0;
next prev parent reply other threads:[~2009-08-02 13:02 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-28 15:04 [RESEND PATCH 0/11] kernel:lockdep:replace DFS with BFS tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 01/11] kernel:lockdep:print the shortest dependency chain if finding a circle tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 02/11] kernel:lockdep:improve implementation of BFS tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 03/11] kernel:lockdep: introduce match function to BFS tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 04/11] kernel:lockdep:implement check_noncircular() by BFS tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 05/11] kernel:lockdep:implement find_usage_*wards " tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 06/11] kernel:lockdep:introduce print_shortest_lock_dependencies tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 07/11] kernel:lockdep: implement lockdep_count_*ward_deps by BFS tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 08/11] kernel:lockdep: update memory usage introduced " tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 09/11] kernel:lockdep:add statistics info for max bfs queue depth tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 10/11] BFS cleanup tom.leiming
2009-06-28 15:04 ` [RESEND PATCH 11/11] kernel:lockdep:fix return value of check_usage*() tom.leiming
2009-07-18 14:24 ` [tip:core/locking] lockdep: BFS cleanup tip-bot for Peter Zijlstra
2009-07-18 17:23 ` Peter Zijlstra
2009-08-02 13:03 ` tip-bot for Peter Zijlstra
2009-07-18 14:24 ` [tip:core/locking] lockdep: Add statistics info for max bfs queue depth tip-bot for Ming Lei
2009-08-02 13:03 ` tip-bot for Ming Lei
2009-07-18 14:24 ` [tip:core/locking] lockdep: Update memory usage introduced by BFS tip-bot for Ming Lei
2009-07-18 17:23 ` Peter Zijlstra
2009-08-02 13:02 ` tip-bot for Ming Lei
2009-07-18 14:24 ` [tip:core/locking] lockdep: Implement lockdep_count_*ward_deps " tip-bot for Ming Lei
2009-08-02 13:02 ` tip-bot for Ming Lei
2009-07-18 14:24 ` [tip:core/locking] lockdep: Introduce print_shortest_lock_dependencies tip-bot for Ming Lei
2009-08-02 13:02 ` tip-bot for Ming Lei
2009-07-18 14:23 ` [tip:core/locking] lockdep: Implement find_usage_*wards by BFS tip-bot for Ming Lei
2009-08-02 13:02 ` tip-bot for Ming Lei
2009-07-13 8:02 ` [RESEND PATCH 04/11] kernel:lockdep:implement check_noncircular() " Dave Young
2009-07-13 8:08 ` Dave Young
2009-07-21 3:33 ` Ming Lei
2009-07-18 14:23 ` [tip:core/locking] lockdep: Implement " tip-bot for Ming Lei
2009-08-02 13:02 ` tip-bot for Ming Lei [this message]
2009-07-18 14:23 ` [tip:core/locking] lockdep: Introduce match function to BFS tip-bot for Ming Lei
2009-08-02 13:01 ` tip-bot for Ming Lei
2009-07-18 14:23 ` [tip:core/locking] lockdep: Improve implementation of BFS tip-bot for Ming Lei
2009-08-02 13:01 ` tip-bot for Ming Lei
2009-07-11 21:30 ` [RESEND PATCH 01/11] kernel:lockdep:print the shortest dependency chain if finding a circle Frederic Weisbecker
2009-07-12 2:42 ` Ming Lei
2009-07-13 7:01 ` Ingo Molnar
2009-07-13 9:14 ` Peter Zijlstra
2009-07-13 13:56 ` Ming Lei
2009-07-13 13:51 ` Ming Lei
2009-07-13 9:01 ` Dave Young
2009-07-18 14:23 ` [tip:core/locking] lockdep: Print " tip-bot for Ming Lei
2009-08-02 13:01 ` tip-bot for Ming Lei
2009-07-11 0:43 ` [RESEND PATCH 0/11] kernel:lockdep:replace DFS with BFS Frederic Weisbecker
2009-07-11 3:25 ` Ming Lei
2009-07-11 21:09 ` Frederic Weisbecker
2009-07-12 2:29 ` Ming Lei
2009-07-13 7:02 ` Ingo Molnar
2009-07-13 9:16 ` Peter Zijlstra
2009-07-16 4:39 ` Ming Lei
2009-07-16 5:22 ` Peter Zijlstra
2009-07-16 7:12 ` Ming Lei
2009-07-16 9:54 ` Peter Zijlstra
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=tip-db0002a32f31060ca900b533d93a074ddf7d5b61@git.kernel.org \
--to=tom.leiming@gmail.com \
--cc=a.p.zijlstra@chello.nl \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=mingo@redhat.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.