diff options
-rw-r--r-- | kernel/printk.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 39ae24d2a415..bdba5d80496c 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -518,7 +518,9 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
518 | zap_locks(); | 518 | zap_locks(); |
519 | 519 | ||
520 | /* This stops the holder of console_sem just where we want him */ | 520 | /* This stops the holder of console_sem just where we want him */ |
521 | spin_lock_irqsave(&logbuf_lock, flags); | 521 | local_irq_save(flags); |
522 | lockdep_off(); | ||
523 | spin_lock(&logbuf_lock); | ||
522 | printk_cpu = smp_processor_id(); | 524 | printk_cpu = smp_processor_id(); |
523 | 525 | ||
524 | /* Emit the output into the temporary buffer */ | 526 | /* Emit the output into the temporary buffer */ |
@@ -588,7 +590,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
588 | */ | 590 | */ |
589 | console_locked = 1; | 591 | console_locked = 1; |
590 | printk_cpu = UINT_MAX; | 592 | printk_cpu = UINT_MAX; |
591 | spin_unlock_irqrestore(&logbuf_lock, flags); | 593 | spin_unlock(&logbuf_lock); |
592 | 594 | ||
593 | /* | 595 | /* |
594 | * Console drivers may assume that per-cpu resources have | 596 | * Console drivers may assume that per-cpu resources have |
@@ -604,6 +606,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
604 | console_locked = 0; | 606 | console_locked = 0; |
605 | up(&console_sem); | 607 | up(&console_sem); |
606 | } | 608 | } |
609 | lockdep_on(); | ||
610 | local_irq_restore(flags); | ||
607 | } else { | 611 | } else { |
608 | /* | 612 | /* |
609 | * Someone else owns the drivers. We drop the spinlock, which | 613 | * Someone else owns the drivers. We drop the spinlock, which |
@@ -611,7 +615,9 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
611 | * console drivers with the output which we just produced. | 615 | * console drivers with the output which we just produced. |
612 | */ | 616 | */ |
613 | printk_cpu = UINT_MAX; | 617 | printk_cpu = UINT_MAX; |
614 | spin_unlock_irqrestore(&logbuf_lock, flags); | 618 | spin_unlock(&logbuf_lock); |
619 | lockdep_on(); | ||
620 | local_irq_restore(flags); | ||
615 | } | 621 | } |
616 | 622 | ||
617 | preempt_enable(); | 623 | preempt_enable(); |
@@ -809,8 +815,15 @@ void release_console_sem(void) | |||
809 | console_may_schedule = 0; | 815 | console_may_schedule = 0; |
810 | up(&console_sem); | 816 | up(&console_sem); |
811 | spin_unlock_irqrestore(&logbuf_lock, flags); | 817 | spin_unlock_irqrestore(&logbuf_lock, flags); |
812 | if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) | 818 | if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) { |
813 | wake_up_interruptible(&log_wait); | 819 | /* |
820 | * If we printk from within the lock dependency code, | ||
821 | * from within the scheduler code, then do not lock | ||
822 | * up due to self-recursion: | ||
823 | */ | ||
824 | if (!lockdep_internal()) | ||
825 | wake_up_interruptible(&log_wait); | ||
826 | } | ||
814 | } | 827 | } |
815 | EXPORT_SYMBOL(release_console_sem); | 828 | EXPORT_SYMBOL(release_console_sem); |
816 | 829 | ||