|
@@ -22,6 +22,8 @@
|
|
|
#include <linux/tty_driver.h>
|
|
|
#include <linux/console.h>
|
|
|
#include <linux/init.h>
|
|
|
+#include <linux/jiffies.h>
|
|
|
+#include <linux/nmi.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/moduleparam.h>
|
|
|
#include <linux/interrupt.h> /* For in_interrupt() */
|
|
@@ -162,6 +164,61 @@ out:
|
|
|
|
|
|
__setup("log_buf_len=", log_buf_len_setup);
|
|
|
|
|
|
+#ifdef CONFIG_BOOT_PRINTK_DELAY
|
|
|
+
|
|
|
+static unsigned int boot_delay; /* msecs delay after each printk during bootup */
|
|
|
+static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */
|
|
|
+
|
|
|
+static int __init boot_delay_setup(char *str)
|
|
|
+{
|
|
|
+ unsigned long lpj;
|
|
|
+ unsigned long long loops_per_msec;
|
|
|
+
|
|
|
+ lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */
|
|
|
+ loops_per_msec = (unsigned long long)lpj / 1000 * HZ;
|
|
|
+
|
|
|
+ get_option(&str, &boot_delay);
|
|
|
+ if (boot_delay > 10 * 1000)
|
|
|
+ boot_delay = 0;
|
|
|
+
|
|
|
+ printk_delay_msec = loops_per_msec;
|
|
|
+ printk(KERN_DEBUG "boot_delay: %u, preset_lpj: %ld, lpj: %lu, "
|
|
|
+ "HZ: %d, printk_delay_msec: %llu\n",
|
|
|
+ boot_delay, preset_lpj, lpj, HZ, printk_delay_msec);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+__setup("boot_delay=", boot_delay_setup);
|
|
|
+
|
|
|
+static void boot_delay_msec(void)
|
|
|
+{
|
|
|
+ unsigned long long k;
|
|
|
+ unsigned long timeout;
|
|
|
+
|
|
|
+ if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
|
|
|
+ return;
|
|
|
+
|
|
|
+ k = (unsigned long long)printk_delay_msec * boot_delay;
|
|
|
+
|
|
|
+ timeout = jiffies + msecs_to_jiffies(boot_delay);
|
|
|
+ while (k) {
|
|
|
+ k--;
|
|
|
+ cpu_relax();
|
|
|
+ /*
|
|
|
+ * use (volatile) jiffies to prevent
|
|
|
+ * compiler reduction; loop termination via jiffies
|
|
|
+ * is secondary and may or may not happen.
|
|
|
+ */
|
|
|
+ if (time_after(jiffies, timeout))
|
|
|
+ break;
|
|
|
+ touch_nmi_watchdog();
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void boot_delay_msec(void)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Commands to do_syslog:
|
|
|
*
|
|
@@ -527,6 +584,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
|
|
|
static char printk_buf[1024];
|
|
|
static int log_level_unknown = 1;
|
|
|
|
|
|
+ boot_delay_msec();
|
|
|
+
|
|
|
preempt_disable();
|
|
|
if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
|
|
|
/* If a crash is occurring during printk() on this CPU,
|