From: tom.leiming@gmail.com
To: a.p.zijlstra@chello.nl
Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
mingo@elte.hu, Ming Lei <tom.leiming@gmail.com>
Subject: [RESEND PATCH 10/11] BFS cleanup
Date: Sun, 28 Jun 2009 23:04:45 +0800 [thread overview]
Message-ID: <1246201486-7308-11-git-send-email-tom.leiming@gmail.com> (raw)
In-Reply-To: <1246201486-7308-10-git-send-email-tom.leiming@gmail.com>
From: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/lockdep.h | 7 +-
kernel/lockdep.c | 232 +++++++++++++++++++++++++++-----------------
kernel/lockdep_internals.h | 97 +------------------
3 files changed, 147 insertions(+), 189 deletions(-)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 9ec026f..12aabfc 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -58,7 +58,6 @@ struct lock_class {
struct lockdep_subclass_key *key;
unsigned int subclass;
- unsigned int dep_gen_id;
/*
* IRQ/softirq usage tracking bits:
@@ -150,9 +149,9 @@ struct lock_list {
struct stack_trace trace;
int distance;
- /*The parent field is used to implement breadth-first search,and
- *the bit 0 is reused to indicate if the lock has been accessed
- *in BFS.
+ /*
+ * The parent field is used to implement breadth-first search, and the
+ * bit 0 is reused to indicate if the lock has been accessed in BFS.
*/
struct lock_list *parent;
};
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index b20f08b..09a141f 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -43,6 +43,7 @@
#include <linux/ftrace.h>
#include <linux/stringify.h>
#include <linux/bitops.h>
+
#include <asm/sections.h>
#include "lockdep_internals.h"
@@ -118,7 +119,7 @@ static inline int debug_locks_off_graph_unlock(void)
static int lockdep_initialized;
unsigned long nr_list_entries;
-struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
/*
* All data structures here are protected by the global debug_lock.
@@ -390,19 +391,6 @@ unsigned int nr_process_chains;
unsigned int max_lockdep_depth;
unsigned int max_recursion_depth;
-static unsigned int lockdep_dependency_gen_id;
-
-static bool lockdep_dependency_visit(struct lock_class *source,
- unsigned int depth)
-{
- if (!depth)
- lockdep_dependency_gen_id++;
- if (source->dep_gen_id == lockdep_dependency_gen_id)
- return true;
- source->dep_gen_id = lockdep_dependency_gen_id;
- return false;
-}
-
#ifdef CONFIG_DEBUG_LOCKDEP
/*
* We cannot printk in early bootup code. Not even early_printk()
@@ -575,64 +563,6 @@ static void print_lock_class_header(struct lock_class *class, int depth)
print_ip_sym((unsigned long)class->key);
}
-/*
- * printk the shortest lock dependencies from @start to @end in reverse order:
- */
-static void __used
-print_shortest_lock_dependencies(struct lock_list *leaf,
- struct lock_list *root)
-{
- struct lock_list *entry = leaf;
- int depth;
-
- /*compute depth from generated tree by BFS*/
- depth = get_lock_depth(leaf);
-
- do {
- print_lock_class_header(entry->class, depth);
- printk("%*s ... acquired at:\n", depth, "");
- print_stack_trace(&entry->trace, 2);
- printk("\n");
-
- if (depth == 0 && (entry != root)) {
- printk("lockdep:%s bad BFS generated tree\n", __func__);
- break;
- }
-
- entry = get_lock_parent(entry);
- depth--;
- } while (entry && (depth >= 0));
-
- return;
-}
-/*
- * printk all lock dependencies starting at <entry>:
- */
-static void __used
-print_lock_dependencies(struct lock_class *class, int depth)
-{
- struct lock_list *entry;
-
- if (lockdep_dependency_visit(class, depth))
- return;
-
- if (DEBUG_LOCKS_WARN_ON(depth >= 20))
- return;
-
- print_lock_class_header(class, depth);
-
- list_for_each_entry(entry, &class->locks_after, entry) {
- if (DEBUG_LOCKS_WARN_ON(!entry->class))
- return;
-
- print_lock_dependencies(entry->class, depth + 1);
-
- printk("%*s ... acquired at:\n",depth,"");
- print_stack_trace(&entry->trace, 2);
- printk("\n");
- }
-}
-
static void print_kernel_version(void)
{
printk("%s %.*s\n", init_utsname()->release,
@@ -927,14 +857,106 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
return 1;
}
-unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
-static struct circular_queue lock_cq;
+/*For good efficiency of modular, we use power of 2*/
+#define MAX_CIRCULAR_QUEUE_SIZE 4096UL
+#define CQ_MASK (MAX_CIRCULAR_QUEUE_SIZE-1)
+
+/* The circular_queue and helpers is used to implement the
+ * breadth-first search(BFS)algorithem, by which we can build
+ * the shortest path from the next lock to be acquired to the
+ * previous held lock if there is a circular between them.
+ * */
+struct circular_queue {
+ unsigned long element[MAX_CIRCULAR_QUEUE_SIZE];
+ unsigned int front, rear;
+};
+
+static struct circular_queue lock_cq;
+static unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
+
unsigned int max_bfs_queue_depth;
+
+static inline void __cq_init(struct circular_queue *cq)
+{
+ cq->front = cq->rear = 0;
+ bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
+}
+
+static inline int __cq_empty(struct circular_queue *cq)
+{
+ return (cq->front == cq->rear);
+}
+
+static inline int __cq_full(struct circular_queue *cq)
+{
+ return ((cq->rear + 1) & CQ_MASK) == cq->front;
+}
+
+static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
+{
+ if (__cq_full(cq))
+ return -1;
+
+ cq->element[cq->rear] = elem;
+ cq->rear = (cq->rear + 1) & CQ_MASK;
+ return 0;
+}
+
+static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
+{
+ if (__cq_empty(cq))
+ return -1;
+
+ *elem = cq->element[cq->front];
+ cq->front = (cq->front + 1) & CQ_MASK;
+ return 0;
+}
+
+static inline unsigned int __cq_get_elem_count(struct circular_queue *cq)
+{
+ return (cq->rear - cq->front) & CQ_MASK;
+}
+
+static inline void mark_lock_accessed(struct lock_list *lock,
+ struct lock_list *parent)
+{
+ unsigned long nr;
+ nr = lock - list_entries;
+ WARN_ON(nr >= nr_list_entries);
+ lock->parent = parent;
+ set_bit(nr, bfs_accessed);
+}
+
+static inline unsigned long lock_accessed(struct lock_list *lock)
+{
+ unsigned long nr;
+ nr = lock - list_entries;
+ WARN_ON(nr >= nr_list_entries);
+ return test_bit(nr, bfs_accessed);
+}
+
+static inline struct lock_list *get_lock_parent(struct lock_list *child)
+{
+ return child->parent;
+}
+
+static inline int get_lock_depth(struct lock_list *child)
+{
+ int depth = 0;
+ struct lock_list *parent;
+
+ while ((parent = get_lock_parent(child))) {
+ child = parent;
+ depth++;
+ }
+ return depth;
+}
+
static int __bfs(struct lock_list *source_entry,
- void *data,
- int (*match)(struct lock_list *entry, void *data),
- struct lock_list **target_entry,
- int forward)
+ void *data,
+ int (*match)(struct lock_list *entry, void *data),
+ struct lock_list **target_entry,
+ int forward)
{
struct lock_list *entry;
struct list_head *head;
@@ -1202,14 +1224,6 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
* without creating any illegal irq-safe -> irq-unsafe lock dependency.
*/
-
-#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);
@@ -1236,6 +1250,8 @@ find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
debug_atomic_inc(&nr_find_usage_forwards_checks);
result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
+ if (result < 0)
+ return print_bfs_bug(result);
return result;
}
@@ -1259,10 +1275,42 @@ find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
debug_atomic_inc(&nr_find_usage_backwards_checks);
result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
+ if (result < 0)
+ return print_bfs_bug(result);
return result;
}
+/*
+ * printk the shortest lock dependencies from @start to @end in reverse order:
+ */
+static void __used
+print_shortest_lock_dependencies(struct lock_list *leaf,
+ struct lock_list *root)
+{
+ struct lock_list *entry = leaf;
+ int depth;
+
+ /*compute depth from generated tree by BFS*/
+ depth = get_lock_depth(leaf);
+
+ do {
+ print_lock_class_header(entry->class, depth);
+ printk("%*s ... acquired at:\n", depth, "");
+ print_stack_trace(&entry->trace, 2);
+ printk("\n");
+
+ if (depth == 0 && (entry != root)) {
+ printk("lockdep:%s bad BFS generated tree\n", __func__);
+ break;
+ }
+
+ entry = get_lock_parent(entry);
+ depth--;
+ } while (entry && (depth >= 0));
+
+ return;
+}
static int
print_bad_irq_dependency(struct task_struct *curr,
@@ -1349,12 +1397,14 @@ check_usage(struct task_struct *curr, struct held_lock *prev,
this.class = hlock_class(prev);
ret = find_usage_backwards(&this, bit_backwards, &target_entry);
- BFS_PROCESS_RET(ret);
+ if (!ret || ret == 1)
+ return ret;
that.parent = NULL;
that.class = hlock_class(next);
ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
- BFS_PROCESS_RET(ret);
+ if (!ret || ret == 1)
+ return ret;
return print_bad_irq_dependency(curr, &this, &that,
target_entry, target_entry1,
@@ -2038,7 +2088,8 @@ check_usage_forwards(struct task_struct *curr, struct held_lock *this,
root.parent = NULL;
root.class = hlock_class(this);
ret = find_usage_forwards(&root, bit, &target_entry);
- BFS_PROCESS_RET(ret);
+ if (!ret || ret == 1)
+ return ret;
return print_irq_inversion_bug(curr, &root, target_entry,
this, 1, irqclass);
@@ -2059,7 +2110,8 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
root.parent = NULL;
root.class = hlock_class(this);
ret = find_usage_backwards(&root, bit, &target_entry);
- BFS_PROCESS_RET(ret);
+ if (!ret || ret == 1)
+ return ret;
return print_irq_inversion_bug(curr, &root, target_entry,
this, 1, irqclass);
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index 6baa880..a2ee95a 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -91,6 +91,8 @@ extern unsigned int nr_process_chains;
extern unsigned int max_lockdep_depth;
extern unsigned int max_recursion_depth;
+extern unsigned int max_bfs_queue_depth;
+
#ifdef CONFIG_PROVE_LOCKING
extern unsigned long lockdep_count_forward_deps(struct lock_class *);
extern unsigned long lockdep_count_backward_deps(struct lock_class *);
@@ -136,98 +138,3 @@ extern atomic_t nr_find_usage_backwards_recursions;
# define debug_atomic_dec(ptr) do { } while (0)
# define debug_atomic_read(ptr) 0
#endif
-
-
-extern unsigned int max_bfs_queue_depth;
-extern unsigned long nr_list_entries;
-extern struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
-extern unsigned long bfs_accessed[];
-
-/*For good efficiency of modular, we use power of 2*/
-#define MAX_CIRCULAR_QUE_SIZE 4096UL
-
-/* The circular_queue and helpers is used to implement the
- * breadth-first search(BFS)algorithem, by which we can build
- * the shortest path from the next lock to be acquired to the
- * previous held lock if there is a circular between them.
- * */
-struct circular_queue{
- unsigned long element[MAX_CIRCULAR_QUE_SIZE];
- unsigned int front, rear;
-};
-
-static inline void __cq_init(struct circular_queue *cq)
-{
- cq->front = cq->rear = 0;
- bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
-}
-
-static inline int __cq_empty(struct circular_queue *cq)
-{
- return (cq->front == cq->rear);
-}
-
-static inline int __cq_full(struct circular_queue *cq)
-{
- return ((cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1)) == cq->front;
-}
-
-static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
-{
- if (__cq_full(cq))
- return -1;
-
- cq->element[cq->rear] = elem;
- cq->rear = (cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
- return 0;
-}
-
-static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
-{
- if (__cq_empty(cq))
- return -1;
-
- *elem = cq->element[cq->front];
- cq->front = (cq->front + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
- return 0;
-}
-
-static inline unsigned int __cq_get_elem_count(struct circular_queue *cq)
-{
- return (cq->rear - cq->front)&(MAX_CIRCULAR_QUE_SIZE-1);
-}
-
-static inline void mark_lock_accessed(struct lock_list *lock,
- struct lock_list *parent)
-{
- unsigned long nr;
- nr = lock - list_entries;
- WARN_ON(nr >= nr_list_entries);
- lock->parent = parent;
- set_bit(nr, bfs_accessed);
-}
-
-static inline unsigned long lock_accessed(struct lock_list *lock)
-{
- unsigned long nr;
- nr = lock - list_entries;
- WARN_ON(nr >= nr_list_entries);
- return test_bit(nr, bfs_accessed);
-}
-
-static inline struct lock_list *get_lock_parent(struct lock_list *child)
-{
- return child->parent;
-}
-
-static inline int get_lock_depth(struct lock_list *child)
-{
- int depth = 0;
- struct lock_list *parent;
-
- while ((parent = get_lock_parent(child))) {
- child = parent;
- depth++;
- }
- return depth;
-}
--
1.6.0.GIT
next prev parent reply other threads:[~2009-06-28 15:07 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 ` tom.leiming [this message]
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
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=1246201486-7308-11-git-send-email-tom.leiming@gmail.com \
--to=tom.leiming@gmail.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/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.