Merge branches 'acpi-apei', 'acpi-misc' and 'acpi-processor'
[linux-2.6-microblaze.git] / kernel / locking / lockdep.c
index b71ad8d..c1418b4 100644 (file)
@@ -108,19 +108,21 @@ static inline void lockdep_lock(void)
 {
        DEBUG_LOCKS_WARN_ON(!irqs_disabled());
 
+       __this_cpu_inc(lockdep_recursion);
        arch_spin_lock(&__lock);
        __owner = current;
-       __this_cpu_inc(lockdep_recursion);
 }
 
 static inline void lockdep_unlock(void)
 {
+       DEBUG_LOCKS_WARN_ON(!irqs_disabled());
+
        if (debug_locks && DEBUG_LOCKS_WARN_ON(__owner != current))
                return;
 
-       __this_cpu_dec(lockdep_recursion);
        __owner = NULL;
        arch_spin_unlock(&__lock);
+       __this_cpu_dec(lockdep_recursion);
 }
 
 static inline bool lockdep_assert_locked(void)
@@ -2765,7 +2767,9 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
  * (Note that this has to be done separately, because the graph cannot
  * detect such classes of deadlocks.)
  *
- * Returns: 0 on deadlock detected, 1 on OK, 2 on recursive read
+ * Returns: 0 on deadlock detected, 1 on OK, 2 if another lock with the same
+ * lock class is held but nest_lock is also held, i.e. we rely on the
+ * nest_lock to avoid the deadlock.
  */
 static int
 check_deadlock(struct task_struct *curr, struct held_lock *next)
@@ -2788,7 +2792,7 @@ check_deadlock(struct task_struct *curr, struct held_lock *next)
                 * lock class (i.e. read_lock(lock)+read_lock(lock)):
                 */
                if ((next->read == 2) && prev->read)
-                       return 2;
+                       continue;
 
                /*
                 * We're holding the nest_lock, which serializes this lock's
@@ -3592,16 +3596,13 @@ static int validate_chain(struct task_struct *curr,
 
                if (!ret)
                        return 0;
-               /*
-                * Mark recursive read, as we jump over it when
-                * building dependencies (just like we jump over
-                * trylock entries):
-                */
-               if (ret == 2)
-                       hlock->read = 2;
                /*
                 * Add dependency only if this lock is not the head
-                * of the chain, and if it's not a secondary read-lock:
+                * of the chain, and if the new lock introduces no more
+                * lock dependency (because we already hold a lock with the
+                * same lock class) nor deadlock (because the nest_lock
+                * serializes nesting locks), see the comments for
+                * check_deadlock().
                 */
                if (!chain_head && ret != 2) {
                        if (!check_prevs_add(curr, hlock))