Merge branch 'nohz/printk-v8' into irq/core
[sfrench/cifs-2.6.git] / kernel / printk.c
index c9104feba5ece1b0a6edea7309ed0cdb6b7ab5ff..0b31715f335a7a8ba1a846fe3b93fe71d97cd8d7 100644 (file)
@@ -88,6 +88,12 @@ static DEFINE_SEMAPHORE(console_sem);
 struct console *console_drivers;
 EXPORT_SYMBOL_GPL(console_drivers);
 
+#ifdef CONFIG_LOCKDEP
+static struct lockdep_map console_lock_dep_map = {
+       .name = "console_lock"
+};
+#endif
+
 /*
  * This is used for debugging the mess that is the VT code by
  * keeping track if we have the console semaphore held. It's
@@ -742,6 +748,21 @@ void __init setup_log_buf(int early)
                free, (free * 100) / __LOG_BUF_LEN);
 }
 
+static bool __read_mostly ignore_loglevel;
+
+static int __init ignore_loglevel_setup(char *str)
+{
+       ignore_loglevel = 1;
+       printk(KERN_INFO "debug: ignoring loglevel setting.\n");
+
+       return 0;
+}
+
+early_param("ignore_loglevel", ignore_loglevel_setup);
+module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to"
+       "print all kernel messages to the console.");
+
 #ifdef CONFIG_BOOT_PRINTK_DELAY
 
 static int boot_delay; /* msecs delay after each printk during bootup */
@@ -765,13 +786,15 @@ static int __init boot_delay_setup(char *str)
 }
 __setup("boot_delay=", boot_delay_setup);
 
-static void boot_delay_msec(void)
+static void boot_delay_msec(int level)
 {
        unsigned long long k;
        unsigned long timeout;
 
-       if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
+       if ((boot_delay == 0 || system_state != SYSTEM_BOOTING)
+               || (level >= console_loglevel && !ignore_loglevel)) {
                return;
+       }
 
        k = (unsigned long long)loops_per_msec * boot_delay;
 
@@ -790,7 +813,7 @@ static void boot_delay_msec(void)
        }
 }
 #else
-static inline void boot_delay_msec(void)
+static inline void boot_delay_msec(int level)
 {
 }
 #endif
@@ -848,10 +871,11 @@ static size_t print_time(u64 ts, char *buf)
        if (!printk_time)
                return 0;
 
+       rem_nsec = do_div(ts, 1000000000);
+
        if (!buf)
-               return 15;
+               return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts);
 
-       rem_nsec = do_div(ts, 1000000000);
        return sprintf(buf, "[%5lu.%06lu] ",
                       (unsigned long)ts, rem_nsec / 1000);
 }
@@ -1233,21 +1257,6 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
        return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
 }
 
-static bool __read_mostly ignore_loglevel;
-
-static int __init ignore_loglevel_setup(char *str)
-{
-       ignore_loglevel = 1;
-       printk(KERN_INFO "debug: ignoring loglevel setting.\n");
-
-       return 0;
-}
-
-early_param("ignore_loglevel", ignore_loglevel_setup);
-module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to"
-       "print all kernel messages to the console.");
-
 /*
  * Call the console drivers, asking them to write out
  * log_buf[start] to log_buf[end - 1].
@@ -1493,7 +1502,7 @@ asmlinkage int vprintk_emit(int facility, int level,
        int this_cpu;
        int printed_len = 0;
 
-       boot_delay_msec();
+       boot_delay_msec(level);
        printk_delay();
 
        /* This stops the holder of console_sem just where we want him */
@@ -1909,12 +1918,14 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self,
  */
 void console_lock(void)
 {
-       BUG_ON(in_interrupt());
+       might_sleep();
+
        down(&console_sem);
        if (console_suspended)
                return;
        console_locked = 1;
        console_may_schedule = 1;
+       mutex_acquire(&console_lock_dep_map, 0, 0, _RET_IP_);
 }
 EXPORT_SYMBOL(console_lock);
 
@@ -1936,6 +1947,7 @@ int console_trylock(void)
        }
        console_locked = 1;
        console_may_schedule = 0;
+       mutex_acquire(&console_lock_dep_map, 0, 1, _RET_IP_);
        return 1;
 }
 EXPORT_SYMBOL(console_trylock);
@@ -2098,6 +2110,7 @@ skip:
                local_irq_restore(flags);
        }
        console_locked = 0;
+       mutex_release(&console_lock_dep_map, 1, _RET_IP_);
 
        /* Release the exclusive_console once it is used */
        if (unlikely(exclusive_console))