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 find_usage_*wards by BFS
Date: Sat, 18 Jul 2009 14:23:49 GMT [thread overview]
Message-ID: <tip-013f1606270e97dc7952f19a7c0eaeebcbfcf048@git.kernel.org> (raw)
In-Reply-To: <1246201486-7308-6-git-send-email-tom.leiming@gmail.com>
Commit-ID: 013f1606270e97dc7952f19a7c0eaeebcbfcf048
Gitweb: http://git.kernel.org/tip/013f1606270e97dc7952f19a7c0eaeebcbfcf048
Author: Ming Lei <tom.leiming@gmail.com>
AuthorDate: Thu, 16 Jul 2009 15:44:29 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Sat, 18 Jul 2009 16:02:54 +0200
lockdep: Implement find_usage_*wards by BFS
This patch uses BFS to implement find_usage_*wards(),which
was originally writen by DFS.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1246201486-7308-6-git-send-email-tom.leiming@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/lockdep.c | 180 ++++++++++++++++++++++--------------------------------
1 files changed, 72 insertions(+), 108 deletions(-)
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 5609d30..b3ade50 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -963,7 +963,7 @@ exit:
return ret;
}
-static inline int __bfs_forward(struct lock_list *src_entry,
+static inline int __bfs_forwards(struct lock_list *src_entry,
void *data,
int (*match)(struct lock_list *entry, void *data),
struct lock_list **target_entry)
@@ -972,7 +972,7 @@ static inline int __bfs_forward(struct lock_list *src_entry,
}
-static inline int __bfs_backward(struct lock_list *src_entry,
+static inline int __bfs_backwards(struct lock_list *src_entry,
void *data,
int (*match)(struct lock_list *entry, void *data),
struct lock_list **target_entry)
@@ -1085,18 +1085,6 @@ static noinline int print_bfs_bug(int ret)
return 0;
}
-#define RECURSION_LIMIT 40
-
-static int noinline print_infinite_recursion_bug(void)
-{
- if (!debug_locks_off_graph_unlock())
- return 0;
-
- WARN_ON(1);
-
- return 0;
-}
-
unsigned long __lockdep_count_forward_deps(struct lock_class *class,
unsigned int depth)
{
@@ -1170,7 +1158,7 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
debug_atomic_inc(&nr_cyclic_checks);
- result = __bfs_forward(root, target, class_equal, target_entry);
+ result = __bfs_forwards(root, target, class_equal, target_entry);
return result;
}
@@ -1181,101 +1169,70 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
* proving that two subgraphs can be connected by a new dependency
* without creating any illegal irq-safe -> irq-unsafe lock dependency.
*/
-static enum lock_usage_bit find_usage_bit;
static struct lock_class *forwards_match, *backwards_match;
+
+#define BFS_PROCESS_RET(ret) do { \
+ if (ret < 0) \
+ return print_bfs_bug(ret); \
+ if (ret == 1) \
+ return 1; \
+ } while (0)
+
+static inline int usage_match(struct lock_list *entry, void *bit)
+{
+ return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
+}
+
+
+
/*
* Find a node in the forwards-direction dependency sub-graph starting
- * at <source> that matches <find_usage_bit>.
+ * at @root->class that matches @bit.
*
- * Return 2 if such a node exists in the subgraph, and put that node
- * into <forwards_match>.
+ * Return 0 if such a node exists in the subgraph, and put that node
+ * into *@target_entry.
*
- * Return 1 otherwise and keep <forwards_match> unchanged.
- * Return 0 on error.
+ * Return 1 otherwise and keep *@target_entry unchanged.
+ * Return <0 on error.
*/
-static noinline int
-find_usage_forwards(struct lock_class *source, unsigned int depth)
+static int
+find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
+ struct lock_list **target_entry)
{
- struct lock_list *entry;
- int ret;
-
- if (lockdep_dependency_visit(source, depth))
- return 1;
-
- if (depth > max_recursion_depth)
- max_recursion_depth = depth;
- if (depth >= RECURSION_LIMIT)
- return print_infinite_recursion_bug();
+ int result;
debug_atomic_inc(&nr_find_usage_forwards_checks);
- if (source->usage_mask & (1 << find_usage_bit)) {
- forwards_match = source;
- return 2;
- }
- /*
- * Check this lock's dependency list:
- */
- list_for_each_entry(entry, &source->locks_after, entry) {
- debug_atomic_inc(&nr_find_usage_forwards_recursions);
- ret = find_usage_forwards(entry->class, depth+1);
- if (ret == 2 || ret == 0)
- return ret;
- }
- return 1;
+ result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
+
+ return result;
}
/*
* Find a node in the backwards-direction dependency sub-graph starting
- * at <source> that matches <find_usage_bit>.
+ * at @root->class that matches @bit.
*
- * Return 2 if such a node exists in the subgraph, and put that node
- * into <backwards_match>.
+ * Return 0 if such a node exists in the subgraph, and put that node
+ * into *@target_entry.
*
- * Return 1 otherwise and keep <backwards_match> unchanged.
- * Return 0 on error.
+ * Return 1 otherwise and keep *@target_entry unchanged.
+ * Return <0 on error.
*/
-static noinline int
-find_usage_backwards(struct lock_class *source, unsigned int depth)
+static int
+find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
+ struct lock_list **target_entry)
{
- struct lock_list *entry;
- int ret;
-
- if (lockdep_dependency_visit(source, depth))
- return 1;
-
- if (!__raw_spin_is_locked(&lockdep_lock))
- return DEBUG_LOCKS_WARN_ON(1);
-
- if (depth > max_recursion_depth)
- max_recursion_depth = depth;
- if (depth >= RECURSION_LIMIT)
- return print_infinite_recursion_bug();
+ int result;
debug_atomic_inc(&nr_find_usage_backwards_checks);
- if (source->usage_mask & (1 << find_usage_bit)) {
- backwards_match = source;
- return 2;
- }
- if (!source && debug_locks_off_graph_unlock()) {
- WARN_ON(1);
- return 0;
- }
+ result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
- /*
- * Check this lock's dependency list:
- */
- list_for_each_entry(entry, &source->locks_before, entry) {
- debug_atomic_inc(&nr_find_usage_backwards_recursions);
- ret = find_usage_backwards(entry->class, depth+1);
- if (ret == 2 || ret == 0)
- return ret;
- }
- return 1;
+ return result;
}
+
static int
print_bad_irq_dependency(struct task_struct *curr,
struct held_lock *prev,
@@ -1343,18 +1300,21 @@ check_usage(struct task_struct *curr, struct held_lock *prev,
enum lock_usage_bit bit_forwards, const char *irqclass)
{
int ret;
+ struct lock_list this;
+ struct lock_list *uninitialized_var(target_entry);
+
+ this.parent = NULL;
+
+ this.class = hlock_class(prev);
+ ret = find_usage_backwards(&this, bit_backwards, &target_entry);
+ BFS_PROCESS_RET(ret);
+ backwards_match = target_entry->class;
+
+ this.class = hlock_class(next);
+ ret = find_usage_forwards(&this, bit_forwards, &target_entry);
+ BFS_PROCESS_RET(ret);
+ forwards_match = target_entry->class;
- find_usage_bit = bit_backwards;
- /* fills in <backwards_match> */
- ret = find_usage_backwards(hlock_class(prev), 0);
- if (!ret || ret == 1)
- return ret;
-
- find_usage_bit = bit_forwards;
- ret = find_usage_forwards(hlock_class(next), 0);
- if (!ret || ret == 1)
- return ret;
- /* ret == 2 */
return print_bad_irq_dependency(curr, prev, next,
bit_backwards, bit_forwards, irqclass);
}
@@ -2029,14 +1989,16 @@ check_usage_forwards(struct task_struct *curr, struct held_lock *this,
enum lock_usage_bit bit, const char *irqclass)
{
int ret;
+ struct lock_list root;
+ struct lock_list *uninitialized_var(target_entry);
- find_usage_bit = bit;
- /* fills in <forwards_match> */
- ret = find_usage_forwards(hlock_class(this), 0);
- if (!ret || ret == 1)
- return ret;
+ root.parent = NULL;
+ root.class = hlock_class(this);
+ ret = find_usage_forwards(&root, bit, &target_entry);
+ BFS_PROCESS_RET(ret);
- return print_irq_inversion_bug(curr, forwards_match, this, 1, irqclass);
+ return print_irq_inversion_bug(curr, target_entry->class,
+ this, 1, irqclass);
}
/*
@@ -2048,14 +2010,16 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
enum lock_usage_bit bit, const char *irqclass)
{
int ret;
+ struct lock_list root;
+ struct lock_list *uninitialized_var(target_entry);
- find_usage_bit = bit;
- /* fills in <backwards_match> */
- ret = find_usage_backwards(hlock_class(this), 0);
- if (!ret || ret == 1)
- return ret;
+ root.parent = NULL;
+ root.class = hlock_class(this);
+ ret = find_usage_backwards(&root, bit, &target_entry);
+ BFS_PROCESS_RET(ret);
- return print_irq_inversion_bug(curr, backwards_match, this, 0, irqclass);
+ return print_irq_inversion_bug(curr, target_entry->class,
+ this, 1, irqclass);
}
void print_irqtrace_events(struct task_struct *curr)
next prev parent reply other threads:[~2009-07-18 14:24 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-bot for Ming Lei [this message]
2009-08-02 13:02 ` [tip:core/locking] lockdep: Implement find_usage_*wards by BFS 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
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-013f1606270e97dc7952f19a7c0eaeebcbfcf048@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.