Merge branch 'core-printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2011 23:43:49 +0000 (16:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2011 23:43:49 +0000 (16:43 -0700)
* 'core-printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  lockdep: Fix trace_[soft,hard]irqs_[on,off]() recursion
  printk: Fix console_sem vs logbuf_lock unlock race
  printk: Release console_sem after logbuf_lock

1  2 
kernel/lockdep.c

diff --combined kernel/lockdep.c
index 628276d05915e7967fd8109e9bc0bab1391fc54b,81968a065b4cc61c0674e20848b5b2e7843f852e..3956f5149e25c2664876c081d8befc9814c1be4e
@@@ -2468,9 -2468,6 +2468,9 @@@ mark_held_locks(struct task_struct *cur
  
                BUG_ON(usage_bit >= LOCK_USAGE_STATES);
  
 +              if (hlock_class(hlock)->key == &__lockdep_no_validate__)
 +                      continue;
 +
                if (!mark_lock(curr, hlock, usage_bit))
                        return 0;
        }
  /*
   * Hardirqs will be enabled:
   */
void trace_hardirqs_on_caller(unsigned long ip)
static void __trace_hardirqs_on_caller(unsigned long ip)
  {
        struct task_struct *curr = current;
  
-       time_hardirqs_on(CALLER_ADDR0, ip);
-       if (unlikely(!debug_locks || current->lockdep_recursion))
-               return;
        if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled)))
                return;
  
        /* we'll do an OFF -> ON transition: */
        curr->hardirqs_enabled = 1;
  
-       if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
-               return;
        if (DEBUG_LOCKS_WARN_ON(current->hardirq_context))
                return;
        /*
        curr->hardirq_enable_event = ++curr->irq_events;
        debug_atomic_inc(hardirqs_on_events);
  }
+ void trace_hardirqs_on_caller(unsigned long ip)
+ {
+       time_hardirqs_on(CALLER_ADDR0, ip);
+       if (unlikely(!debug_locks || current->lockdep_recursion))
+               return;
+       if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+               return;
+       current->lockdep_recursion = 1;
+       __trace_hardirqs_on_caller(ip);
+       current->lockdep_recursion = 0;
+ }
  EXPORT_SYMBOL(trace_hardirqs_on_caller);
  
  void trace_hardirqs_on(void)
@@@ -2577,7 -2582,7 +2585,7 @@@ void trace_softirqs_on(unsigned long ip
  {
        struct task_struct *curr = current;
  
-       if (unlikely(!debug_locks))
+       if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
  
        if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
                return;
        }
  
+       current->lockdep_recursion = 1;
        /*
         * We'll do an OFF -> ON transition:
         */
         */
        if (curr->hardirqs_enabled)
                mark_held_locks(curr, SOFTIRQ);
+       current->lockdep_recursion = 0;
  }
  
  /*
@@@ -2611,7 -2618,7 +2621,7 @@@ void trace_softirqs_off(unsigned long i
  {
        struct task_struct *curr = current;
  
-       if (unlikely(!debug_locks))
+       if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
  
        if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
@@@ -3429,7 -3436,7 +3439,7 @@@ int lock_is_held(struct lockdep_map *lo
        int ret = 0;
  
        if (unlikely(current->lockdep_recursion))
 -              return ret;
 +              return 1; /* avoid false negative lockdep_assert_held() */
  
        raw_local_irq_save(flags);
        check_flags(flags);