diff options
Diffstat (limited to 'kernel/printk.c')
-rw-r--r-- | kernel/printk.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 95b7fe17f124..bdba5d80496c 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/interrupt.h> /* For in_interrupt() */ | 28 | #include <linux/interrupt.h> /* For in_interrupt() */ |
29 | #include <linux/config.h> | ||
30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
31 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
32 | #include <linux/security.h> | 31 | #include <linux/security.h> |
@@ -519,7 +518,9 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
519 | zap_locks(); | 518 | zap_locks(); |
520 | 519 | ||
521 | /* 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 */ |
522 | spin_lock_irqsave(&logbuf_lock, flags); | 521 | local_irq_save(flags); |
522 | lockdep_off(); | ||
523 | spin_lock(&logbuf_lock); | ||
523 | printk_cpu = smp_processor_id(); | 524 | printk_cpu = smp_processor_id(); |
524 | 525 | ||
525 | /* Emit the output into the temporary buffer */ | 526 | /* Emit the output into the temporary buffer */ |
@@ -589,7 +590,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
589 | */ | 590 | */ |
590 | console_locked = 1; | 591 | console_locked = 1; |
591 | printk_cpu = UINT_MAX; | 592 | printk_cpu = UINT_MAX; |
592 | spin_unlock_irqrestore(&logbuf_lock, flags); | 593 | spin_unlock(&logbuf_lock); |
593 | 594 | ||
594 | /* | 595 | /* |
595 | * Console drivers may assume that per-cpu resources have | 596 | * Console drivers may assume that per-cpu resources have |
@@ -605,6 +606,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
605 | console_locked = 0; | 606 | console_locked = 0; |
606 | up(&console_sem); | 607 | up(&console_sem); |
607 | } | 608 | } |
609 | lockdep_on(); | ||
610 | local_irq_restore(flags); | ||
608 | } else { | 611 | } else { |
609 | /* | 612 | /* |
610 | * Someone else owns the drivers. We drop the spinlock, which | 613 | * Someone else owns the drivers. We drop the spinlock, which |
@@ -612,7 +615,9 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
612 | * console drivers with the output which we just produced. | 615 | * console drivers with the output which we just produced. |
613 | */ | 616 | */ |
614 | printk_cpu = UINT_MAX; | 617 | printk_cpu = UINT_MAX; |
615 | spin_unlock_irqrestore(&logbuf_lock, flags); | 618 | spin_unlock(&logbuf_lock); |
619 | lockdep_on(); | ||
620 | local_irq_restore(flags); | ||
616 | } | 621 | } |
617 | 622 | ||
618 | preempt_enable(); | 623 | preempt_enable(); |
@@ -810,8 +815,15 @@ void release_console_sem(void) | |||
810 | console_may_schedule = 0; | 815 | console_may_schedule = 0; |
811 | up(&console_sem); | 816 | up(&console_sem); |
812 | spin_unlock_irqrestore(&logbuf_lock, flags); | 817 | spin_unlock_irqrestore(&logbuf_lock, flags); |
813 | if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) | 818 | if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) { |
814 | 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 | } | ||
815 | } | 827 | } |
816 | EXPORT_SYMBOL(release_console_sem); | 828 | EXPORT_SYMBOL(release_console_sem); |
817 | 829 | ||