Commit bfe8df3d authored by Randy Dunlap's avatar Randy Dunlap Committed by Linus Torvalds
Browse files

slow down printk during boot

Optionally add a boot delay after each kernel printk() call, crudely
measured in milliseconds, with a maximum delay of 10 seconds per printk.

Enable CONFIG_BOOT_PRINTK_DELAY=y and then add (e.g.):
"lpj=loops_per_jiffy boot_delay=100"
to the kernel command line.

It has been useful in cases like "during boot, my machine just reboots or the
screen goes black" by slowing down printk, (and adding initcall_debug), we can
usually see the last thing that happened before the lights went out which is
usually a valuable clue.

[ not all architectures implement CONFIG_HZ]
[ fix lots of stuff]
[ kernel/printk.c: make 2 variables static]
[ fix slow down printk on boot compile error]
Signed-off-by: default avatarRandy Dunlap <>
Signed-off-by: default avatarDave Jones <>
Signed-off-by: default avatarAdrian Bunk <>
Signed-off-by: default avatarHeiko Carstens <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarLinus Torvalds <>
parent 1bcf5482
......@@ -349,6 +349,11 @@ and is between 256 and 4096 characters. It is defined in the file
boot_delay= Milliseconds to delay each printk during boot.
Values larger than 10 seconds (10000) are changed to
no delay (0).
Format: integer
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards) Most important insmod options are available as
kernel args too.
......@@ -148,6 +148,8 @@ static inline u64 get_jiffies_64(void)
#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)
extern unsigned long preset_lpj;
* We want to do realistic conversions of time so we need to use the same
* values the update wall clock code uses as the jiffies size. This value
......@@ -10,7 +10,7 @@
#include <asm/timex.h>
static unsigned long preset_lpj;
unsigned long preset_lpj;
static int __init lpj_setup(char *str)
preset_lpj = simple_strtoul(str,NULL,0);
......@@ -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 @@ static int __init log_buf_len_setup(char *str)
__setup("log_buf_len=", log_buf_len_setup);
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)
k = (unsigned long long)printk_delay_msec * boot_delay;
timeout = jiffies + msecs_to_jiffies(boot_delay);
while (k) {
* use (volatile) jiffies to prevent
* compiler reduction; loop termination via jiffies
* is secondary and may or may not happen.
if (time_after(jiffies, timeout))
static inline void boot_delay_msec(void)
* 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;
if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
/* If a crash is occurring during printk() on this CPU,
......@@ -413,6 +413,24 @@ config FORCED_INLINING
become the default in the future, until then this option is there to
test gcc for this.
bool "Delay each boot printk message by N milliseconds"
This build option allows you to read kernel boot messages
by inserting a short delay after each one. The delay is
specified in milliseconds on the kernel command line,
using "boot_delay=N".
It is likely that you would also need to use "lpj=M" to preset
the "loops per jiffie" value.
See a previous boot log for the "lpj" value to use for your
system, and then set "lpj=M" before setting "boot_delay=N".
NOTE: Using this option may adversely affect SMP systems.
I.e., processors other than the first one may not boot up.
what it believes to be lockup conditions.
tristate "torture tests for RCU"
depends on DEBUG_KERNEL
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment