[RFC/T PATCH 07/12] lockdep: non-recursive validation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a validation mode that diregards all recursive locking errors.
This is useful for locks like lock_page where there is a high degree
of nested locking.

Obviously it will not report a useful class of errors :-/

Signed-off-by: Peter Zijlstra <[email protected]>
---
 include/linux/lockdep.h |   15 ++++++++-------
 kernel/lockdep.c        |   15 ++++++++++++---
 2 files changed, 20 insertions(+), 10 deletions(-)

Index: linux-2.6/include/linux/lockdep.h
===================================================================
--- linux-2.6.orig/include/linux/lockdep.h
+++ linux-2.6/include/linux/lockdep.h
@@ -286,7 +286,8 @@ extern void lockdep_init_map(struct lock
  *
  *   0: disabled
  *   1: simple checks (freeing, held-at-exit-time, etc.)
- *   2: full validation
+ *   2: validation without recursion checks
+ *   3: full validation
  */
 extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 			 int trylock, int read, int check, unsigned long ip);
@@ -426,7 +427,7 @@ static inline void print_irqtrace_events
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # ifdef CONFIG_PROVE_LOCKING
-#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 3, i)
 # else
 #  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
 # endif
@@ -438,8 +439,8 @@ static inline void print_irqtrace_events
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # ifdef CONFIG_PROVE_LOCKING
-#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
-#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 2, i)
+#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 3, i)
+#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 3, i)
 # else
 #  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
 #  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 1, i)
@@ -453,7 +454,7 @@ static inline void print_irqtrace_events
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # ifdef CONFIG_PROVE_LOCKING
-#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 3, i)
 # else
 #  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
 # endif
@@ -465,8 +466,8 @@ static inline void print_irqtrace_events
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # ifdef CONFIG_PROVE_LOCKING
-#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
-#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 2, i)
+#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 3, i)
+#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 3, i)
 # else
 #  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
 #  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 1, i)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2176,7 +2176,7 @@ static int __lock_acquire(struct lockdep
 	struct task_struct *curr = current;
 	struct lock_class *class = NULL;
 	struct held_lock *hlock;
-	unsigned int depth, id;
+	unsigned int depth, id, first;
 	int chain_head = 0;
 	u64 chain_key;
 
@@ -2225,6 +2225,14 @@ static int __lock_acquire(struct lockdep
 		return 0;
 
 	hlock = curr->held_locks + depth;
+	if (check == 2 && depth > 0) {
+		struct held_lock *prev_hlock = NULL;
+
+		prev_hlock = curr->held_locks + depth - 1;
+		if (prev_hlock->class == class)
+			first = 0;
+	} else
+		first = 1;
 
 	hlock->class = class;
 	hlock->acquire_ip = ip;
@@ -2238,7 +2246,7 @@ static int __lock_acquire(struct lockdep
 	hlock->holdtime_stamp = sched_clock();
 #endif
 
-	if (check != 2)
+	if (check < 2)
 		goto out_calc_hash;
 #ifdef CONFIG_TRACE_IRQFLAGS
 	/*
@@ -2347,7 +2355,8 @@ out_calc_hash:
 	 * graph_lock for us)
 	 */
 #ifdef CONFIG_PROVE_LOCKING
-	if (!trylock && (check == 2) && lookup_chain_cache(chain_key, class)) {
+	if (!trylock && (check >= 2 && first) &&
+			lookup_chain_cache(chain_key, class)) {
 		/*
 		 * Check whether last held lock:
 		 *

--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux